begin cli v2

This commit is contained in:
mbecker20
2022-03-18 23:02:51 -07:00
parent 2db166ddb3
commit d64da60d4e
44 changed files with 472 additions and 391 deletions
-53
View File
@@ -1,53 +0,0 @@
import { Box, Newline, Text, useInput } from "ink";
import React from "react";
import { Config } from "../types";
const FinalConfig = (p: {
periphery: boolean | undefined;
config: Config;
onConfirm: () => void;
}) => {
useInput((_, key) => {
if (key.return) p.onConfirm();
});
if (p.periphery) {
return (
<Text>
press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to start setup of the <Text color="red">monitor periphery</Text>. you
cannot go back after this begins.
</Text>
);
} else {
return (
<Box flexDirection="column">
<Text color="blue" bold>
your monitor core config
</Text>
<Newline />
<Box flexDirection="column" borderColor="green" borderStyle="round">
<Text color="green">
mongo url: <Text color="white">{p.config.mongoURL}</Text>
</Text>
<Text color="green">
registry url: <Text color="white">{p.config.registryURL}</Text>
</Text>
</Box>
<Newline />
<Text>
press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to start setup of <Text color="cyan">monitor core</Text>. you cannot
go back after this begins.
</Text>
</Box>
);
}
};
export default FinalConfig;
-29
View File
@@ -1,29 +0,0 @@
import React from "react";
import { Box, Newline, Text, useInput } from "ink";
const Intro = (p: { next: () => void }) => {
useInput((_, key) => {
if (key.return) p.next();
});
return (
<Box flexDirection="column">
<Text>
This is a CLI to setup{" "}
<Text color="cyan" bold>
Monitor
</Text>
, a tool to manage application deployment.
</Text>
<Newline />
<Text>
press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to continue.
</Text>
</Box>
);
};
export default Intro;
-28
View File
@@ -1,28 +0,0 @@
import React from "react";
import { Box, Newline, Text } from "ink";
import Selector from "./util/Selector";
import { SetConfig } from "../types";
const Periphery = (p: {
setPeriphery: (a: boolean) => void;
next: () => void;
}) => {
return (
<Box flexDirection="column">
<Text>
Are you setting up <Text color="cyan">monitor core</Text> or {" "}
<Text color="red">monitor periphery</Text>?
</Text>
<Newline />
<Selector
items={["core", "peripheral"]}
onSelect={(item) => {
p.setPeriphery(item === "periphery");
p.next();
}}
/>
</Box>
);
};
export default Periphery;
-18
View File
@@ -1,18 +0,0 @@
import React from "react";
import { Box, Text } from "ink";
const Setup = (p: { periphery: boolean | undefined }) => {
return (
<Box flexDirection="column">
<Text>
setting up{" "}
<Text color={p.periphery ? "red" : "cyan"}>
{p.periphery ? "a peripheral client..." : "monitor core"}
</Text>{" "}
{!p.periphery && "using the specified configuration..."}
</Text>
</Box>
);
};
export default Setup;
-40
View File
@@ -1,40 +0,0 @@
import React, { useEffect, 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>();
useEffect(() => {
if (installDocker === false) {
process.exit();
}
}, [installDocker]);
if (installDocker === undefined) {
return (
<YesNo
label={
<Text>
Docker does not appear to be installed. Would you like to install
Docker? This will begin the{" "}
<Text color="cyan" bold>
Docker Install Helper
</Text>{" "}
and is necessary to proceed.
</Text>
}
onSelect={(res) => {
setInstallDocker(res === "yes");
}}
direction="vertical"
/>
);
} else if (installDocker) {
return <InstallDocker next={next} />;
} else {
return <Text>Install docker and restart the CLI to proceed.</Text>;
}
};
export default Docker;
-132
View File
@@ -1,132 +0,0 @@
import React, { Fragment, useState } from "react";
import { Box, Newline, Text, useInput } from "ink";
import { Next } from "../../types";
import YesNo from "../util/YesNo";
import { installDockerUbuntu, InstallLog } from "../../helpers/docker";
const InstallDocker = ({ next }: { next: Next }) => {
const [stage, setStage] = useState<
| "sysCtlEnable"
| "confirm"
| "install"
| "installing"
| "finish"
| "error"
>("sysCtlEnable");
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]),
sysCtlEnable === "yes"
);
if (log) {
// there was some error
setLogs((logs) => [...logs, log])
setStage("error");
} else {
setStage("finish");
}
break;
case "finish":
next();
break;
case "error":
setSysCtlEnable(undefined);
setStage("sysCtlEnable");
break;
default:
break;
}
} else if (key.leftArrow) {
switch (stage) {
case "confirm":
setSysCtlEnable(undefined);
setStage("sysCtlEnable");
break;
default:
break;
}
}
});
return (
<Box flexDirection="column">
<Text color="cyan" bold>
Docker Install Helper
</Text>
<Newline />
{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;
-105
View File
@@ -1,105 +0,0 @@
import { Box, Newline, Text, useInput } from "ink";
import React, { useState } from "react";
import { useBlinker } from "../../hooks";
import { SetConfig } from "../../types";
import YesNo from "../util/YesNo";
import SetupMongo from "./SetupMongo";
const Mongo = ({
setConfig,
next,
}: {
setConfig: SetConfig;
next: () => void;
}) => {
const [setup, setSetup] = useState<boolean>();
const [mongoURL, setMongoUrl] = useState("mongodb://127.0.0.1:27017/monitor");
const [confirm, setConfirm] = useState(false);
const blinker = useBlinker();
useInput((input, key) => {
if (setup === false) {
if (key.return) {
if (confirm) {
setConfig("mongoURL", mongoURL);
next();
} else {
setConfirm(true);
}
} else if (!confirm && key.delete) {
setMongoUrl(mongoURL.slice(0, mongoURL.length - 1));
} else if (key.leftArrow) {
setConfirm(false);
} else if (!confirm) {
setMongoUrl(mongoURL + input);
}
}
});
if (setup === undefined) {
return (
<YesNo
label={
<Text>
Do you need to set up mongo db locally? This will begin the{" "}
<Text color="cyan" bold>
Mongo Setup Helper
</Text>
.
</Text>
}
onYes={() => {
setSetup(true);
}}
onNo={() => {
setSetup(false);
}}
labelColor="white"
direction="vertical"
/>
);
} else if (setup) {
return (
<SetupMongo
blinker={blinker}
onFinished={(mongoURL) => {
setConfig("mongoURL", mongoURL);
next();
}}
/>
);
} else {
return (
<Box flexDirection="column">
<Box flexDirection="row">
<Text color="green">mongo url: </Text>
<Text>
{mongoURL}
{blinker && !confirm ? "|" : ""}
</Text>
</Box>
<Newline />
<Text color="gray">
note: remember to specify the database name in the url, ie
mongodb://localhost:27017<Text color="green">/monitor</Text>
</Text>
<Newline />
{confirm && (
<Text>
press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to confirm mongo url or press the{" "}
<Text color="blue" bold>
left arrow
</Text>{" "}
on your keyboard to continue editing.
</Text>
)}
</Box>
);
}
};
export default Mongo;
-274
View File
@@ -1,274 +0,0 @@
import { CommandLogError } from "@monitor/types";
import { Box, Newline, Text, useInput } from "ink";
import React, { Fragment, useState } from "react";
import { startMongo } from "../../helpers/deploy/mongo";
import LabelledSelector from "../util/LabelledSelector";
import YesNo from "../util/YesNo";
const RESTART_MODES = ["no", "on-failure", "always", "unless-stopped"];
const SetupMongo = ({
onFinished,
blinker,
}: {
onFinished: (mongoURL: string) => void;
blinker: boolean;
}) => {
const [stage, setStage] = useState<
"name" | "port" | "volume" | "restart" | "confirm" | "finish"
>("name"); // 0: name, 1: port, 2: volume, 3: restart
const [name, setName] = useState("mongo-db");
const [port, setPort] = useState<string>();
const [volume, setVolume] = useState<string | false>();
const [restart, setRestart] = useState<string>();
const [running, setRunning] = useState(false);
const [result, setResult] = useState<CommandLogError>();
useInput((input, key) => {
if (key.return) {
switch (stage) {
case "name":
setStage("port");
setPort("27017");
break;
case "port":
if (!isNaN(Number(port))) {
setStage("volume");
}
break;
case "volume":
if (volume) {
setStage("restart");
}
break;
case "restart":
if (restart) {
setStage("confirm");
}
break;
case "confirm":
setRunning(true);
startMongo(name, Number(port!), volume!, restart!).then((res) => {
setResult(res);
setStage("finish");
});
break;
case "finish":
if (!result?.isError) {
onFinished(`mongodb://127.0.0.1:${port}/monitor`);
}
break;
default:
break;
}
} else if (key.leftArrow) {
switch (stage) {
case "port":
setPort(undefined);
setStage("name");
break;
case "volume":
setVolume(undefined);
setStage("port");
break;
case "restart":
setRestart(undefined);
if (volume === false) {
setVolume(undefined);
}
setStage("volume");
break;
case "confirm":
setRestart(undefined);
setStage("restart");
break;
default:
break;
}
} else if (key.delete) {
switch (stage) {
case "name":
setName(name.slice(0, Math.max(0, name.length - 1)));
break;
case "port":
if (port) setPort(port.slice(0, Math.max(0, port.length - 1)));
break;
case "volume":
if (volume)
setVolume(volume.slice(0, Math.max(0, volume.length - 1)));
break;
default:
break;
}
} else {
switch (stage) {
case "name":
setName(name + input);
break;
case "port":
const newPort = Number(port + input);
if (!isNaN(newPort)) {
setPort(newPort.toString());
}
break;
case "volume":
if (volume) setVolume(volume + input);
break;
default:
break;
}
}
});
return (
<Box flexDirection="column">
<Text color="cyan" bold>
Mongo Setup Helper
</Text>
<Newline />
<Text>
press your keyboard back arrow ({"<-"}) to go back to the previous field
</Text>
<Newline />
<Text color="green">
container name:{" "}
<Text color="white">
{name}
{stage === "name" && blinker ? "|" : ""}
</Text>
</Text>
{port && (
<Text color="green">
port:{" "}
<Text color="white">
{port}
{stage === "port" && blinker ? "|" : ""}
</Text>
</Text>
)}
{stage === "volume" && volume === undefined && (
<LabelledSelector
label="mount data on local filesystem:"
items={["yes", "no"]}
onSelect={(use) => {
if (use === "yes") {
setVolume("~/mongo");
} else {
setVolume(false);
setStage("restart");
}
}}
/>
)}
{(volume || volume === false) && (
<Text color="green">
{volume ? "mount folder: " : "mount: "}
<Text color="white">
{volume || "no"}
{stage === "volume" && blinker ? "|" : ""}
</Text>
</Text>
)}
{stage === "restart" && restart === undefined && (
<LabelledSelector
label="restart:"
items={RESTART_MODES}
onSelect={(mode) => {
setRestart(mode);
setStage("confirm");
}}
/>
)}
{restart !== undefined && (
<Text color="green">
restart: <Text color="white">{restart}</Text>
</Text>
)}
{/* {stage === "confirm" && (
<Box flexDirection="column">
<Newline />
{running ? (
<Text color="cyan">running...</Text>
) : (
<Text color="green">press enter to start mongo...</Text>
)}
</Box>
)} */}
{stage === "confirm" && (
<Fragment>
<Newline />
{running ? (
<Text color="cyan">running...</Text>
) : (
<Text>
press <Text color="green">enter</Text> to start mongo...
</Text>
)}
</Fragment>
)}
{result && (
<Fragment>
<Newline />
<Text>command: {result.command}</Text>
{result.log.stdout ? (
<Fragment>
<Newline />
<Text>stdout: {result.log.stdout}</Text>
</Fragment>
) : undefined}
{result.log.stderr ? (
<Fragment>
<Newline />
<Text>stderr: {result.log.stderr}</Text>
</Fragment>
) : undefined}
</Fragment>
)}
{stage === "finish" && result && !result.isError && (
<Text>
Success! Press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to continue
</Text>
)}
{stage === "finish" && result && result.isError && (
<Fragment>
<Newline />
<YesNo
label="looks like that failed, would you like to retry?"
labelColor="white"
onYes={() => {
setPort(undefined);
setVolume(undefined);
setRestart(undefined);
setResult(undefined);
setStage("name");
}}
onNo={() => {
onFinished(`mongodb://127.0.0.1:${port}/monitor`);
}}
direction="vertical"
/>
</Fragment>
)}
</Box>
);
};
export default SetupMongo;
-100
View File
@@ -1,100 +0,0 @@
import { Box, Newline, Text, useInput } from "ink";
import React, { useState } from "react";
import { useBlinker } from "../../hooks";
import { SetConfig } from "../../types";
import YesNo from "../util/YesNo";
import SetupRegistry from "./SetupRegistry";
const Registry = ({
setConfig,
next,
}: {
setConfig: SetConfig;
next: () => void;
}) => {
const [setup, setSetup] = useState<boolean>();
const [registryURL, setRegistryURL] = useState("http://127.0.0.1:5000/");
const [confirm, setConfirm] = useState(false);
const blinker = useBlinker();
useInput((input, key) => {
if (setup === false) {
if (key.return) {
if (confirm) {
setConfig("registryURL", registryURL);
next();
} else {
setConfirm(true);
}
} else if (!confirm && key.delete) {
setRegistryURL(registryURL.slice(0, registryURL.length - 1));
} else if (key.leftArrow) {
setConfirm(false);
} else if (!confirm) {
setRegistryURL(registryURL + input);
}
}
});
if (setup === undefined) {
return (
<YesNo
label={
<Text>
Do you need to set up a docker registry locally? This will begin the{" "}
<Text color="cyan" bold>
Registry Setup Helper
</Text>
.
</Text>
}
onYes={() => {
setSetup(true);
}}
onNo={() => {
setSetup(false);
}}
labelColor="white"
direction="vertical"
/>
);
} else if (setup) {
return (
<SetupRegistry
blinker={blinker}
onFinished={(registryURL) => {
setConfig("registryURL", registryURL);
next();
}}
/>
);
} else {
return (
<Box flexDirection="column">
<Box flexDirection="row">
<Text color="green">registry url: </Text>
<Text>
{registryURL}
{blinker && !confirm ? "|" : ""}
</Text>
</Box>
<Newline />
{confirm && (
<Text>
press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to confirm registry url or press the{" "}
<Text color="blue" bold>
left arrow
</Text>{" "}
on your keyboard to continue editing.
</Text>
)}
</Box>
);
}
};
export default Registry;
@@ -1,274 +0,0 @@
import { CommandLogError } from "@monitor/types";
import { Box, Newline, Text, useInput } from "ink";
import React, { Fragment, useState } from "react";
import { startRegistry } from "../../helpers/deploy/registry";
import LabelledSelector from "../util/LabelledSelector";
import YesNo from "../util/YesNo";
const RESTART_MODES = ["no", "on-failure", "always", "unless-stopped"];
const SetupRegistry = ({
onFinished,
blinker,
}: {
onFinished: (registryURL: string) => void;
blinker: boolean;
}) => {
const [stage, setStage] = useState<
"name" | "port" | "volume" | "restart" | "confirm" | "finish"
>("name"); // 0: name, 1: port, 2: volume, 3: restart
const [name, setName] = useState("monitor-registry");
const [port, setPort] = useState<string>();
const [volume, setVolume] = useState<string | false>();
const [restart, setRestart] = useState<string>();
const [running, setRunning] = useState(false);
const [result, setResult] = useState<CommandLogError>();
useInput((input, key) => {
if (key.return) {
switch (stage) {
case "name":
setStage("port");
setPort("5000");
break;
case "port":
if (!isNaN(Number(port))) {
setStage("volume");
}
break;
case "volume":
if (volume) {
setStage("restart");
}
break;
case "restart":
if (restart) {
setStage("confirm");
}
break;
case "confirm":
setRunning(true);
startRegistry(name, Number(port!), volume!, restart!).then((res) => {
setResult(res);
setStage("finish");
});
break;
case "finish":
if (!result?.isError) {
onFinished(`http://127.0.0.1:${port}/`);
}
break;
default:
break;
}
} else if (key.leftArrow) {
switch (stage) {
case "port":
setPort(undefined);
setStage("name");
break;
case "volume":
setVolume(undefined);
setStage("port");
break;
case "restart":
setRestart(undefined);
if (volume === false) {
setVolume(undefined);
}
setStage("volume");
break;
case "confirm":
setRestart(undefined);
setStage("restart");
break;
default:
break;
}
} else if (key.delete) {
switch (stage) {
case "name":
setName(name.slice(0, Math.max(0, name.length - 1)));
break;
case "port":
if (port) setPort(port.slice(0, Math.max(0, port.length - 1)));
break;
case "volume":
if (volume)
setVolume(volume.slice(0, Math.max(0, volume.length - 1)));
break;
default:
break;
}
} else {
switch (stage) {
case "name":
setName(name + input);
break;
case "port":
const newPort = Number(port + input);
if (!isNaN(newPort)) {
setPort(newPort.toString());
}
break;
case "volume":
if (volume) setVolume(volume + input);
break;
default:
break;
}
}
});
return (
<Box flexDirection="column">
<Text color="cyan" bold>
Registry Setup Helper
</Text>
<Newline />
<Text>
press your keyboard back arrow ({"<-"}) to go back to the previous field
</Text>
<Newline />
<Text color="green">
container name:{" "}
<Text color="white">
{name}
{stage === "name" && blinker ? "|" : ""}
</Text>
</Text>
{port && (
<Text color="green">
port:{" "}
<Text color="white">
{port}
{stage === "port" && blinker ? "|" : ""}
</Text>
</Text>
)}
{stage === "volume" && volume === undefined && (
<LabelledSelector
label="mount data on local filesystem:"
items={["yes", "no"]}
onSelect={(use) => {
if (use === "yes") {
setVolume("~/registry");
} else {
setVolume(false);
setStage("restart");
}
}}
/>
)}
{(volume || volume === false) && (
<Text color="green">
{volume ? "mount folder: " : "mount: "}
<Text color="white">
{volume || "no"}
{stage === "volume" && blinker ? "|" : ""}
</Text>
</Text>
)}
{stage === "restart" && restart === undefined && (
<LabelledSelector
label="restart:"
items={RESTART_MODES}
onSelect={(mode) => {
setRestart(mode);
setStage("confirm");
}}
/>
)}
{restart !== undefined && (
<Text color="green">
restart: <Text color="white">{restart}</Text>
</Text>
)}
{/* {stage === "confirm" && (
<Box flexDirection="column">
<Newline />
{running ? (
<Text color="cyan">running...</Text>
) : (
<Text color="green">press enter to start mongo...</Text>
)}
</Box>
)} */}
{stage === "confirm" && (
<Fragment>
<Newline />
{running ? (
<Text color="cyan">running...</Text>
) : (
<Text>
press <Text color="green">enter</Text> to start the registry...
</Text>
)}
</Fragment>
)}
{result && (
<Fragment>
<Newline />
<Text>command: {result.command}</Text>
{result.log.stdout ? (
<Fragment>
<Newline />
<Text>stdout: {result.log.stdout}</Text>
</Fragment>
) : undefined}
{result.log.stderr ? (
<Fragment>
<Newline />
<Text>stderr: {result.log.stderr}</Text>
</Fragment>
) : undefined}
</Fragment>
)}
{stage === "finish" && result && !result.isError && (
<Text>
Success! Press{" "}
<Text color="green" bold>
enter
</Text>{" "}
to continue
</Text>
)}
{stage === "finish" && result && result.isError && (
<Fragment>
<Newline />
<YesNo
label="looks like that failed, would you like to retry?"
labelColor="white"
onYes={() => {
setPort(undefined);
setVolume(undefined);
setRestart(undefined);
setResult(undefined);
setStage("name");
}}
onNo={() => {
onFinished(`http://127.0.0.1:${port}/`);
}}
direction="vertical"
/>
</Fragment>
)}
</Box>
);
};
export default SetupRegistry;