feat: basic image/container apis

This commit is contained in:
2025-01-06 21:34:48 +01:00
parent b918c65cf7
commit 1bd06e1a4c
11 changed files with 822 additions and 0 deletions

View File

@ -0,0 +1,9 @@
import type { Container } from "#src/types/Container.ts";
import { inspectContainer } from "#src/utils/containers.ts";
import type { FastifyInstance, FastifyRequest } from "fastify";
export default (fastify: FastifyInstance) => {
fastify.get("/", (req: FastifyRequest<{ Params: Container }>) => {
return inspectContainer(req.params.name);
});
};

View File

@ -0,0 +1,21 @@
import createContainerSchema from "#src/schemas/createContainerSchema.ts";
import type { CreateContainerBody } from "#src/types/Container.ts";
import { createContainer, getContainers } from "#src/utils/containers.ts";
import type { FastifyInstance, FastifyRequest } from "fastify";
export default (fastify: FastifyInstance) => {
fastify.get("/", () => {
return getContainers();
});
fastify.post(
"/",
{ schema: createContainerSchema },
async (req: FastifyRequest<{ Body: CreateContainerBody }>) => {
const container = await createContainer({ image: req.body.image });
container.start();
return container;
},
);
};

View File

@ -0,0 +1,9 @@
import type { Image } from "#src/types.ts";
import { inspectImage } from "#src/utils/images.ts";
import type { FastifyInstance, FastifyRequest } from "fastify";
export default (fastify: FastifyInstance) => {
fastify.get("/", (req: FastifyRequest<{ Params: Image }>) => {
return inspectImage(req.params.name);
});
};

View File

@ -0,0 +1,8 @@
import { getImages } from "#src/utils/images.ts";
import type { FastifyInstance, FastifyRequest } from "fastify";
export default (fastify: FastifyInstance) => {
fastify.get("/", () => {
return getImages();
});
};

View File

@ -0,0 +1,13 @@
import type { FastifySchema } from "fastify";
const createContainerSchema: FastifySchema = {
body: {
type: "object",
properties: {
image: { type: "string", minLength: 1 },
},
required: ["image"],
},
};
export default createContainerSchema;

8
src/types/Container.ts Normal file
View File

@ -0,0 +1,8 @@
export interface Container {
name: string;
image: string;
}
export interface CreateContainerBody {
image: string;
}

3
src/types/Image.ts Normal file
View File

@ -0,0 +1,3 @@
export interface Image {
name: string;
}

29
src/utils/containers.ts Normal file
View File

@ -0,0 +1,29 @@
import type { CreateContainerBody } from "#src/types/Container.ts";
import Dockerode from "dockerode";
const dockerode = new Dockerode();
export const getContainers = () => {
const containers = dockerode.listContainers({
filters: { label: ["code-containers.image"] },
all: true,
});
return containers;
};
export const inspectContainer = (id: string) => {
const container = dockerode.getContainer(id);
return container.inspect();
};
export const createContainer = ({ image }: CreateContainerBody) => {
const container = dockerode.createContainer({
Image: `code-containers/${image}`,
Labels: {
"code-containers.image": image,
},
});
return container;
};

16
src/utils/images.ts Normal file
View File

@ -0,0 +1,16 @@
import Dockerode from "dockerode";
const dockerode = new Dockerode();
export const getImages = () => {
const images = dockerode.listImages({
filters: { reference: ["code-containers/*"] },
});
return images;
};
export const inspectImage = async (name: string) => {
const image = dockerode.getImage(`code-containers/${name}`);
return image.inspect();
};