Improve docker swarm status check
This commit is contained in:
parent
8a6343dee7
commit
08f9120326
@ -7,15 +7,21 @@ export default function Status({ service }) {
|
||||
const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`);
|
||||
|
||||
if (error) {
|
||||
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
|
||||
<div
|
||||
className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"
|
||||
title={data.status}
|
||||
>
|
||||
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
if (data && data.status === "running") {
|
||||
if (data.health === "starting") {
|
||||
return (
|
||||
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.health}>
|
||||
<div
|
||||
className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"
|
||||
title={data.health}
|
||||
>
|
||||
<div className="text-[8px] font-bold text-blue-500/80 uppercase">{data.health}</div>
|
||||
</div>
|
||||
);
|
||||
@ -23,22 +29,31 @@ export default function Status({ service }) {
|
||||
|
||||
if (data.health === "unhealthy") {
|
||||
return (
|
||||
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.health}>
|
||||
<div
|
||||
className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"
|
||||
title={data.health}
|
||||
>
|
||||
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.health}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.health || data.status}>
|
||||
<div
|
||||
className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"
|
||||
title={data.health || data.status}
|
||||
>
|
||||
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{data.health || data.status}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (data && (data.status === "not found" || data.status === "exited")) {
|
||||
if (data && (data.status === "not found" || data.status === "exited" || data.status?.startsWith("partial"))) {
|
||||
return (
|
||||
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
|
||||
<div
|
||||
className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"
|
||||
title={data.status}
|
||||
>
|
||||
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.status}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -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();
|
||||
|
||||
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: info.State.Status,
|
||||
health: info.State.Health?.Status,
|
||||
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" },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user