feat(server): test mount endpoint

This commit is contained in:
Nicolas Meienberger
2025-09-02 22:52:44 +02:00
parent de0ae08008
commit 0c0a3b8581
9 changed files with 184 additions and 4 deletions

View File

@@ -7,6 +7,8 @@ import {
deleteVolumeDto,
type ListVolumesResponseDto,
listVolumesDto,
testConnectionBody,
testConnectionDto,
} from "./volume.dto";
import { volumeService } from "./volume.service";
@@ -35,6 +37,12 @@ export const volumeController = new Hono()
return c.json({ message: "Volume created", volume: res.volume });
})
.post("/test-connection", testConnectionDto, validator("json", testConnectionBody), async (c) => {
const body = c.req.valid("json");
const result = await volumeService.testConnection(body.config);
return c.json(result, 200);
})
.delete("/:name", deleteVolumeDto, async (c) => {
const { name } = c.req.param();
const res = await volumeService.deleteVolume(name);

View File

@@ -89,3 +89,32 @@ export const deleteVolumeDto = describeRoute({
},
},
});
/**
* Test connection
*/
export const testConnectionBody = type({
config: volumeConfigSchema,
});
export const testConnectionResponse = type({
success: "boolean",
message: "string",
});
export const testConnectionDto = describeRoute({
description: "Test connection to backend",
operationId: "testConnection",
validateResponse: true,
tags: ["Volumes"],
responses: {
200: {
description: "Connection test result",
content: {
"application/json": {
schema: resolver(testConnectionResponse),
},
},
},
},
});

View File

@@ -1,3 +1,5 @@
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import type { BackendConfig } from "@ironmount/schemas";
import { eq } from "drizzle-orm";
@@ -33,7 +35,7 @@ const createVolume = async (name: string, backendConfig: BackendConfig) => {
name: slug,
config: backendConfig,
path: path.join(volumePathHost, slug),
type: "nfs",
type: backendConfig.backend,
})
.returning();
@@ -84,9 +86,53 @@ const mountVolume = async (name: string) => {
}
};
const testConnection = async (backendConfig: BackendConfig) => {
let tempDir: string | null = null;
try {
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "ironmount-test-"));
const mockVolume = {
id: 0,
name: "test-connection",
path: tempDir,
config: backendConfig,
createdAt: new Date(),
updatedAt: new Date(),
type: backendConfig.backend,
};
const backend = createVolumeBackend(mockVolume);
await backend.mount();
await backend.unmount();
return {
success: true,
message: "Connection successful",
};
} catch (error) {
return {
success: false,
message: error instanceof Error ? error.message : "Connection failed",
};
} finally {
if (tempDir) {
try {
await fs.access(tempDir);
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);
}
}
}
};
export const volumeService = {
listVolumes,
createVolume,
mountVolume,
deleteVolume,
testConnection,
};