diff --git a/core/src/messages/builds/index.ts b/core/src/messages/builds/index.ts index cd28058d6..a9de62e7e 100644 --- a/core/src/messages/builds/index.ts +++ b/core/src/messages/builds/index.ts @@ -4,7 +4,7 @@ import { CLONE_BUILD_REPO, CREATE_BUILD, DELETE_BUILD, - PULL, + PULL_BUILD, UPDATE_BUILD, } from "@monitor/util"; import { FastifyInstance } from "fastify"; @@ -47,7 +47,7 @@ async function buildMessages( } return true; - case PULL: + case PULL_BUILD: message.buildID && (await pullRepo(app, user, message)); return true; diff --git a/core/src/messages/builds/pull.ts b/core/src/messages/builds/pull.ts index 909e0ebe7..347337027 100644 --- a/core/src/messages/builds/pull.ts +++ b/core/src/messages/builds/pull.ts @@ -1,5 +1,5 @@ import { User } from "@monitor/types"; -import { prettyStringify, pull, PULL } from "@monitor/util"; +import { prettyStringify, pull, PULL_BUILD } from "@monitor/util"; import { FastifyInstance } from "fastify"; import { PERMISSIONS_DENY_LOG, BUILD_REPO_PATH } from "../../config"; import { PULLING } from "../../plugins/actionStates"; @@ -16,7 +16,7 @@ async function pullRepo( addBuildUpdate( app, buildID, - PULL, + PULL_BUILD, "Pull (DENIED)", PERMISSIONS_DENY_LOG, user.username, @@ -27,7 +27,7 @@ async function pullRepo( } if (!app.buildActionStates.get(buildID, PULLING)) { app.buildActionStates.set(buildID, PULLING, true); - app.broadcast(PULL, { complete: false, buildID }); + app.broadcast(PULL_BUILD, { complete: false, buildID }); try { const { pullName, branch } = build; const { command, log, isError } = await pull( @@ -37,7 +37,7 @@ async function pullRepo( addBuildUpdate( app, buildID, - PULL, + PULL_BUILD, command, log, user.username, @@ -48,7 +48,7 @@ async function pullRepo( addBuildUpdate( app, buildID, - PULL, + PULL_BUILD, "Pull (ERROR)", { stderr: prettyStringify(error) }, user.username, @@ -56,7 +56,7 @@ async function pullRepo( true ); } - app.broadcast(PULL, { complete: true, buildID }); + app.broadcast(PULL_BUILD, { complete: true, buildID }); app.buildActionStates.set(buildID, PULLING, false); } } diff --git a/core/src/messages/deployments/index.ts b/core/src/messages/deployments/index.ts index 1aac6155b..316214fa0 100644 --- a/core/src/messages/deployments/index.ts +++ b/core/src/messages/deployments/index.ts @@ -1,11 +1,10 @@ import { User } from "@monitor/types"; import { - COPY_ENV, CREATE_DEPLOYMENT, DELETE_CONTAINER, DELETE_DEPLOYMENT, DEPLOY, - REFRESH_CONTAINER_STATUS, + PULL_DEPLOYMENT, START_CONTAINER, STOP_CONTAINER, UPDATE_DEPLOYMENT, @@ -20,6 +19,7 @@ import { import createDeployment from "./create"; import deleteDeployment from "./delete"; import deployDeployment from "./deploy"; +import pullDeploymentRepo from "./pull"; import updateDeployment from "./update"; async function deploymentMessages( @@ -65,10 +65,8 @@ async function deploymentMessages( await deleteDeploymentContainer(app, user, message); return true; - case REFRESH_CONTAINER_STATUS: - return true; - - case COPY_ENV: + case PULL_DEPLOYMENT: + await pullDeploymentRepo(app, user, message) return true; default: diff --git a/core/src/messages/deployments/pull.ts b/core/src/messages/deployments/pull.ts new file mode 100644 index 000000000..78f0cdca9 --- /dev/null +++ b/core/src/messages/deployments/pull.ts @@ -0,0 +1,80 @@ +import { User } from "@monitor/types"; +import { execute, mergeCommandLogError, PULL_DEPLOYMENT, pull } from "@monitor/util"; +import { FastifyInstance } from "fastify"; +import { join } from "path"; +import { DEPLOYMENT_REPO_PATH, PERMISSIONS_DENY_LOG, SYSTEM_OPERATOR } from "../../config"; +import { pullPeriphery } from "../../util/periphery/git"; +import { addDeploymentUpdate } from "../../util/updates"; + +async function pullDeploymentRepo( + app: FastifyInstance, + user: User, + { deploymentID }: { deploymentID: string } +) { + const deployment = await app.deployments.findById(deploymentID); + if (!deployment) { + return; + } + if (user.permissions! < 2 && !deployment.owners.includes(user.username)) { + addDeploymentUpdate( + app, + deploymentID, + PULL_DEPLOYMENT, + "Pull Deployemnt (DENIED)", + PERMISSIONS_DENY_LOG, + user.username, + undefined, + true + ); + return; + } + const { branch, containerName, onPull, serverID } = deployment; + const server = await app.servers.findById(serverID!); + if (!server) { + return; + } + app.deployActionStates.set(deploymentID, "pulling", true); + app.broadcast(PULL_DEPLOYMENT, { deploymentID, complete: false }); + if (server.isCore) { + const pullCle = await pull(join(DEPLOYMENT_REPO_PATH, containerName!), branch); + const onPullCle = + onPull && + (await execute( + `cd ${join( + DEPLOYMENT_REPO_PATH, + containerName!, + onPull.path || "" + )} && ${onPull.command}` + )); + const { command, log, isError } = mergeCommandLogError( + { name: "pull", cle: pullCle }, + { name: "on pull", cle: onPullCle } + ); + addDeploymentUpdate( + app, + deploymentID, + PULL_DEPLOYMENT, + command, + log, + SYSTEM_OPERATOR, + "", + isError + ); + } else { + const { command, log, isError } = await pullPeriphery(server, deployment); + await addDeploymentUpdate( + app, + deploymentID, + PULL_DEPLOYMENT, + command, + log, + SYSTEM_OPERATOR, + "", + isError + ); + } + app.deployActionStates.set(deploymentID, "pulling", false); + app.broadcast(PULL_DEPLOYMENT, { deploymentID, complete: true }); +} + +export default pullDeploymentRepo; \ No newline at end of file diff --git a/core/src/plugins/actionStates.ts b/core/src/plugins/actionStates.ts index 772f6d8c2..c3c3e9a2a 100644 --- a/core/src/plugins/actionStates.ts +++ b/core/src/plugins/actionStates.ts @@ -81,6 +81,7 @@ const actionStates = fp((app: FastifyInstance, _: {}, done: () => void) => { stopping: false, updating: false, fullDeleting: false, + pulling: false, }; }, delete: (deploymentID: string) => { diff --git a/core/src/routes/deployments.ts b/core/src/routes/deployments.ts index 1e7c3be23..4758ba1b2 100644 --- a/core/src/routes/deployments.ts +++ b/core/src/routes/deployments.ts @@ -25,7 +25,7 @@ const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => { } const deployments = await app.deployments.find( { serverID: server._id }, - "name containerName serverID owners" + "name containerName serverID owners repo" ); const status = server.isCore ? await deploymentStatusLocal(app) diff --git a/core/src/routes/listener.ts b/core/src/routes/listener.ts index e5b164fae..37fefb6e7 100644 --- a/core/src/routes/listener.ts +++ b/core/src/routes/listener.ts @@ -81,7 +81,7 @@ const listener = fp((app: FastifyInstance, _: {}, done: () => void) => { return; } if (server.isCore) { - const pullCle = await pull(join(BUILD_REPO_PATH, containerName!), branch); + const pullCle = await pull(join(DEPLOYMENT_REPO_PATH, containerName!), branch); const onPullCle = onPull && (await execute( diff --git a/frontend/src/components/deployment/ActionStateProvider.tsx b/frontend/src/components/deployment/ActionStateProvider.tsx index e842a768e..77b44959d 100644 --- a/frontend/src/components/deployment/ActionStateProvider.tsx +++ b/frontend/src/components/deployment/ActionStateProvider.tsx @@ -7,7 +7,7 @@ import { useContext, } from "solid-js"; import { createStore } from "solid-js/store"; -import { DELETE_CONTAINER, DELETE_DEPLOYMENT, DEPLOY, START_CONTAINER, STOP_CONTAINER } from "../../state/actions"; +import { DELETE_CONTAINER, DELETE_DEPLOYMENT, DEPLOY, PULL_DEPLOYMENT, START_CONTAINER, STOP_CONTAINER } from "../../state/actions"; import { useAppState } from "../../state/StateProvider"; import { getDeploymentActionState } from "../../util/query"; @@ -24,6 +24,7 @@ export const ActionStateProvider: Component<{}> = (p) => { stopping: false, fullDeleting: false, updating: false, + pulling: false, }); createEffect(() => { getDeploymentActionState(selected.id()).then(setActions); @@ -63,6 +64,13 @@ export const ActionStateProvider: Component<{}> = (p) => { } }) ); + onCleanup( + ws.subscribe([PULL_DEPLOYMENT], ({ complete, deploymentID }) => { + if (deploymentID === selected.id()) { + setActions("pulling", !complete); + } + }) + ); return {p.children}; }; diff --git a/frontend/src/components/deployment/Actions.tsx b/frontend/src/components/deployment/Actions.tsx index ee0a4b489..75edf5342 100644 --- a/frontend/src/components/deployment/Actions.tsx +++ b/frontend/src/components/deployment/Actions.tsx @@ -1,23 +1,15 @@ -import { ContainerStatus, DeployActionState } from "@monitor/types"; -import { - Component, - createEffect, - Match, - onCleanup, - Show, - Switch, -} from "solid-js"; -import { createStore } from "solid-js/store"; +import { ContainerStatus } from "@monitor/types"; +import { Component, Match, Show, Switch } from "solid-js"; import { pushNotification } from "../.."; import { DELETE_CONTAINER, DEPLOY, + PULL_DEPLOYMENT, START_CONTAINER, STOP_CONTAINER, } from "../../state/actions"; import { useAppState } from "../../state/StateProvider"; import { useUser } from "../../state/UserProvider"; -import { getDeploymentActionState } from "../../util/query"; import ConfirmButton from "../util/ConfirmButton"; import Icon from "../util/icons/Icon"; import Flex from "../util/layout/Flex"; @@ -57,7 +49,7 @@ const Actions: Component<{}> = (p) => { { - ws.send(DEPLOY, { deploymentID: deployment()._id }); + ws.send(DEPLOY, { deploymentID: selected.id() }); pushNotification( "ok", `deploying ${deployment().name}...` @@ -80,7 +72,7 @@ const Actions: Component<{}> = (p) => { color="red" onConfirm={() => { ws.send(DELETE_CONTAINER, { - deploymentID: deployment()._id, + deploymentID: selected.id(), }); pushNotification("ok", `removing container...`); }} @@ -214,6 +206,22 @@ const Actions: Component<{}> = (p) => { + + + pull{" "} + + { + ws.send(PULL_DEPLOYMENT, { deploymentID: selected.id() }); + pushNotification("ok", `pulling ${deployment().name}...`); + }} + > + + + + + ); diff --git a/frontend/src/state/actions.ts b/frontend/src/state/actions.ts index 091d9ac85..4c873b2f9 100644 --- a/frontend/src/state/actions.ts +++ b/frontend/src/state/actions.ts @@ -2,7 +2,7 @@ export const CREATE_BUILD = "CREATE_BUILD"; export const DELETE_BUILD = "DELETE_BUILD"; export const UPDATE_BUILD = "UPDATE_BUILD"; -export const PULL = "PULL"; +export const PULL_BUILD = "PULL_BUILD"; export const BUILD = "BUILD"; export const CLONE_BUILD_REPO = "CLONE_BUILD_REPO"; @@ -17,6 +17,7 @@ export const DELETE_CONTAINER = "DELETE_CONTAINER"; export const REFRESH_CONTAINER_STATUS = "REFRESH_CONTAINER_STATUS"; export const COPY_ENV = "COPY_ENV"; export const CLONE_DEPLOYMENT_REPO = "CLONE_DEPLOYMENT_REPO"; +export const PULL_DEPLOYMENT = "PULL_DEPLOYMENT"; /* SERVER */ export const ADD_SERVER = "ADD_SERVER"; @@ -32,4 +33,4 @@ export const PRUNE_NETWORKS = "PRUNE_NETWORKS"; export const ADD_UPDATE = "ADD_UPDATE"; /* ALERT */ -export const ALERT = "ALERT" +export const ALERT = "ALERT"; diff --git a/types/types.d.ts b/types/types.d.ts index 6b203eb67..2918e9e3e 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -151,6 +151,7 @@ export type DeployActionState = { stopping: boolean; updating: boolean; fullDeleting: boolean; + pulling: boolean; }; export type ServerActionState = { diff --git a/util/actions.ts b/util/actions.ts index de493b28e..8060cd707 100644 --- a/util/actions.ts +++ b/util/actions.ts @@ -2,9 +2,9 @@ export const CREATE_BUILD = "CREATE_BUILD"; export const DELETE_BUILD = "DELETE_BUILD"; export const UPDATE_BUILD = "UPDATE_BUILD"; -export const PULL = "PULL"; export const BUILD = "BUILD"; export const CLONE_BUILD_REPO = "CLONE_BUILD_REPO"; +export const PULL_BUILD = "PULL_BUILD"; /* DEPLOY */ export const CREATE_DEPLOYMENT = "CREATE_DEPLOYMENT"; @@ -17,6 +17,7 @@ export const DELETE_CONTAINER = "DELETE_CONTAINER"; export const REFRESH_CONTAINER_STATUS = "REFRESH_CONTAINER_STATUS"; export const COPY_ENV = "COPY_ENV"; export const CLONE_DEPLOYMENT_REPO = "CLONE_DEPLOYMENT_REPO"; +export const PULL_DEPLOYMENT = "PULL_DEPLOYMENT"; /* SERVER */ export const ADD_SERVER = "ADD_SERVER";