mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
feat: mount / unmount
This commit is contained in:
@@ -13,8 +13,11 @@ import {
|
||||
updateVolumeBody,
|
||||
updateVolumeDto,
|
||||
type VolumeDto,
|
||||
mountVolumeDto,
|
||||
unmountVolumeDto,
|
||||
} from "./volume.dto";
|
||||
import { volumeService } from "./volume.service";
|
||||
import { logger } from "../../utils/logger";
|
||||
|
||||
export const volumeController = new Hono()
|
||||
.get("/", listVolumesDto, async (c) => {
|
||||
@@ -100,4 +103,26 @@ export const volumeController = new Hono()
|
||||
};
|
||||
|
||||
return c.json(response, 200);
|
||||
})
|
||||
.post("/:name/mount", mountVolumeDto, async (c) => {
|
||||
const { name } = c.req.param();
|
||||
const res = await volumeService.mountVolume(name);
|
||||
|
||||
if (res.error) {
|
||||
const { message, status } = handleServiceError(res.error);
|
||||
return c.json(message, status);
|
||||
}
|
||||
|
||||
return c.json({ message: "Volume mounted successfully" }, 200);
|
||||
})
|
||||
.post("/:name/unmount", unmountVolumeDto, async (c) => {
|
||||
const { name } = c.req.param();
|
||||
const res = await volumeService.unmountVolume(name);
|
||||
|
||||
if (res.error) {
|
||||
const { message, status } = handleServiceError(res.error);
|
||||
return c.json(message, status);
|
||||
}
|
||||
|
||||
return c.json({ message: "Volume unmounted successfully" }, 200);
|
||||
});
|
||||
|
||||
@@ -190,3 +190,57 @@ export const testConnectionDto = describeRoute({
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Mount volume
|
||||
*/
|
||||
export const mountVolumeResponse = type({
|
||||
message: "string",
|
||||
});
|
||||
|
||||
export const mountVolumeDto = describeRoute({
|
||||
description: "Mount a volume",
|
||||
operationId: "mountVolume",
|
||||
validateResponse: true,
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume mounted successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(mountVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "Volume not found",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Unmount volume
|
||||
*/
|
||||
export const unmountVolumeResponse = type({
|
||||
message: "string",
|
||||
});
|
||||
|
||||
export const unmountVolumeDto = describeRoute({
|
||||
description: "Unmount a volume",
|
||||
operationId: "unmountVolume",
|
||||
validateResponse: true,
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume unmounted successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(unmountVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "Volume not found",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ import { config } from "../../core/config";
|
||||
import { db } from "../../db/db";
|
||||
import { volumesTable } from "../../db/schema";
|
||||
import { createVolumeBackend } from "../backends/backend";
|
||||
import { logger } from "../../utils/logger";
|
||||
|
||||
const listVolumes = async () => {
|
||||
const volumes = await db.query.volumesTable.findMany({});
|
||||
@@ -76,7 +77,18 @@ const mountVolume = async (name: string) => {
|
||||
}
|
||||
|
||||
const backend = createVolumeBackend(volume);
|
||||
await backend.unmount().catch((_) => {
|
||||
// Ignore unmount errors
|
||||
});
|
||||
|
||||
await backend.mount();
|
||||
|
||||
await db
|
||||
.update(volumesTable)
|
||||
.set({ status: "mounted", lastHealthCheck: new Date() })
|
||||
.where(eq(volumesTable.name, name));
|
||||
|
||||
return { status: 200 };
|
||||
} catch (error) {
|
||||
return {
|
||||
error: new InternalServerError("Failed to mount volume", {
|
||||
@@ -86,6 +98,34 @@ const mountVolume = async (name: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const unmountVolume = 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
|
||||
.update(volumesTable)
|
||||
.set({ status: "unmounted", lastHealthCheck: new Date() })
|
||||
.where(eq(volumesTable.name, name));
|
||||
|
||||
return { status: 200 };
|
||||
} catch (error) {
|
||||
return {
|
||||
error: new InternalServerError("Failed to unmount volume", {
|
||||
cause: error,
|
||||
}),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const getVolume = async (name: string) => {
|
||||
const volume = await db.query.volumesTable.findFirst({
|
||||
where: eq(volumesTable.name, name),
|
||||
@@ -202,7 +242,7 @@ const testConnection = async (backendConfig: BackendConfig) => {
|
||||
await fs.rm(tempDir, { recursive: true, force: true });
|
||||
} catch (cleanupError) {
|
||||
// Ignore cleanup errors if directory doesn't exist or can't be removed
|
||||
console.warn("Failed to cleanup temp directory:", cleanupError);
|
||||
logger.warn("Failed to cleanup temp directory:", cleanupError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,4 +258,5 @@ export const volumeService = {
|
||||
testConnection,
|
||||
updateVolumeStatus,
|
||||
getVolumeStatus,
|
||||
unmountVolume,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user