From 08f9120326b1c6140fa90cfc4f61f79dea7fff75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Catarino?= Date: Tue, 14 Feb 2023 13:54:52 +0100 Subject: [PATCH] Improve docker swarm status check --- src/components/services/status.jsx | 29 +++++++++---- src/pages/api/docker/status/[...service].js | 45 +++++++++++++-------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/components/services/status.jsx b/src/components/services/status.jsx index 81d48589..4aa0a441 100644 --- a/src/components/services/status.jsx +++ b/src/components/services/status.jsx @@ -7,15 +7,21 @@ export default function Status({ service }) { const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`); if (error) { -
+
{t("docker.error")}
-
+
; } if (data && data.status === "running") { if (data.health === "starting") { return ( -
+
{data.health}
); @@ -23,22 +29,31 @@ export default function Status({ service }) { if (data.health === "unhealthy") { return ( -
+
{data.health}
); } return ( -
+
{data.health || data.status}
); } - 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 f232eb98..c33061a8 100644 --- a/src/pages/api/docker/status/[...service].js +++ b/src/pages/api/docker/status/[...service].js @@ -44,37 +44,48 @@ 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(() => []); - // For now we are only interested in the first one (in case replicas > 1). - // TODO: Show the result for all replicas/containers? - const taskContainerId = tasks.at(0)?.Status?.ContainerStatus?.ContainerID; - - if (taskContainerId) { - const container = docker.getContainer(taskContainerId); - const info = await container.inspect(); - - return res.status(200).json({ - status: info.State.Status, - health: info.State.Health?.Status, - }); + const replicas = serviceInfo.Spec.Mode?.Global + ? (await docker.listNodes()).length + : serviceInfo.Spec.Mode?.Replicated?.Replicas; + if (replicas) { + if (tasks.length === replicas) { + return res.status(200).json({ + status: `running`, + }); + } + if (tasks.length > 0) { + return res.status(200).json({ + status: `partial ${tasks.length}/${replicas}`, + }); + } } } - return res.status(200).send({ - error: "not found", + return res.status(404).send({ + status: "not found", }); } catch (e) { logger.error(e); return res.status(500).send({ - error: {message: e?.message ?? "Unknown error"}, + error: { message: e?.message ?? "Unknown error" }, }); } }