From d059d7fb301abd3d2fd805d537e4519ed246efeb Mon Sep 17 00:00:00 2001 From: mbecker20 Date: Wed, 23 Mar 2022 02:20:02 -0700 Subject: [PATCH] selected state deployment and server / deployment status --- core/src/routes/deployments.ts | 26 ++++++++++++++---- core/src/routes/servers.ts | 2 +- core/src/util/deploymentStatus.ts | 27 ++++--------------- .../src/components/deployment/Deployment.tsx | 3 ++- .../src/components/sidebar/Sidebar.module.css | 6 +++++ .../components/sidebar/server/Deployment.tsx | 26 +++++++++++------- frontend/src/index.css | 3 ++- frontend/src/state/StateProvider.tsx | 21 ++++++++------- frontend/src/state/hooks.ts | 24 ++++++++++++++--- frontend/src/util/hooks.ts | 1 + package.json | 1 + types/types.d.ts | 4 ++- util/docker.ts | 5 ++-- 13 files changed, 93 insertions(+), 56 deletions(-) diff --git a/core/src/routes/deployments.ts b/core/src/routes/deployments.ts index 921e2cba1..e73371028 100644 --- a/core/src/routes/deployments.ts +++ b/core/src/routes/deployments.ts @@ -1,10 +1,11 @@ import { + getContainerStatus, intoCollection, } from "@monitor/util"; import { FastifyInstance } from "fastify"; import fp from "fastify-plugin"; import { deploymentStatusLocal } from "../util/deploymentStatus"; -import { getPeripheryContainers } from "../util/periphery/container"; +import { getPeripheryContainer, getPeripheryContainers } from "../util/periphery/container"; const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => { app.get("/deployments", { onRequest: [app.auth] }, async (req, res) => { @@ -21,12 +22,12 @@ const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => { { serverID: server._id }, "name containerName serverID" ); - const status = server.isCore ? await deploymentStatusLocal(app, deployments) : await getPeripheryContainers(server); + const status = server.isCore ? await deploymentStatusLocal(app) : await getPeripheryContainers(server); res.send( intoCollection( - deployments.map((dep) => ({ - ...dep, - status: status[dep.containerName!], + deployments.map((deployment) => ({ + ...deployment, + status: status[deployment.containerName!], })) ) ); @@ -35,6 +36,21 @@ const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => { app.get("/deployment/:id", { onRequest: [app.auth] }, async (req, res) => { const { id } = req.params as { id: string }; const deployment = await app.deployments.findById(id); + if (!deployment) { + res.status(400); + res.send("could not find deployment"); + return; + } + const onCore = deployment.serverID === app.core._id; + const server = onCore ? app.core : await app.servers.findById(deployment.serverID!); + if (!server) { + res.status(400); + res.send("could not find deployment's server"); + return; + } + deployment.status = onCore + ? await getContainerStatus(app.dockerode, deployment.containerName!) + : await getPeripheryContainer(server, deployment.containerName!); res.send(deployment); }); done(); diff --git a/core/src/routes/servers.ts b/core/src/routes/servers.ts index 577fc5f8d..5f4c047aa 100644 --- a/core/src/routes/servers.ts +++ b/core/src/routes/servers.ts @@ -5,7 +5,7 @@ import { serverStatusPeriphery } from "../util/periphery/status"; const servers = fp((app: FastifyInstance, _: {}, done: () => void) => { app.get("/servers", { onRequest: [app.auth] }, async (req, res) => { - const servers = await app.servers.find({}, "name enabled"); + const servers = await app.servers.find({}); await Promise.all( servers.map(async (server) => { server.status = (await serverStatusPeriphery(server)) diff --git a/core/src/util/deploymentStatus.ts b/core/src/util/deploymentStatus.ts index e16e28098..cd3ec71ba 100644 --- a/core/src/util/deploymentStatus.ts +++ b/core/src/util/deploymentStatus.ts @@ -1,10 +1,8 @@ -import { ContainerStatus, Deployment } from "@monitor/types"; import { objFrom2Arrays } from "@monitor/util"; import { FastifyInstance } from "fastify"; export async function deploymentStatusLocal( app: FastifyInstance, - deploymentsAr: Deployment[] ) { const statusAr = await app.dockerode.listContainers({ all: true }); const statusNames = statusAr.map((stat) => @@ -20,27 +18,12 @@ export async function deploymentStatusLocal( ); return objFrom2Arrays( statusNames, - statusNames.map((name) => { - const tryDeployment = getDeployment(status[name]!, deploymentsAr); - const _id = tryDeployment ? tryDeployment._id : "none"; - return { - ...status[name], - deploymentID: _id, - }; - }) + statusAr.map((stat, i) => ({ + name: statusNames[i], + Status: stat.Status, + State: stat.State as "running" | "exited", + })) ); } -function getDeployment( - status: ContainerStatus, - deploymentsAr: Deployment[] -) { - for (let i = 0; i < deploymentsAr.length; i++) { - if (deploymentsAr[i].containerName === status.name) { - return deploymentsAr[i]; - } - } - return undefined; -} - diff --git a/frontend/src/components/deployment/Deployment.tsx b/frontend/src/components/deployment/Deployment.tsx index 233091a76..91fad4650 100644 --- a/frontend/src/components/deployment/Deployment.tsx +++ b/frontend/src/components/deployment/Deployment.tsx @@ -2,8 +2,9 @@ import { Component } from "solid-js"; import { useAppState } from "../../state/StateProvider"; import s from "./deployment.module.css"; -const Deployment: Component<{}> = (p) => { +const Deployment: Component<{ id: string }> = (p) => { const { servers, deployments } = useAppState(); + return (
diff --git a/frontend/src/components/sidebar/Sidebar.module.css b/frontend/src/components/sidebar/Sidebar.module.css index 70d2ab69d..c2776a5fb 100644 --- a/frontend/src/components/sidebar/Sidebar.module.css +++ b/frontend/src/components/sidebar/Sidebar.module.css @@ -1,6 +1,7 @@ .Sidebar { grid-area: sidebar; background-color: blue; + overflow-y: scroll; } .Server { @@ -10,4 +11,9 @@ .Deployments { background-color: rgb(85, 85, 85); +} + +.Deployment { + padding: 0.5rem 1rem; + justify-content: space-between; } \ No newline at end of file diff --git a/frontend/src/components/sidebar/server/Deployment.tsx b/frontend/src/components/sidebar/server/Deployment.tsx index 3f2d56bb5..bed68c41f 100644 --- a/frontend/src/components/sidebar/server/Deployment.tsx +++ b/frontend/src/components/sidebar/server/Deployment.tsx @@ -1,18 +1,26 @@ +import { ContainerStatus } from "@monitor/types"; import { Component, Show } from "solid-js"; import { useAppState } from "../../../state/StateProvider"; import s from "../sidebar.module.css"; const Deployment: Component<{ id: string }> = (p) => { - const { deployments } = useAppState(); - const deployment = () => deployments.get(p.id); - - return ( + const { deployments } = useAppState(); + const deployment = () => deployments.get(p.id); + const status = () => { + if (!deployment() || deployment()!.status === "not created") { + return "not created"; + } else { + return (deployment()!.status as ContainerStatus).State; + } + }; + return ( -
-
{deployment()!.name}
-
+
); -} +}; -export default Deployment; \ No newline at end of file +export default Deployment; diff --git a/frontend/src/index.css b/frontend/src/index.css index da99a7b8a..5f048c946 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -6,7 +6,8 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; background-color: lightskyblue; - + scrollbar-color: rgba(252, 234, 222, 0.3) transparent; + scrollbar-width: thin; color: #fceade; } diff --git a/frontend/src/state/StateProvider.tsx b/frontend/src/state/StateProvider.tsx index 46e66054e..9bbbf65ea 100644 --- a/frontend/src/state/StateProvider.tsx +++ b/frontend/src/state/StateProvider.tsx @@ -1,11 +1,7 @@ import { Accessor, Component, createContext, useContext } from "solid-js"; +import { createStore, SetStoreFunction } from "solid-js/store"; import { useLocalStorageToggle } from "../util/hooks"; -import { - useBuilds, - useDeployments, - useServers, - useUpdates, -} from "./hooks"; +import { useBuilds, useDeployments, useSelected, useServers, useUpdates } from "./hooks"; import socket from "./socket"; export type State = { @@ -13,8 +9,9 @@ export type State = { builds: ReturnType; deployments: ReturnType; updates: ReturnType; + selected: ReturnType; sidebar: { - open: Accessor, + open: Accessor; toggle: () => void; }; }; @@ -22,16 +19,20 @@ export type State = { const context = createContext }>(); export const AppStateProvider: Component<{}> = (p) => { - const [sidebarOpen, toggleSidebarOpen] = useLocalStorageToggle("sidebar-open"); + const [sidebarOpen, toggleSidebarOpen] = useLocalStorageToggle( + "sidebar-open", + true + ); const state: State = { servers: useServers(), builds: useBuilds(), deployments: useDeployments(), updates: useUpdates(), + selected: useSelected(), sidebar: { open: sidebarOpen, toggle: toggleSidebarOpen, - } + }, }; // created state before attaching ws, to pass state easily @@ -44,4 +45,4 @@ export const AppStateProvider: Component<{}> = (p) => { export function useAppState() { return useContext(context) as State & { ws: ReturnType }; -} \ No newline at end of file +} diff --git a/frontend/src/state/hooks.ts b/frontend/src/state/hooks.ts index 555567f74..c34af7078 100644 --- a/frontend/src/state/hooks.ts +++ b/frontend/src/state/hooks.ts @@ -1,6 +1,7 @@ import { Collection, Update } from "@monitor/types"; import { createEffect, createResource } from "solid-js"; import { filterOutFromObj } from "../util/helpers"; +import { useLocalStorage } from "../util/hooks"; import { getBuilds, getDeployments, @@ -8,6 +9,21 @@ import { getUpdates, } from "../util/query"; +export function useSelected() { + const [selected, setSelected] = useLocalStorage<{ + id: string; + type: "server" | "deployment" | "build"; + }>({ id: "", type: "deployment" }, "selected-item"); + const set = (id: string, type: "server" | "deployment" | "build") => { + setSelected({ id, type }); + }; + return { + id: () => selected().id, + type: () => selected().type, + set, + }; +} + export function useServers() { return useCollection(getServers); } @@ -29,11 +45,11 @@ export function useArray(query: () => Promise) { const push = (update: Update) => { mutate((updates: any) => [update, ...updates]); }; - const loaded = () => collection() ? true : false; + const loaded = () => (collection() ? true : false); return { collection, push, - loaded + loaded, }; } @@ -58,9 +74,9 @@ export function useCollection(query: () => Promise>) { return collection() && collection()![id]; }; const ids = () => collection() && Object.keys(collection()!); - const loaded = () => collection() ? true : false; + const loaded = () => (collection() ? true : false); - createEffect(() => console.log(collection())) + createEffect(() => console.log(collection())); return { collection, diff --git a/frontend/src/util/hooks.ts b/frontend/src/util/hooks.ts index 5faa1a1b4..18e4f626b 100644 --- a/frontend/src/util/hooks.ts +++ b/frontend/src/util/hooks.ts @@ -1,4 +1,5 @@ import { Accessor, createSignal, onCleanup, onMount } from "solid-js"; +import { createStore, DeepReadonly, SetStoreFunction } from "solid-js/store"; export function useToggle(initial = false): [Accessor, () => void] { const [s, set] = createSignal(initial); diff --git a/package.json b/package.json index 829175d36..ce89ed228 100644 --- a/package.json +++ b/package.json @@ -20,6 +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", "push-periphery": "cd periphery && yarn push" }, "devDependencies": { diff --git a/types/types.d.ts b/types/types.d.ts index 60bd7b89f..ecf94eec5 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -90,6 +90,9 @@ export interface Deployment extends DockerRunArgs { branch?: string; accessToken?: string; containerMount?: string; // the file path to mount repo on inside the container + + // running status + status?: "not created" | ContainerStatus; } export type Conversion = { @@ -120,7 +123,6 @@ export type DeployActionState = { export type ContainerStatus = { name: string; - deploymentID?: string; Status: string; State: "running" | "exited"; }; diff --git a/util/docker.ts b/util/docker.ts index 141cff7d4..9a15f7287 100644 --- a/util/docker.ts +++ b/util/docker.ts @@ -1,4 +1,5 @@ import { + ContainerStatus, Conversion, DockerBuildArgs, DockerRunArgs, @@ -30,13 +31,13 @@ export async function allContainerStatus(dockerode: Dockerode) { ); } -export async function getContainerStatus(dockerode: Dockerode, name: string) { +export async function getContainerStatus(dockerode: Dockerode, name: string): Promise { const status = (await dockerode.listContainers({ all: true })).filter( ({ Names }) => Names[0] === "/" + name ); return status[0] ? { - State: status[0].State, + State: status[0].State as "running" | "exited", Status: status[0].Status, name, }