mirror of
https://github.com/moghtech/komodo.git
synced 2026-07-17 20:42:49 -05:00
selected state deployment and server / deployment status
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<div class={s.Deployment} >
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 (
|
||||
<Show when={deployment()}>
|
||||
<div class={s.Deployment}>
|
||||
<div>{deployment()!.name}</div>
|
||||
</div>
|
||||
<button class={s.Deployment}>
|
||||
<div>{deployment()!.name}</div>
|
||||
<div>{status()}</div>
|
||||
</button>
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Deployment;
|
||||
export default Deployment;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<typeof useBuilds>;
|
||||
deployments: ReturnType<typeof useDeployments>;
|
||||
updates: ReturnType<typeof useUpdates>;
|
||||
selected: ReturnType<typeof useSelected>;
|
||||
sidebar: {
|
||||
open: Accessor<boolean>,
|
||||
open: Accessor<boolean>;
|
||||
toggle: () => void;
|
||||
};
|
||||
};
|
||||
@@ -22,16 +19,20 @@ export type State = {
|
||||
const context = createContext<State & { ws: ReturnType<typeof socket> }>();
|
||||
|
||||
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<typeof socket> };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T>(query: () => Promise<T[]>) {
|
||||
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<T>(query: () => Promise<Collection<T>>) {
|
||||
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,
|
||||
|
||||
@@ -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<boolean>, () => void] {
|
||||
const [s, set] = createSignal(initial);
|
||||
|
||||
@@ -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": {
|
||||
|
||||
4
types/types.d.ts
vendored
4
types/types.d.ts
vendored
@@ -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";
|
||||
};
|
||||
|
||||
@@ -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<ContainerStatus | "not created"> {
|
||||
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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user