mirror of
https://github.com/moghtech/komodo.git
synced 2026-07-19 12:21:28 -05:00
docker install with cli
This commit is contained in:
@@ -8,6 +8,8 @@ import Intro from "./components/Intro";
|
||||
import Setup from "./components/Setup";
|
||||
import Periphery from "./components/Periphery";
|
||||
import Mongo from "./components/mongo/Mongo";
|
||||
import { dockerNotInstalled } from "./monitor-cli";
|
||||
import Docker from "./components/docker/Docker";
|
||||
|
||||
const App = () => {
|
||||
const [current, next, prev] = useSequence();
|
||||
@@ -27,6 +29,7 @@ const App = () => {
|
||||
|
||||
const pages: ReactNode[] = [
|
||||
<Intro next={next} />,
|
||||
...(dockerNotInstalled ? [<Docker next={next} />] : []),
|
||||
<Periphery setPeriphery={setPeriphery} next={next} />,
|
||||
...(periphery === true ? peripheryPages : []),
|
||||
...(periphery === false ? corePages : []),
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import React, { useState } from "react";
|
||||
import { Text } from "ink";
|
||||
import { Next } from "../../types";
|
||||
import YesNo from "../util/YesNo";
|
||||
import InstallDocker from "./InstallDocker";
|
||||
|
||||
const Docker = ({ next }: { next: Next }) => {
|
||||
const [installDocker, setInstallDocker] = useState<boolean>();
|
||||
if (installDocker === undefined) {
|
||||
return (
|
||||
<YesNo
|
||||
label={
|
||||
<Text>
|
||||
Would you like to install Docker? This will begin the{" "}
|
||||
<Text color="cyan" bold>
|
||||
Docker Install Helper
|
||||
</Text>
|
||||
</Text>
|
||||
}
|
||||
onSelect={(res) => {
|
||||
if (res === "yes") {
|
||||
setInstallDocker(true);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}}
|
||||
direction="vertical"
|
||||
/>
|
||||
);
|
||||
} else if (installDocker) {
|
||||
return <InstallDocker next={next} />
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export default Docker;
|
||||
@@ -0,0 +1,157 @@
|
||||
import React, { Fragment, useState } from "react";
|
||||
import { Box, Newline, Text, useInput } from "ink";
|
||||
import { Next, SetConfig } from "../../types";
|
||||
import YesNo from "../util/YesNo";
|
||||
import { installDockerUbuntu, InstallLog } from "../../helpers/docker";
|
||||
|
||||
const InstallDocker = ({ next }: { next: Next }) => {
|
||||
const [stage, setStage] = useState<
|
||||
| "userGroup"
|
||||
| "sysCtlEnable"
|
||||
| "confirm"
|
||||
| "install"
|
||||
| "installing"
|
||||
| "finish"
|
||||
| "error"
|
||||
>("userGroup");
|
||||
const [addToUG, setAddToUG] = useState<"yes" | "no">();
|
||||
const [sysCtlEnable, setSysCtlEnable] = useState<"yes" | "no">();
|
||||
const [logs, setLogs] = useState<InstallLog[]>([]);
|
||||
useInput(async (_, key) => {
|
||||
if (key.return) {
|
||||
switch (stage) {
|
||||
case "confirm":
|
||||
const log = await installDockerUbuntu(
|
||||
(log) => setLogs((logs) => [...logs, log]),
|
||||
addToUG === "yes",
|
||||
sysCtlEnable === "yes"
|
||||
);
|
||||
if (log) {
|
||||
// there was some error
|
||||
setLogs((logs) => [...logs, log])
|
||||
setStage("error");
|
||||
} else {
|
||||
setStage("finish");
|
||||
}
|
||||
break;
|
||||
|
||||
case "finish":
|
||||
next();
|
||||
break;
|
||||
|
||||
case "error":
|
||||
setAddToUG(undefined);
|
||||
setSysCtlEnable(undefined);
|
||||
setStage("userGroup");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (key.leftArrow) {
|
||||
switch (stage) {
|
||||
case "sysCtlEnable":
|
||||
setAddToUG(undefined);
|
||||
setStage("userGroup");
|
||||
break;
|
||||
|
||||
case "confirm":
|
||||
setSysCtlEnable(undefined);
|
||||
setStage("sysCtlEnable");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text color="cyan" bold>
|
||||
Docker Install Helper
|
||||
</Text>
|
||||
<Newline />
|
||||
{addToUG === undefined && (
|
||||
<YesNo
|
||||
label="add to user group? this will allow for the use of docker without sudo."
|
||||
labelColor="white"
|
||||
onSelect={(res) => {
|
||||
setAddToUG(res);
|
||||
setStage("sysCtlEnable");
|
||||
}}
|
||||
direction="vertical"
|
||||
/>
|
||||
)}
|
||||
{addToUG !== undefined && (
|
||||
<Text color="green">
|
||||
add to user group: <Text color="white">{addToUG}</Text>
|
||||
</Text>
|
||||
)}
|
||||
{stage === "sysCtlEnable" && sysCtlEnable === undefined && (
|
||||
<YesNo
|
||||
label="start docker on system start (boot)?"
|
||||
labelColor="white"
|
||||
onSelect={(res) => {
|
||||
setSysCtlEnable(res);
|
||||
setStage("confirm");
|
||||
}}
|
||||
direction="vertical"
|
||||
/>
|
||||
)}
|
||||
{sysCtlEnable !== undefined && (
|
||||
<Text color="green">
|
||||
start on boot: <Text color="white">{sysCtlEnable}</Text>
|
||||
</Text>
|
||||
)}
|
||||
{stage === "confirm" && (
|
||||
<Fragment>
|
||||
<Newline />
|
||||
<Text>
|
||||
press <Text color="green">enter</Text> to install docker
|
||||
</Text>
|
||||
</Fragment>
|
||||
)}
|
||||
{(stage === "installing" || stage === "finish") && (
|
||||
<Fragment>
|
||||
{stage === "installing" && <Text color="cyan">installing...</Text>}
|
||||
<Newline />
|
||||
{logs.map(({ stage, log }) => {
|
||||
<Fragment>
|
||||
<Text color="cyan" bold>
|
||||
{stage}
|
||||
</Text>
|
||||
<Text color="green">
|
||||
command: <Text color="white">{log.command}</Text>
|
||||
</Text>
|
||||
{log.log.stdout ? (
|
||||
<Text color="green">
|
||||
stdout: <Text color="white">{log.log.stdout}</Text>
|
||||
</Text>
|
||||
) : undefined}
|
||||
{log.log.stderr ? (
|
||||
<Text color="red">
|
||||
stderr: <Text color="white">{log.log.stderr}</Text>
|
||||
</Text>
|
||||
) : undefined}
|
||||
<Newline />
|
||||
</Fragment>;
|
||||
})}
|
||||
</Fragment>
|
||||
)}
|
||||
{stage === "finish" && (
|
||||
<Text>
|
||||
Docker has finished installing. Press <Text color="green">enter</Text>{" "}
|
||||
to continue.
|
||||
</Text>
|
||||
)}
|
||||
{stage === "error" && (
|
||||
<Text>
|
||||
There was an error during install. Press{" "}
|
||||
<Text color="green">enter</Text> to try again.
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default InstallDocker;
|
||||
@@ -5,12 +5,14 @@ const YesNo = ({
|
||||
label,
|
||||
onYes,
|
||||
onNo,
|
||||
onSelect,
|
||||
direction,
|
||||
labelColor
|
||||
}: {
|
||||
label: ReactNode;
|
||||
onYes?: () => void;
|
||||
onNo?: () => void;
|
||||
onSelect?: (res: "yes" | "no") => void;
|
||||
direction?: "vertical" | "horizontal";
|
||||
labelColor?: "green" | "white"
|
||||
}) => {
|
||||
@@ -22,8 +24,9 @@ const YesNo = ({
|
||||
if (item === "yes") {
|
||||
onYes && onYes();
|
||||
} else {
|
||||
onNo && onNo()
|
||||
onNo && onNo();
|
||||
}
|
||||
onSelect && onSelect(item as "yes" | "no");
|
||||
}}
|
||||
direction={direction}
|
||||
labelColor={labelColor}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import { CommandLogError } from "@monitor/types";
|
||||
import { execute } from "./execute";
|
||||
|
||||
export type InstallLog = {
|
||||
stage: string;
|
||||
log: CommandLogError;
|
||||
};
|
||||
|
||||
export async function installDockerUbuntu(
|
||||
onCommandEnd: (log: InstallLog) => void,
|
||||
addToUserGroup?: boolean,
|
||||
systemCtlEnable?: boolean
|
||||
) {
|
||||
const total = 5 + (addToUserGroup ? 1 : 0) + (systemCtlEnable ? 1 : 0);
|
||||
const update = await execute("sudo apt-get update");
|
||||
if (update.isError) return {
|
||||
stage: "error updating system",
|
||||
log: update
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `updated system (1 of ${total})`,
|
||||
log: update,
|
||||
});
|
||||
|
||||
|
||||
const installDeps = await execute(`
|
||||
sudo apt-get install \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release
|
||||
`);
|
||||
if (installDeps.isError) return {
|
||||
stage: "error installing dependencies",
|
||||
log: installDeps
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `installed dependencies (2 of ${total})`,
|
||||
log: installDeps,
|
||||
});
|
||||
|
||||
|
||||
const addKey = await execute(
|
||||
"curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg"
|
||||
);
|
||||
if (addKey.isError) return {
|
||||
stage: "error adding docker key",
|
||||
log: addKey,
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `added docker key (3 of ${total})`,
|
||||
log: addKey,
|
||||
});
|
||||
|
||||
|
||||
const setStableRepository = await execute(`
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
`);
|
||||
if (setStableRepository.isError) return {
|
||||
stage: "error adding stable repository",
|
||||
log: setStableRepository,
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `set docker stable repository (4 of ${total})`,
|
||||
log: setStableRepository,
|
||||
});
|
||||
|
||||
const installDocker = await execute(
|
||||
"sudo apt-get udpate && sudo apt-get install docker-ce docker-ce-cli containerd.io"
|
||||
);
|
||||
if (installDocker.isError) return {
|
||||
stage: "error installing docker",
|
||||
log: installDocker,
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `installed docker (5 of ${total})`,
|
||||
log: installDocker,
|
||||
});
|
||||
|
||||
if (addToUserGroup) {
|
||||
const addUser = await execute(
|
||||
"sudo groupadd docker && sudo usermod -aG docker $USER && newgrp docker"
|
||||
);
|
||||
if (addUser.isError) return {
|
||||
stage: "error adding user to docker group",
|
||||
log: addUser,
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `added user to docker user group (6 of ${total})`,
|
||||
log: addUser,
|
||||
});
|
||||
}
|
||||
|
||||
if (systemCtlEnable) {
|
||||
const startOnBoot = await execute(
|
||||
"sudo systemctl enable docker.service && sudo systemctl enable containerd.service"
|
||||
);
|
||||
if (startOnBoot.isError) return {
|
||||
stage: "error configuring to start on boot",
|
||||
log: startOnBoot,
|
||||
};
|
||||
onCommandEnd({
|
||||
stage: `configured to start on boot (7 of ${total})`,
|
||||
log: startOnBoot,
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
export async function checkDockerNotInstalled() {
|
||||
const res = await execute("docker ps");
|
||||
return res.isError
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import React from "react";
|
||||
import { render } from "ink";
|
||||
// import meow from "meow";
|
||||
import App from "./App";
|
||||
import { checkDockerNotInstalled } from "./helpers/docker";
|
||||
|
||||
// const cli = meow(
|
||||
// `
|
||||
@@ -24,5 +25,8 @@ import App from "./App";
|
||||
// },
|
||||
// }
|
||||
// );
|
||||
|
||||
render(<App />);
|
||||
export let dockerNotInstalled = true;
|
||||
checkDockerNotInstalled().then((res) => {
|
||||
dockerNotInstalled = res;
|
||||
render(<App />);
|
||||
});
|
||||
Vendored
+2
@@ -7,3 +7,5 @@ export type SetConfig = (
|
||||
field: keyof Config,
|
||||
val: string | number | boolean
|
||||
) => void;
|
||||
|
||||
export type Next = () => void;
|
||||
|
||||
Reference in New Issue
Block a user