mirror of
https://github.com/moghtech/komodo.git
synced 2026-05-01 09:50:28 -05:00
working with accounts
This commit is contained in:
@@ -129,12 +129,6 @@ function getInitialUpdate(config: Config): Update {
|
||||
function getNextUpdate({ stage }: Update): Update | undefined {
|
||||
switch (stage) {
|
||||
case "mongo":
|
||||
return {
|
||||
stage: "registry",
|
||||
description: "starting registry...",
|
||||
};
|
||||
|
||||
case "registry":
|
||||
return {
|
||||
stage: "core",
|
||||
description: "starting monitor core...",
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Box, Newline, Text } from "ink";
|
||||
import { useConfig, useMainSequence } from "../../cli";
|
||||
import { useEsc, useStore } from "../../util/hooks";
|
||||
import YesNo from "../util/YesNo";
|
||||
import { DEFAULT_PERIPHERY_PORT, DEFAULT_PORT } from "../../config";
|
||||
import { DEFAULT_PERIPHERY_PORT, DEFAULT_PORT, RESTART_MODES } from "../../config";
|
||||
import EnterToContinue from "../util/EnterToContinue";
|
||||
import { ControlledInput } from "../util/Input";
|
||||
import NumberInput from "../util/NumberInput";
|
||||
@@ -13,13 +13,6 @@ import { toDashedName } from "../../util/helpers/general";
|
||||
|
||||
type Stage = "name" | "secret" | "port" | "restart" | "confirm";
|
||||
|
||||
const RESTART_MODES = [
|
||||
"always",
|
||||
"on failure",
|
||||
"unless stopped",
|
||||
"don't restart",
|
||||
];
|
||||
|
||||
const CoreOrPeriphery = ({ type }: { type: "core" | "periphery" }) => {
|
||||
const { set } = useConfig();
|
||||
const { next, prev } = useMainSequence();
|
||||
|
||||
@@ -7,6 +7,7 @@ import YesNo from "../util/YesNo";
|
||||
import { toDashedName } from "../../util/helpers/general";
|
||||
import { Input } from "../util/Input";
|
||||
import NumberInput from "../util/NumberInput";
|
||||
import { RESTART_MODES } from "../../config";
|
||||
|
||||
type DeploymentConfig = {
|
||||
stage: "name" | "port" | "volume" | "restart" | "confirm";
|
||||
@@ -16,13 +17,6 @@ type DeploymentConfig = {
|
||||
restart?: string;
|
||||
};
|
||||
|
||||
const RESTART_MODES = [
|
||||
"always",
|
||||
"on failure",
|
||||
"unless stopped",
|
||||
"don't restart",
|
||||
];
|
||||
|
||||
const DeploymentConfig = ({
|
||||
deployment,
|
||||
onFinish,
|
||||
|
||||
@@ -5,3 +5,9 @@ export const DEFAULT_REGISTRY_URL = "registry:5000/";
|
||||
export const CORE_IMAGE = "mbecker2020/monitor-core";
|
||||
export const PERIPHERY_IMAGE = "mbecker2020/monitor-periphery";
|
||||
export const DOCKER_NETWORK = "monitor-network";
|
||||
export const RESTART_MODES = [
|
||||
"don't restart",
|
||||
"unless stopped",
|
||||
"on failure",
|
||||
"always",
|
||||
];
|
||||
|
||||
@@ -31,8 +31,8 @@ export default function deploymentModel() {
|
||||
/* to manage repo for static frontend, mounted as a volume */
|
||||
repo: String,
|
||||
branch: String,
|
||||
accessToken: String,
|
||||
containerMount: String, // the file path to mount repo on inside the container
|
||||
githubAccount: String,
|
||||
});
|
||||
|
||||
return model("Deployment", schema)
|
||||
|
||||
@@ -7,25 +7,27 @@ import {
|
||||
} from "@monitor/util";
|
||||
import { join } from "path";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { BUILD_REPO_PATH } from "../../config";
|
||||
import { BUILD_REPO_PATH, SECRETS } from "../../config";
|
||||
import { addBuildUpdate } from "../../util/updates";
|
||||
|
||||
async function cloneRepo(
|
||||
app: FastifyInstance,
|
||||
user: User,
|
||||
{ pullName, branch, repo, subfolder, onClone, accessToken, _id }: Build
|
||||
{ pullName, branch, repo, subfolder, onClone, githubAccount, _id }: Build
|
||||
) {
|
||||
const cloneCle = await clone(
|
||||
repo!,
|
||||
BUILD_REPO_PATH + pullName!,
|
||||
subfolder,
|
||||
branch,
|
||||
accessToken
|
||||
githubAccount && SECRETS.GITHUB_ACCOUNTS[githubAccount]
|
||||
);
|
||||
const onCloneCle =
|
||||
onClone &&
|
||||
(await execute(
|
||||
`cd ${join(BUILD_REPO_PATH, pullName!, onClone.path || "")} && ${onClone.command}`
|
||||
`cd ${join(BUILD_REPO_PATH, pullName!, onClone.path || "")} && ${
|
||||
onClone.command
|
||||
}`
|
||||
));
|
||||
const { command, log, isError } = mergeCommandLogError(
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ const builds = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
/* repo related */
|
||||
repo: String,
|
||||
branch: String,
|
||||
accessToken: String,
|
||||
githubAccount: String,
|
||||
onClone: Command,
|
||||
/* build related */
|
||||
cliBuild: Command,
|
||||
|
||||
@@ -24,7 +24,7 @@ const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
/* to manage repo for static frontend, mounted as a volume */
|
||||
repo: String,
|
||||
branch: String,
|
||||
accessToken: String,
|
||||
githubAccount: String,
|
||||
containerMount: String, // the file path to mount repo on inside the container
|
||||
onPull: Command,
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Build, Update } from "@monitor/types";
|
||||
import { Accessor, Component, createContext, createEffect, createSignal, onCleanup, useContext } from "solid-js";
|
||||
import { Component, createContext, createEffect, createResource, onCleanup, Resource, useContext } from "solid-js";
|
||||
import { createStore, DeepReadonly, SetStoreFunction } from "solid-js/store";
|
||||
import { ADD_UPDATE, UPDATE_BUILD } from "../../../state/actions";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { getBuild } from "../../../util/query";
|
||||
import { getBuild, getDockerAccounts } from "../../../util/query";
|
||||
|
||||
type ConfigBuild = Build & { loaded: boolean; updated: boolean; saving: boolean };
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ const BuildConfig: Component<{}> = (p) => {
|
||||
<Show when={build.loaded}>
|
||||
<Grid class={s.Config}>
|
||||
<Grid class={combineClasses(s.ConfigItems, "scroller")}>
|
||||
<CliBuild />
|
||||
<Docker />
|
||||
<CliBuild />
|
||||
</Grid>
|
||||
<Show when={build.updated}>
|
||||
<Flex style={{ "place-self": "center", padding: "1rem" }}>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { Component } from "solid-js";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../../state/StateProvider";
|
||||
import { combineClasses } from "../../../../util/helpers";
|
||||
import Input from "../../../util/Input";
|
||||
import Flex from "../../../util/layout/Flex";
|
||||
import Grid from "../../../util/layout/Grid";
|
||||
import Selector from "../../../util/menu/Selector";
|
||||
import s from "../../build.module.css";
|
||||
import { useConfig } from "../Provider";
|
||||
|
||||
const Docker: Component<{}> = (p) => {
|
||||
const { dockerAccounts } = useAppState();
|
||||
const { build, setBuild } = useConfig();
|
||||
return (
|
||||
<Grid class={combineClasses(s.ConfigItem, "shadow")}>
|
||||
@@ -24,9 +27,27 @@ const Docker: Component<{}> = (p) => {
|
||||
<Input
|
||||
placeholder="from root of build path"
|
||||
value={build.dockerBuildArgs?.dockerfilePath || ""}
|
||||
onEdit={(dockerfilePath) => setBuild("dockerBuildArgs", { dockerfilePath })}
|
||||
onEdit={(dockerfilePath) =>
|
||||
setBuild("dockerBuildArgs", { dockerfilePath })
|
||||
}
|
||||
/>
|
||||
</Flex>
|
||||
<Show when={dockerAccounts()}>
|
||||
<Flex justifyContent="space-between" alignItems="center">
|
||||
<div>account</div>
|
||||
<Selector
|
||||
selected={build.dockerAccount || "none"}
|
||||
items={["none", ...dockerAccounts()!]}
|
||||
onSelect={(account) => {
|
||||
setBuild(
|
||||
"dockerAccount",
|
||||
account === "none" ? undefined : account
|
||||
);
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
</Flex>
|
||||
</Show>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { Component } from "solid-js";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { combineClasses } from "../../../../util/helpers";
|
||||
import Grid from "../../../util/layout/Grid";
|
||||
import { useConfig } from "../Provider";
|
||||
import s from "../../build.module.css";
|
||||
import Flex from "../../../util/layout/Flex";
|
||||
import Input from "../../../util/Input";
|
||||
import { useAppState } from "../../../../state/StateProvider";
|
||||
import Selector from "../../../util/menu/Selector";
|
||||
|
||||
const Git: Component<{}> = (p) => {
|
||||
const { githubAccounts } = useAppState();
|
||||
const { build, setBuild } = useConfig();
|
||||
return (
|
||||
<Grid class={combineClasses(s.ConfigItem, "shadow")}>
|
||||
@@ -27,14 +30,22 @@ const Git: Component<{}> = (p) => {
|
||||
onEdit={(value) => setBuild("branch", value)}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex justifyContent="space-between" alignItems="center">
|
||||
<div>access token</div>
|
||||
<Input
|
||||
placeholder="paste token"
|
||||
value={build.accessToken || ""}
|
||||
onEdit={(value) => setBuild("accessToken", value)}
|
||||
/>
|
||||
</Flex>
|
||||
<Show when={githubAccounts()}>
|
||||
<Flex justifyContent="space-between" alignItems="center">
|
||||
<div>github account</div>
|
||||
<Selector
|
||||
selected={build.dockerAccount || "none"}
|
||||
items={["none", ...githubAccounts()!]}
|
||||
onSelect={(account) => {
|
||||
setBuild(
|
||||
"githubAccount",
|
||||
account === "none" ? undefined : account
|
||||
);
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
</Flex>
|
||||
</Show>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ import Icon from "../../../util/icons/Icon";
|
||||
import ConfirmButton from "../../../util/ConfirmButton";
|
||||
import Restart from "./Restart";
|
||||
import { combineClasses } from "../../../../util/helpers";
|
||||
import DockerAccount from "./DockerAccount";
|
||||
|
||||
const Config: Component<{}> = (p) => {
|
||||
const { deployment, reset, save } = useConfig();
|
||||
@@ -20,6 +21,7 @@ const Config: Component<{}> = (p) => {
|
||||
<Grid class={s.Config}>
|
||||
<Grid class={combineClasses(s.ConfigItems, "scroller")}>
|
||||
<Image />
|
||||
<DockerAccount />
|
||||
<Network />
|
||||
<Restart />
|
||||
<Ports />
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../../state/StateProvider";
|
||||
import { combineClasses } from "../../../../util/helpers";
|
||||
import Flex from "../../../util/layout/Flex";
|
||||
import Selector from "../../../util/menu/Selector";
|
||||
import s from "../../deployment.module.css";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const DockerAccount: Component<{}> = (p) => {
|
||||
const { dockerAccounts } = useAppState();
|
||||
const { deployment, setDeployment } = useConfig();
|
||||
return (
|
||||
<Show when={dockerAccounts}>
|
||||
<Flex
|
||||
class={combineClasses(s.ConfigItem, "shadow")}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<h1>docker account</h1>
|
||||
<Selector
|
||||
items={["none", ...dockerAccounts()!]}
|
||||
selected={deployment.dockerAccount || "none"}
|
||||
onSelect={(account) =>
|
||||
setDeployment(
|
||||
"dockerAccount",
|
||||
account === "none" ? undefined : account
|
||||
)
|
||||
}
|
||||
position="bottom right"
|
||||
/>
|
||||
</Flex>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
export default DockerAccount;
|
||||
@@ -6,10 +6,10 @@ import s from "../../deployment.module.css";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const RESTART_MODES = [
|
||||
"always",
|
||||
"on failure",
|
||||
"unless stopped",
|
||||
"don't restart",
|
||||
"unless stopped",
|
||||
"on failure",
|
||||
"always",
|
||||
];
|
||||
|
||||
const Restart: Component<{}> = (p) => {
|
||||
@@ -35,11 +35,6 @@ const Restart: Component<{}> = (p) => {
|
||||
}
|
||||
position="bottom right"
|
||||
/>
|
||||
{/* <Input
|
||||
value={deployment.network}
|
||||
placeholder="network"
|
||||
onConfirm={(value) => setDeployment("network", value)}
|
||||
/> */}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -129,3 +129,7 @@
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.SelectorItem:hover {
|
||||
background-color: rgba(180, 43, 43, 0.377);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ const Selector: Component<{
|
||||
toggle();
|
||||
}}
|
||||
style={{ width: "100%", "justify-content": "flex-end" }}
|
||||
class={s.SelectorItem}
|
||||
>
|
||||
{item}
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Accessor, Component, createContext, useContext } from "solid-js";
|
||||
import { Accessor, Component, createContext, createResource, Resource, useContext } from "solid-js";
|
||||
import { useLocalStorageToggle } from "../util/hooks";
|
||||
import { getDockerAccounts, getGithubAccounts } from "../util/query";
|
||||
import {
|
||||
useBuilds,
|
||||
useDeployments,
|
||||
@@ -15,6 +16,8 @@ export type State = {
|
||||
builds: ReturnType<typeof useBuilds>;
|
||||
deployments: ReturnType<typeof useDeployments>;
|
||||
updates: ReturnType<typeof useUpdates>;
|
||||
dockerAccounts: Resource<string[] | undefined>;
|
||||
githubAccounts: Resource<string[] | undefined>;
|
||||
sidebar: {
|
||||
open: Accessor<boolean>;
|
||||
toggle: () => void;
|
||||
@@ -35,11 +38,15 @@ export const AppStateProvider: Component<{}> = (p) => {
|
||||
"sidebar-open",
|
||||
true
|
||||
);
|
||||
const [dockerAccounts] = createResource(getDockerAccounts);
|
||||
const [githubAccounts] = createResource(getGithubAccounts);
|
||||
const state: State = {
|
||||
servers: useServers(),
|
||||
builds: useBuilds(),
|
||||
deployments: useDeployments(),
|
||||
updates: useUpdates(),
|
||||
dockerAccounts,
|
||||
githubAccounts,
|
||||
sidebar: {
|
||||
open: sidebarOpen,
|
||||
toggle: toggleSidebarOpen,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"esModuleInterop": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
"types": ["vite/client"]
|
||||
"types": ["vite/client"],
|
||||
"noEmit": true,
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
"build-core": "cd core && yarn build",
|
||||
"restart-core": "cd core && yarn build && cd ../cli && yarn restart-default",
|
||||
"push-core": "cd core && yarn push",
|
||||
"build-periphery": "cd periphery && yarn build",
|
||||
"build-periphery": "cd periphery && yarn docker-build",
|
||||
"push-periphery": "cd periphery && yarn push"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
+32
-13
@@ -1,8 +1,9 @@
|
||||
import { Deployment } from "@monitor/types";
|
||||
import { clone, pull } from "@monitor/util";
|
||||
import { clone, execute, mergeCommandLogError, pull } from "@monitor/util";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import fp from "fastify-plugin";
|
||||
import { remove } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { CONTAINER_REPO_ROOT, SECRETS } from "../config";
|
||||
|
||||
const git = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
@@ -14,24 +15,42 @@ const git = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
CONTAINER_REPO_ROOT + deployment.containerName,
|
||||
deployment.subfolder,
|
||||
deployment.branch,
|
||||
deployment.githubAccount && SECRETS.GITHUB_ACCOUNTS[deployment.githubAccount]
|
||||
deployment.githubAccount &&
|
||||
SECRETS.GITHUB_ACCOUNTS[deployment.githubAccount]
|
||||
);
|
||||
res.send(log);
|
||||
res.send(log);
|
||||
});
|
||||
|
||||
app.post("/repo/pull", { onRequest: [app.auth] }, async (req, res) => {
|
||||
const body = req.body as { deployment: Deployment };
|
||||
app.post("/repo/pull", { onRequest: [app.auth] }, async (req, res) => {
|
||||
const body = req.body as { deployment: Deployment };
|
||||
const deployment = body.deployment;
|
||||
const log = await pull(CONTAINER_REPO_ROOT + deployment.containerName, deployment.branch);
|
||||
res.send(log);
|
||||
});
|
||||
const pullCle = await pull(
|
||||
join(CONTAINER_REPO_ROOT, deployment.containerName!),
|
||||
deployment.branch
|
||||
);
|
||||
const onPullCle =
|
||||
deployment.onPull &&
|
||||
(await execute(
|
||||
`cd ${join(
|
||||
CONTAINER_REPO_ROOT,
|
||||
deployment.containerName!,
|
||||
deployment.onPull.path || ""
|
||||
)} && ${deployment.onPull.command}`
|
||||
));
|
||||
res.send(
|
||||
mergeCommandLogError(
|
||||
{ name: "pull", cle: pullCle },
|
||||
{ name: "post", cle: onPullCle }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
app.post("/repo/delete", { onRequest: [app.auth] }, async (req, res) => {
|
||||
const body = req.body as { deployment: Deployment };
|
||||
app.post("/repo/delete", { onRequest: [app.auth] }, async (req, res) => {
|
||||
const body = req.body as { deployment: Deployment };
|
||||
const deployment = body.deployment;
|
||||
await remove(CONTAINER_REPO_ROOT + deployment.containerName).catch();
|
||||
res.send();
|
||||
});
|
||||
await remove(CONTAINER_REPO_ROOT + deployment.containerName).catch();
|
||||
res.send();
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
Vendored
+2
-3
@@ -73,7 +73,7 @@ export interface Build {
|
||||
repo?: string;
|
||||
subfolder?: string; // subfolder of monorepo. uses sparse clone
|
||||
branch?: string;
|
||||
accessToken?: string; // to gain access to private repos
|
||||
githubAccount?: string; // to gain access to private repos
|
||||
onClone?: Command;
|
||||
/* build related */
|
||||
cliBuild?: Command; // run shell commands on build, before docker build step if it exists
|
||||
@@ -105,8 +105,7 @@ export interface Deployment extends DockerRunArgs {
|
||||
repo?: string;
|
||||
branch?: string;
|
||||
subfolder?: string; // subfolder of repo to clone (uses sparse clone)
|
||||
githubAccount?: string;
|
||||
|
||||
githubAccount?: string;
|
||||
repoMount?: string; // subfolder of repo to mount in container
|
||||
containerMount?: string; // the file path to mount repo on inside the container
|
||||
onPull?: Command;
|
||||
|
||||
Reference in New Issue
Block a user