From ae7a77d24736d25a43838c957569c13b33b966f5 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 14 Feb 2023 10:12:19 -0800 Subject: [PATCH] Use replica count for swarm status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Raphaƫl Catarino --- src/components/services/status.jsx | 4 +- src/pages/api/docker/status/[...service].js | 65 ++++++++++++++------- src/widgets/docker/component.jsx | 2 +- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/components/services/status.jsx b/src/components/services/status.jsx index 81d485891..afe161fbf 100644 --- a/src/components/services/status.jsx +++ b/src/components/services/status.jsx @@ -12,7 +12,7 @@ export default function Status({ service }) { } - if (data && data.status === "running") { + if (data && data.status.includes("running")) { if (data.health === "starting") { return (
@@ -36,7 +36,7 @@ export default function Status({ service }) { ); } - if (data && (data.status === "not found" || data.status === "exited")) { + if (data && (data.status === "not found" || data.status === "exited" || data.status?.startsWith("partial"))) { return (
{data.status}
diff --git a/src/pages/api/docker/status/[...service].js b/src/pages/api/docker/status/[...service].js index 4a706c4da..2bcc0a8a6 100644 --- a/src/pages/api/docker/status/[...service].js +++ b/src/pages/api/docker/status/[...service].js @@ -44,42 +44,65 @@ export default async function handler(req, res) { } if (dockerArgs.swarm) { - const tasks = await docker.listTasks({ + const serviceInfo = await docker.getService(containerName).inspect() + .catch(() => undefined); + + if (!serviceInfo) { + return res.status(404).send({ + status: "not found", + }); + } + + const tasks = await docker + .listTasks({ filters: { service: [containerName], - // A service can have several offline containers, we only look for an active one. "desired-state": ["running"], }, }) .catch(() => []); - // TODO: Show the result for all replicas/containers? - // We can only get stats for 'local' containers so try to find one - const localContainerIDs = containers.map(c => c.Id); - const task = tasks.find(t => localContainerIDs.includes(t.Status?.ContainerStatus?.ContainerID)) ?? tasks.at(0); - const taskContainerId = task?.Status?.ContainerStatus?.ContainerID; - - if (taskContainerId) { - try { - const container = docker.getContainer(taskContainerId); - const info = await container.inspect(); - + if (serviceInfo.Spec.Mode?.Replicated) { + // Replicated service, check n replicas + const replicas = parseInt(serviceInfo.Spec.Mode?.Replicated?.Replicas, 10); + if (tasks.length === replicas) { return res.status(200).json({ - status: info.State.Status, - health: info.State.Health?.Status, + status: `running ${tasks.length}/${replicas}`, }); - } catch (e) { - if (task) { + } + if (tasks.length > 0) { + return res.status(200).json({ + status: `partial ${tasks.length}/${replicas}`, + }); + } + } else { + // Global service, prefer 'local' containers + const localContainerIDs = containers.map(c => c.Id); + const task = tasks.find(t => localContainerIDs.includes(t.Status?.ContainerStatus?.ContainerID)) ?? tasks.at(0); + const taskContainerId = task?.Status?.ContainerStatus?.ContainerID; + + if (taskContainerId) { + try { + const container = docker.getContainer(taskContainerId); + const info = await container.inspect(); + return res.status(200).json({ - status: task.Status.State - }) + status: info.State.Status, + health: info.State.Health?.Status, + }); + } catch (e) { + if (task) { + return res.status(200).json({ + status: task.Status.State + }) + } } } } } - return res.status(200).send({ - error: "not found", + return res.status(404).send({ + status: "not found", }); } catch (e) { logger.error(e); diff --git a/src/widgets/docker/component.jsx b/src/widgets/docker/component.jsx index 9d3affd3d..7ef5e6cec 100644 --- a/src/widgets/docker/component.jsx +++ b/src/widgets/docker/component.jsx @@ -22,7 +22,7 @@ export default function Component({ service }) { return ; } - if (statusData && statusData.status !== "running") { + if (statusData && !(statusData.status.includes("running") || statusData.status.includes("partial"))) { return (