From cc12f7221eba0a84e939dccafd7fe893703b0d4a Mon Sep 17 00:00:00 2001 From: Lance Cain <90141999+mizady@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:28:55 -0400 Subject: [PATCH] add container buttons Added start and stop service buttons for each service in a stack by changes to the container and compose components as well as the socket handler and the stack class. --- .../docker-socket-handler.ts | 45 +++++++++++++++++++ backend/stack.ts | 20 +++++++++ frontend/src/components/Container.vue | 20 +++++++++ frontend/src/pages/Compose.vue | 29 ++++++++++++ 4 files changed, 114 insertions(+) diff --git a/backend/agent-socket-handlers/docker-socket-handler.ts b/backend/agent-socket-handlers/docker-socket-handler.ts index 93abe85..ae9bf18 100644 --- a/backend/agent-socket-handlers/docker-socket-handler.ts +++ b/backend/agent-socket-handlers/docker-socket-handler.ts @@ -141,6 +141,8 @@ export class DockerSocketHandler extends AgentSocketHandler { msg: "Stopped" }, callback); server.sendStackList(); + + stack.leaveCombinedTerminal(socket); } catch (e) { callbackError(e, callback); } @@ -229,6 +231,49 @@ export class DockerSocketHandler extends AgentSocketHandler { } }); + // Start a service + agentSocket.on("startService", async (stackName: unknown, serviceName: unknown, callback) => { + try { + checkLogin(socket); + + if (typeof (stackName) !== "string" || typeof (serviceName) !== "string") { + throw new ValidationError("Stack name and service name must be strings"); + } + + const stack = await Stack.getStack(server, stackName); + await stack.startService(socket, serviceName); + stack.joinCombinedTerminal(socket); // Ensure the combined terminal is joined + callbackResult({ + ok: true, + msg: `Service ${serviceName} started` + }, callback); + server.sendStackList(); + } catch (e) { + callbackError(e, callback); + } + }); + + // Stop a service + agentSocket.on("stopService", async (stackName: unknown, serviceName: unknown, callback) => { + try { + checkLogin(socket); + + if (typeof (stackName) !== "string" || typeof (serviceName) !== "string") { + throw new ValidationError("Stack name and service name must be strings"); + } + + const stack = await Stack.getStack(server, stackName); + await stack.stopService(socket, serviceName); + callbackResult({ + ok: true, + msg: `Service ${serviceName} stopped` + }, callback); + server.sendStackList(); + } catch (e) { + callbackError(e, callback); + } + }); + // getExternalNetworkList agentSocket.on("getDockerNetworkList", async (callback) => { try { diff --git a/backend/stack.ts b/backend/stack.ts index fbce500..8605f02 100644 --- a/backend/stack.ts +++ b/backend/stack.ts @@ -530,4 +530,24 @@ export class Stack { } } + + async startService(socket: DockgeSocket, serviceName: string) { + const terminalName = getComposeTerminalName(socket.endpoint, this.name); + const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "up", "-d", serviceName], this.path); + if (exitCode !== 0) { + throw new Error(`Failed to start service ${serviceName}, please check the terminal output for more information.`); + } + + return exitCode; + } + + async stopService(socket: DockgeSocket, serviceName: string): Promise { + const terminalName = getComposeTerminalName(socket.endpoint, this.name); + const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "stop", serviceName], this.path); + if (exitCode !== 0) { + throw new Error(`Failed to stop service ${serviceName}, please check the terminal output for more information.`); + } + + return exitCode; + } } diff --git a/frontend/src/components/Container.vue b/frontend/src/components/Container.vue index 12f7709..0ca135a 100644 --- a/frontend/src/components/Container.vue +++ b/frontend/src/components/Container.vue @@ -20,6 +20,20 @@ Bash + + @@ -284,6 +298,12 @@ export default defineComponent({ remove() { delete this.jsonObject.services[this.name]; }, + startService() { + this.$emit('start-service', this.name); + }, + stopService() { + this.$emit('stop-service', this.name); + } } }); diff --git a/frontend/src/pages/Compose.vue b/frontend/src/pages/Compose.vue index 512f090..4e65d08 100644 --- a/frontend/src/pages/Compose.vue +++ b/frontend/src/pages/Compose.vue @@ -129,6 +129,9 @@ :is-edit-mode="isEditMode" :first="name === Object.keys(jsonConfig.services)[0]" :status="serviceStatusList[name]" + :processing="processing" + @start-service="startService" + @stop-service="stopService" /> @@ -786,6 +789,32 @@ export default { this.stack.name = this.stack?.name?.toLowerCase(); }, + startService(serviceName) { + this.processing = true; + + this.$root.emitAgent(this.endpoint, "startService", this.stack.name, serviceName, (res) => { + this.processing = false; + this.$root.toastRes(res); + + if (res.ok) { + this.requestServiceStatus(); // Refresh service status + } + }); + }, + + stopService(serviceName) { + this.processing = true; + + this.$root.emitAgent(this.endpoint, "stopService", this.stack.name, serviceName, (res) => { + this.processing = false; + this.$root.toastRes(res); + + if (res.ok) { + this.requestServiceStatus(); // Refresh service status + } + }); + }, + } };