mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-10 08:01:11 +00:00
updates
This commit is contained in:
@@ -31,9 +31,9 @@ async function deployDeployment(
|
||||
app.deployActionStates.set(deploymentID, DEPLOYING, true);
|
||||
app.broadcast(DEPLOY, { complete: false, deploymentID });
|
||||
try {
|
||||
const server = deployment.serverID
|
||||
? await app.servers.findById(deployment.serverID)
|
||||
: undefined;
|
||||
const server = deployment.serverID === app.core._id
|
||||
? undefined
|
||||
: await app.servers.findById(deployment.serverID!);
|
||||
if (server) {
|
||||
// delete the container on periphery
|
||||
await deletePeripheryContainer(server, deployment.containerName!);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>download</title>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path fill="#fceade" d="M16.4338096,0 C16.7850725,2.73772263e-15 17.1105793,0.184298834 17.2913025,0.485504245 L20,5 L20,19 C20,19.5522847 19.5522847,20 19,20 L1,20 C0.44771525,20 6.76353751e-17,19.5522847 0,19 L0,5 L2.70869745,0.485504245 C2.8894207,0.184298834 3.21492753,-1.57518666e-16 3.56619038,0 L16.4338096,0 Z M10,8 C9.45,8 9,8.45 9,9 L9,9 L9,13.58 L7.71,12.29 L7.62868805,12.2167055 C7.45795918,12.0781633 7.24,11.99 7,11.99 C6.45,11.99 6,12.44 6,12.99 C6,13.27 6.11,13.52 6.29,13.7 L6.29,13.7 L9.29,16.7 L9.38564815,16.7839815 C9.55416667,16.9136111 9.76666667,16.99 10,16.99 C10.28,16.99 10.53,16.88 10.71,16.7 L10.71,16.7 L13.71,13.7 L13.7939815,13.6043519 C13.9236111,13.4358333 14,13.2233333 14,12.99 C14,12.44 13.55,11.99 13,11.99 C12.72,11.99 12.47,12.1 12.29,12.28 L12.29,12.28 L11,13.58 L11,9 L10.9932398,8.88380102 C10.9352041,8.3880102 10.5107143,8 10,8 Z M16,2 L4,2 L2,5.00162374 L18,5.00162374 L16,2 Z" id="Combined-Shape" fill="#000000"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>upload</title>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path fill="#fceade" d="M16.4338096,0 C16.7850725,2.73772263e-15 17.1105793,0.184298834 17.2913025,0.485504245 L20,5 L20,19 C20,19.5522847 19.5522847,20 19,20 L1,20 C0.44771525,20 6.76353751e-17,19.5522847 0,19 L0,5 L2.70869745,0.485504245 C2.8894207,0.184298834 3.21492753,-1.57518666e-16 3.56619038,0 L16.4338096,0 Z M10,8 C9.72,8 9.47,8.11 9.29,8.29 L9.29,8.29 L6.29,11.29 L6.20601852,11.3856481 C6.07638889,11.5541667 6,11.7666667 6,12 C6,12.55 6.45,13 7,13 C7.28,13 7.53,12.89 7.71,12.71 L7.71,12.71 L9,11.41 L9,15.99 L9.0067602,16.106199 C9.06479592,16.6019898 9.48928571,16.99 10,16.99 C10.55,16.99 11,16.54 11,15.99 L11,15.99 L11,11.41 L12.29,12.7 L12.371312,12.7732945 C12.5420408,12.9118367 12.76,13 13,13 C13.55,13 14,12.55 14,12 C14,11.72 13.89,11.47 13.71,11.29 L13.71,11.29 L10.71,8.29 L10.6143519,8.20601852 C10.4458333,8.07638889 10.2333333,8 10,8 Z M16,2 L4,2 L2,5.00162374 L18,5.00162374 L16,2 Z" id="Combined-Shape" fill="#000000"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,68 +1,124 @@
|
||||
import { ContainerStatus, Deployment } from "@monitor/types";
|
||||
import { Component, Match, Switch } from "solid-js";
|
||||
import { Component, Match, Show, Switch } from "solid-js";
|
||||
import { pushNotification } from "../..";
|
||||
import {
|
||||
DELETE_CONTAINER,
|
||||
DEPLOY,
|
||||
START_CONTAINER,
|
||||
STOP_CONTAINER,
|
||||
} from "../../state/actions";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { combineClasses } from "../../util/helpers";
|
||||
import ConfirmButton from "../util/ConfirmButton";
|
||||
import Icon from "../util/icons/Icon";
|
||||
import Flex from "../util/layout/Flex";
|
||||
import Grid from "../util/layout/Grid";
|
||||
import s from "./deployment.module.css";
|
||||
|
||||
const Actions: Component<{ deployment: Deployment }> = (p) => {
|
||||
const { ws } = useAppState();
|
||||
return (
|
||||
<Grid class={combineClasses(s.Actions, "shadow")}>
|
||||
<div class={s.ItemHeader}>actions</div>
|
||||
<Switch>
|
||||
<Match
|
||||
when={(p.deployment.status as ContainerStatus)?.State === "running"}
|
||||
>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
deploy{" "}
|
||||
<Flex>
|
||||
<button class="green">
|
||||
<Icon type="reset" />
|
||||
</button>
|
||||
<button class="red">
|
||||
<Icon type="trash" />
|
||||
</button>
|
||||
<Show when={true}>
|
||||
<Grid class={combineClasses(s.Actions, "shadow")}>
|
||||
<div class={s.ItemHeader}>actions</div>
|
||||
<Switch>
|
||||
<Match
|
||||
when={(p.deployment.status as ContainerStatus)?.State === "running"}
|
||||
>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
deploy{" "}
|
||||
<Flex>
|
||||
<ConfirmButton
|
||||
color="green"
|
||||
onConfirm={() => {
|
||||
ws.send(DEPLOY, { deploymentID: p.deployment._id });
|
||||
pushNotification("ok", `deploying ${p.deployment.name}...`);
|
||||
}}
|
||||
>
|
||||
<Icon type="reset" />
|
||||
</ConfirmButton>
|
||||
<ConfirmButton
|
||||
color="red"
|
||||
onConfirm={() => {
|
||||
ws.send(DELETE_CONTAINER, {
|
||||
deploymentID: p.deployment._id,
|
||||
});
|
||||
pushNotification("ok", `removing container...`);
|
||||
}}
|
||||
>
|
||||
<Icon type="trash" />
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
container{" "}
|
||||
<button class="orange">
|
||||
<Icon type="pause" />
|
||||
</button>
|
||||
</Flex>
|
||||
</Match>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
container{" "}
|
||||
<ConfirmButton
|
||||
color="orange"
|
||||
onConfirm={() => {
|
||||
ws.send(STOP_CONTAINER, { deploymentID: p.deployment._id });
|
||||
pushNotification("ok", `stopping container`);
|
||||
}}
|
||||
>
|
||||
<Icon type="pause" />
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Match>
|
||||
|
||||
<Match
|
||||
when={(p.deployment.status as ContainerStatus).State === "exited"}
|
||||
>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
deploy{" "}
|
||||
<button class="green">
|
||||
<Icon type="reset" />
|
||||
</button>
|
||||
<button class="red">
|
||||
<Icon type="trash" />
|
||||
</button>
|
||||
</Flex>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
container{" "}
|
||||
<button class="green">
|
||||
<Icon type="play" />
|
||||
</button>
|
||||
</Flex>
|
||||
</Match>
|
||||
<Match
|
||||
when={(p.deployment.status as ContainerStatus).State === "exited"}
|
||||
>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
deploy{" "}
|
||||
<ConfirmButton
|
||||
color="green"
|
||||
onConfirm={() => {
|
||||
ws.send(DEPLOY, { deploymentID: p.deployment._id });
|
||||
pushNotification("ok", `deploying ${p.deployment.name}...`);
|
||||
}}
|
||||
>
|
||||
<Icon type="reset" />
|
||||
</ConfirmButton>
|
||||
<ConfirmButton
|
||||
color="red"
|
||||
onConfirm={() => {
|
||||
ws.send(DELETE_CONTAINER, { deploymentID: p.deployment._id });
|
||||
pushNotification("ok", `removing container...`);
|
||||
}}
|
||||
>
|
||||
<Icon type="trash" />
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
container{" "}
|
||||
<ConfirmButton
|
||||
color="green"
|
||||
onConfirm={() => {
|
||||
ws.send(START_CONTAINER, { deploymentID: p.deployment._id });
|
||||
pushNotification("ok", `starting container...`);
|
||||
}}
|
||||
>
|
||||
<Icon type="play" />
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Match>
|
||||
|
||||
<Match when={p.deployment.status === "not created"}>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
deploy{" "}
|
||||
<button class="green">
|
||||
<Icon type="play" />
|
||||
</button>
|
||||
</Flex>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Grid>
|
||||
<Match when={p.deployment.status === "not created"}>
|
||||
<Flex class={combineClasses(s.Action, "shadow")}>
|
||||
deploy{" "}
|
||||
<ConfirmButton
|
||||
color="green"
|
||||
onConfirm={() => {
|
||||
ws.send(DEPLOY, { deploymentID: p.deployment._id });
|
||||
pushNotification("ok", `deploying ${p.deployment.name}...`);
|
||||
}}
|
||||
>
|
||||
<Icon type="play" />
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Grid>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.UpdatesContainer {
|
||||
max-height: 50vh;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.Update {
|
||||
background-color: rgb(69, 34, 96);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
import { Component, For, Show } from "solid-js";
|
||||
import { Component, For, onCleanup, Show } from "solid-js";
|
||||
import { useArray, useUpdates } from "../../state/hooks";
|
||||
import { combineClasses } from "../../util/helpers";
|
||||
import Grid from "../util/layout/Grid";
|
||||
import s from "./deployment.module.css";
|
||||
import Update from "../update/Update";
|
||||
import { getUpdates } from "../../util/query";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { ADD_UPDATE } from "../../state/actions";
|
||||
|
||||
const Updates: Component<{ deploymentID: string }> = (p) => {
|
||||
const { ws } = useAppState();
|
||||
const selectedUpdates = useArray(() =>
|
||||
getUpdates({ deploymentID: p.deploymentID })
|
||||
);
|
||||
const listener = ({ data }: { data: string }) => {
|
||||
const message = JSON.parse(data);
|
||||
if (
|
||||
message.type === ADD_UPDATE &&
|
||||
message.update.deploymentID === p.deploymentID
|
||||
) {
|
||||
selectedUpdates.add(message.update);
|
||||
}
|
||||
};
|
||||
ws.socket.addEventListener("message", listener);
|
||||
onCleanup(() => {
|
||||
ws.socket.removeEventListener("message", listener);
|
||||
});
|
||||
return (
|
||||
<Show
|
||||
when={
|
||||
@@ -19,9 +35,11 @@ const Updates: Component<{ deploymentID: string }> = (p) => {
|
||||
>
|
||||
<Grid class={combineClasses(s.Updates, "shadow")}>
|
||||
<div class={s.ItemHeader}>updates</div>
|
||||
<For each={selectedUpdates.collection()}>
|
||||
{(update) => <Update update={update} showName={false} />}
|
||||
</For>
|
||||
<Grid class={s.UpdatesContainer}>
|
||||
<For each={selectedUpdates.collection()}>
|
||||
{(update) => <Update update={update} showName={false} />}
|
||||
</For>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Show>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { Update as UpdateType } from "@monitor/types";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { combineClasses, readableOperation, readableTimestamp } from "../../util/helpers";
|
||||
import {
|
||||
combineClasses,
|
||||
readableOperation,
|
||||
readableTimestamp,
|
||||
} from "../../util/helpers";
|
||||
import { useToggle } from "../../util/hooks";
|
||||
import Icon from "../util/icons/Icon";
|
||||
import Flex from "../util/layout/Flex";
|
||||
import Grid from "../util/layout/Grid";
|
||||
import CenterMenu from "../util/menu/CenterMenu";
|
||||
import s from "./update.module.css";
|
||||
|
||||
const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => {
|
||||
@@ -33,7 +39,20 @@ const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => {
|
||||
} else {
|
||||
return op;
|
||||
}
|
||||
};
|
||||
const log = () => {
|
||||
const outText = p.update.log.stdout
|
||||
? `stdout:\n\n${p.update.log.stdout}` +
|
||||
(p.update.log.stderr ? "\n\n" : "")
|
||||
: "";
|
||||
const errText = p.update.log.stderr
|
||||
? `stderr:\n\n${p.update.log.stderr}`
|
||||
: "";
|
||||
return outText + errText;
|
||||
}
|
||||
const [showCommand, toggleShowCommand] = useToggle();
|
||||
const [showLog, toggleShowLog] = useToggle();
|
||||
const [showNote, toggleShowNote] = useToggle();
|
||||
return (
|
||||
<Grid gap="0.5rem" class={combineClasses(s.Update, "shadow")}>
|
||||
<Show when={p.showName}>
|
||||
@@ -46,7 +65,13 @@ const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => {
|
||||
"grid-template-rows": "1fr 1fr",
|
||||
}}
|
||||
>
|
||||
<div>{operation()}</div>
|
||||
<div
|
||||
style={{
|
||||
color: p.update.isError ? "rgb(182, 47, 52)" : "inherit",
|
||||
}}
|
||||
>
|
||||
{operation()}
|
||||
</div>
|
||||
<div style={{ "place-self": "center end" }}>
|
||||
{readableTimestamp(p.update.timestamp)}
|
||||
</div>
|
||||
@@ -56,12 +81,31 @@ const Update: Component<{ update: UpdateType; showName: boolean }> = (p) => {
|
||||
</Flex>
|
||||
<Flex justifyContent="space-between" alignItems="center">
|
||||
{/* show command */}
|
||||
<Icon type="arrow-down" />
|
||||
<CenterMenu
|
||||
title="command"
|
||||
show={showCommand}
|
||||
toggleShow={toggleShowCommand}
|
||||
target={<Icon type="arrow-down" />}
|
||||
content={<pre class={s.Log}>{p.update.command}</pre>}
|
||||
/>
|
||||
|
||||
<Show when={p.update.note}>
|
||||
<Icon type="arrow-down" />
|
||||
<CenterMenu
|
||||
title="note"
|
||||
show={showNote}
|
||||
toggleShow={toggleShowNote}
|
||||
target={<Icon type="arrow-down" />}
|
||||
content={<div></div>}
|
||||
/>
|
||||
</Show>
|
||||
{/* show log */}
|
||||
<Icon type="arrow-down" />
|
||||
<CenterMenu
|
||||
title="log"
|
||||
show={showLog}
|
||||
toggleShow={toggleShowLog}
|
||||
target={<Icon type="arrow-down" />}
|
||||
content={<pre class={s.Log}>{log()}</pre>}
|
||||
/>
|
||||
</Flex>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
.Update {
|
||||
background-color: rgb(98, 46, 46);
|
||||
background-color: rgb(83, 37, 37);
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.Log {
|
||||
white-space: pre-line;
|
||||
overflow-wrap: anywhere;
|
||||
word-wrap: break-word;
|
||||
max-height: 80vh;
|
||||
overflow: scroll;
|
||||
tab-size: 2;
|
||||
-moz-tab-size: 2;
|
||||
width: 40rem;
|
||||
max-width: 90vw;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { Component, createSignal, JSX } from "solid-js";
|
||||
|
||||
const ConfirmButton: Component<{
|
||||
onConfirm: () => void;
|
||||
color?: "red" | "green" | "blue";
|
||||
color?: "red" | "green" | "blue" | "orange";
|
||||
style?: JSX.CSSProperties;
|
||||
}> = (p) => {
|
||||
const [confirm, set] = createSignal(false);
|
||||
@@ -20,7 +20,7 @@ const ConfirmButton: Component<{
|
||||
set(confirm => !confirm);
|
||||
}}
|
||||
>
|
||||
{confirm() ? "Confirm" : p.children}
|
||||
{confirm() ? "confirm" : p.children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,9 @@ export type IconType =
|
||||
| "reset"
|
||||
| "plus"
|
||||
| "minus"
|
||||
| "floppy-disk";
|
||||
| "floppy-disk"
|
||||
| "download"
|
||||
| "upload";
|
||||
|
||||
const Icon: Component<{
|
||||
type: IconType;
|
||||
|
||||
@@ -115,14 +115,14 @@
|
||||
}
|
||||
|
||||
.CenterMenuContainer {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
z-index: 200;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
place-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.CenterMenuTitle {
|
||||
|
||||
@@ -85,7 +85,6 @@ export function useUpdates(query?: Parameters<typeof getUpdates>[0]) {
|
||||
export function useArray<T>(query: () => Promise<T[]>) {
|
||||
const [collection, set] = createSignal<T[]>();
|
||||
createEffect(() => {
|
||||
console.log("running query")
|
||||
query().then(set);
|
||||
})
|
||||
const add = (item: T) => {
|
||||
|
||||
@@ -33,6 +33,7 @@ function socket(state: State) {
|
||||
});
|
||||
|
||||
return {
|
||||
socket: ws,
|
||||
send: <T>(type: string, message: T) => {
|
||||
ws.send(JSON.stringify({ ...message, type }));
|
||||
},
|
||||
|
||||
+2
-2
@@ -118,7 +118,7 @@ export async function dockerRun(
|
||||
repoMount?: { repoFolder: string; containerMount: string }
|
||||
) {
|
||||
const command =
|
||||
`docker pull ${image}${latest && ":latest"} && docker run -d` +
|
||||
`docker pull ${image}${latest ? ":latest" : ""} && docker run -d` +
|
||||
name(containerName) +
|
||||
containerUserString(containerUser) +
|
||||
portsString(ports) +
|
||||
@@ -173,7 +173,7 @@ function repoVolume(
|
||||
|
||||
function restartString(restart?: string) {
|
||||
return restart
|
||||
? ` --restart=${restart}${restart === "on-failure" ? ":10" : ""}`
|
||||
? ` --restart ${restart}${restart === "on-failure" ? ":10" : ""}`
|
||||
: "";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user