diff --git a/backend/agent-socket-handlers/docker-socket-handler.ts b/backend/agent-socket-handlers/docker-socket-handler.ts index 81746019..f81ee47e 100644 --- a/backend/agent-socket-handlers/docker-socket-handler.ts +++ b/backend/agent-socket-handlers/docker-socket-handler.ts @@ -147,6 +147,8 @@ export class DockerSocketHandler extends AgentSocketHandler { msgi18n: true, }, callback); server.sendStackList(); + + stack.leaveCombinedTerminal(socket); } catch (e) { callbackError(e, callback); } @@ -238,6 +240,68 @@ 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); + } + }); + + 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 fbce5002..bddd0123 100644 --- a/backend/stack.ts +++ b/backend/stack.ts @@ -530,4 +530,34 @@ 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 logs 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 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 0bedae5e..fca36afc 100644 --- a/frontend/src/components/Container.vue +++ b/frontend/src/components/Container.vue @@ -1,7 +1,7 @@