Merge pull request #660 from vinaydawani/features/basic-docker-swarm

Support for docker swarm services
This commit is contained in:
shamoon 2022-12-16 21:49:37 -08:00 committed by GitHub
commit 7ca7a9cc58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 20 deletions

View File

@ -14,7 +14,8 @@ export default async function handler(req, res) {
} }
try { try {
const docker = new Docker(getDockerArguments(containerServer)); const dockerArgs = getDockerArguments(containerServer);
const docker = new Docker(dockerArgs.conn);
const containers = await docker.listContainers({ const containers = await docker.listContainers({
all: true, all: true,
}); });
@ -31,18 +32,44 @@ export default async function handler(req, res) {
const containerNames = containers.map((container) => container.Names[0].replace(/^\//, "")); const containerNames = containers.map((container) => container.Names[0].replace(/^\//, ""));
const containerExists = containerNames.includes(containerName); const containerExists = containerNames.includes(containerName);
if (!containerExists) { if (containerExists) {
res.status(200).send({ const container = docker.getContainer(containerName);
error: "not found", const stats = await container.stats({ stream: false });
res.status(200).json({
stats,
}); });
return; return;
} }
const container = docker.getContainer(containerName); // Try with a service deployed in Docker Swarm, if enabled
const stats = await container.stats({ stream: false }); if (dockerArgs.swarm) {
const tasks = await docker.listTasks({
filters: {
service: [containerName],
// A service can have several offline containers, so we only look for an active one.
"desired-state": ["running"],
},
})
.catch(() => []);
res.status(200).json({ // For now we are only interested in the first one (in case replicas > 1).
stats, // TODO: Show the result for all replicas/containers?
const taskContainerId = tasks.at(0)?.Status?.ContainerStatus?.ContainerID;
if (taskContainerId) {
const container = docker.getContainer(taskContainerId);
const stats = await container.stats({ stream: false });
res.status(200).json({
stats,
});
return;
}
}
res.status(200).send({
error: "not found",
}); });
} catch { } catch {
res.status(500).send({ res.status(500).send({

View File

@ -13,7 +13,8 @@ export default async function handler(req, res) {
} }
try { try {
const docker = new Docker(getDockerArguments(containerServer)); const dockerArgs = getDockerArguments(containerServer);
const docker = new Docker(dockerArgs.conn);
const containers = await docker.listContainers({ const containers = await docker.listContainers({
all: true, all: true,
}); });
@ -29,18 +30,43 @@ export default async function handler(req, res) {
const containerNames = containers.map((container) => container.Names[0].replace(/^\//, "")); const containerNames = containers.map((container) => container.Names[0].replace(/^\//, ""));
const containerExists = containerNames.includes(containerName); const containerExists = containerNames.includes(containerName);
if (!containerExists) { if (containerExists) {
return res.status(200).send({ const container = docker.getContainer(containerName);
error: "not found", const info = await container.inspect();
return res.status(200).json({
status: info.State.Status,
health: info.State.Health?.Status,
}); });
} }
const container = docker.getContainer(containerName); if (dockerArgs.swarm) {
const info = await container.inspect(); 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(() => []);
return res.status(200).json({ // For now we are only interested in the first one (in case replicas > 1).
status: info.State.Status, // TODO: Show the result for all replicas/containers?
health: info.State.Health?.Status 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,
});
}
}
return res.status(200).send({
error: "not found",
}); });
} catch { } catch {
return res.status(500).send({ return res.status(500).send({

View File

@ -22,11 +22,14 @@ export default function getDockerArguments(server) {
if (servers[server]) { if (servers[server]) {
if (servers[server].socket) { if (servers[server].socket) {
return { socketPath: servers[server].socket }; return { conn: { socketPath: servers[server].socket }, swarm: !!servers[server].swarm };
} }
if (servers[server].host) { if (servers[server].host) {
return { host: servers[server].host, port: servers[server].port || null }; return {
conn: { host: servers[server].host, port: servers[server].port || null },
swarm: !!servers[server].swarm,
};
} }
return servers[server]; return servers[server];

View File

@ -44,7 +44,7 @@ export async function servicesFromDocker() {
const serviceServers = await Promise.all( const serviceServers = await Promise.all(
Object.keys(servers).map(async (serverName) => { Object.keys(servers).map(async (serverName) => {
const docker = new Docker(getDockerArguments(serverName)); const docker = new Docker(getDockerArguments(serverName).conn);
const containers = await docker.listContainers({ const containers = await docker.listContainers({
all: true, all: true,
}); });