feat: delete volume

This commit is contained in:
Nicolas Meienberger
2025-08-31 21:49:49 +02:00
parent 37effcb4e3
commit eb2fbe8f75
22 changed files with 282 additions and 316 deletions

View File

@@ -1,7 +1,13 @@
import { Hono } from "hono";
import { validator } from "hono-openapi/arktype";
import { handleServiceError } from "../../utils/errors";
import { createVolumeBody, createVolumeDto, type ListVolumesResponseDto, listVolumesDto } from "./volume.dto";
import {
createVolumeBody,
createVolumeDto,
deleteVolumeDto,
type ListVolumesResponseDto,
listVolumesDto,
} from "./volume.dto";
import { volumeService } from "./volume.service";
export const volumeController = new Hono()
@@ -11,8 +17,8 @@ export const volumeController = new Hono()
const response = {
volumes: volumes.map((volume) => ({
name: volume.name,
mountpoint: volume.path,
createdAt: volume.createdAt,
path: volume.path,
createdAt: volume.createdAt.getTime(),
})),
} satisfies ListVolumesResponseDto;
@@ -29,6 +35,17 @@ export const volumeController = new Hono()
return c.json({ message: "Volume created", volume: res.volume });
})
.delete("/:name", deleteVolumeDto, async (c) => {
const { name } = c.req.param();
const res = await volumeService.deleteVolume(name);
if (res.error) {
const { message, status } = handleServiceError(res.error);
return c.json(message, status);
}
return c.json({ message: "Volume deleted" });
})
.get("/:name", (c) => {
return c.json({ message: `Details of volume ${c.req.param("name")}` });
})

View File

@@ -9,7 +9,7 @@ import { volumeConfigSchema } from "../../db/schema";
export const listVolumesResponse = type({
volumes: type({
name: "string",
mountpoint: "string",
path: "string",
createdAt: "number",
}).array(),
});
@@ -41,9 +41,12 @@ export const createVolumeBody = type({
});
export const createVolumeResponse = type({
name: "string",
mountpoint: "string",
createdAt: "number",
message: "string",
volume: type({
name: "string",
path: "string",
createdAt: "number",
}),
});
export const createVolumeDto = describeRoute({
@@ -62,3 +65,27 @@ export const createVolumeDto = describeRoute({
},
},
});
/**
* Delete a volume
*/
export const deleteVolumeResponse = type({
message: "string",
});
export const deleteVolumeDto = describeRoute({
description: "Delete a volume",
operationId: "deleteVolume",
validateResponse: true,
tags: ["Volumes"],
responses: {
200: {
description: "Volume deleted successfully",
content: {
"application/json": {
schema: resolver(deleteVolumeResponse),
},
},
},
},
});

View File

@@ -39,6 +39,29 @@ const createVolume = async (name: string, backendConfig: BackendConfig) => {
return { volume: val[0], status: 201 };
};
const deleteVolume = async (name: string) => {
try {
const volume = await db.query.volumesTable.findFirst({
where: eq(volumesTable.name, name),
});
if (!volume) {
return { error: new NotFoundError("Volume not found") };
}
const backend = createVolumeBackend(volume);
await backend.unmount();
await db.delete(volumesTable).where(eq(volumesTable.name, name));
return { status: 200 };
} catch (error) {
return {
error: new InternalServerError("Failed to delete volume", {
cause: error,
}),
};
}
};
const mountVolume = async (name: string) => {
try {
const volume = await db.query.volumesTable.findFirst({
@@ -64,4 +87,5 @@ export const volumeService = {
listVolumes,
createVolume,
mountVolume,
deleteVolume,
};