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 1/3] 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 93abe851..ae9bf189 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 fbce5002..8605f02a 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 12f77096..0ca135a7 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 512f090f..4e65d083 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 + } + }); + }, + } }; From faa052933ebc1e5e7a3b8b1a70cc80b6ca4b8316 Mon Sep 17 00:00:00 2001 From: Lance Cain <90141999+mizady@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:27:25 -0400 Subject: [PATCH 2/3] add restart button added restart service/container button as well as fixed start/stop buttons for correct statuses of healthy/unhealthy --- .../docker-socket-handler.ts | 19 +++++++++++++++++++ backend/stack.ts | 14 ++++++++++++-- frontend/src/components/Container.vue | 19 +++++++++++++++---- frontend/src/pages/Compose.vue | 13 +++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/backend/agent-socket-handlers/docker-socket-handler.ts b/backend/agent-socket-handlers/docker-socket-handler.ts index ae9bf189..b14a389d 100644 --- a/backend/agent-socket-handlers/docker-socket-handler.ts +++ b/backend/agent-socket-handlers/docker-socket-handler.ts @@ -274,6 +274,25 @@ export class DockerSocketHandler extends AgentSocketHandler { } }); + agentSocket.on('restartService', async (stackName: unknown, serviceName: unknown, callback) => { + try { + checkLogin(socket); + + if (typeof stackName !== 'string' || typeof serviceName !== 'string') { + throw new Error('Invalid stackName or serviceName'); + } + + const stack = await Stack.getStack(server, stackName, true); + await stack.restartService(socket, serviceName); + callbackResult({ + ok: true, + msg: `Service ${serviceName} restarted` + }, callback); + } catch (e) { + callbackError(e, callback); + } + }); + // getExternalNetworkList agentSocket.on("getDockerNetworkList", async (callback) => { try { diff --git a/backend/stack.ts b/backend/stack.ts index 8605f02a..bddd0123 100644 --- a/backend/stack.ts +++ b/backend/stack.ts @@ -535,7 +535,7 @@ export class Stack { 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.`); + throw new Error(`Failed to start service ${serviceName}, please check logs for more information.`); } return exitCode; @@ -545,7 +545,17 @@ export class Stack { 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.`); + throw new Error(`Failed to stop service ${serviceName}, please check logs for more information.`); + } + + return exitCode; + } + + async restartService(socket: DockgeSocket, serviceName: string): Promise { + const terminalName = getComposeTerminalName(socket.endpoint, this.name); + const exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", ["compose", "restart", serviceName], this.path); + if (exitCode !== 0) { + throw new Error(`Failed to restart service ${serviceName}, please check logs for more information.`); } return exitCode; diff --git a/frontend/src/components/Container.vue b/frontend/src/components/Container.vue index 0ca135a7..13cf20eb 100644 --- a/frontend/src/components/Container.vue +++ b/frontend/src/components/Container.vue @@ -1,7 +1,7 @@