mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
refactor: docker volume prefix
This commit is contained in:
@@ -16,17 +16,17 @@ export const DockerTabContent = ({ volume }: Props) => {
|
|||||||
services: {
|
services: {
|
||||||
nginx: {
|
nginx: {
|
||||||
image: "nginx:latest",
|
image: "nginx:latest",
|
||||||
volumes: [`${volume.name}:/path/in/container`],
|
volumes: [`im-${volume.name}:/path/in/container`],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
volumes: {
|
volumes: {
|
||||||
[volume.name]: {
|
[`im-${volume.name}`]: {
|
||||||
external: true,
|
external: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const dockerRunCommand = `docker run -v ${volume.name}:/path/in/container nginx:latest`;
|
const dockerRunCommand = `docker run -v im-${volume.name}:/path/in/container nginx:latest`;
|
||||||
|
|
||||||
const containersQuery = getContainersUsingVolumeOptions({ path: { name: volume.name } });
|
const containersQuery = getContainersUsingVolumeOptions({ path: { name: volume.name } });
|
||||||
const { data: containersData, isLoading, error } = useQuery(containersQuery);
|
const { data: containersData, isLoading, error } = useQuery(containersQuery);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ export default function DetailsPage({ loaderData }: Route.ComponentProps) {
|
|||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
...getVolumeOptions({ path: { name: name ?? "" } }),
|
...getVolumeOptions({ path: { name: name ?? "" } }),
|
||||||
initialData: loaderData,
|
initialData: loaderData,
|
||||||
|
refetchInterval: 10000,
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const deleteVol = useMutation({
|
const deleteVol = useMutation({
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ export default function Home({ loaderData }: Route.ComponentProps) {
|
|||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
...listVolumesOptions(),
|
...listVolumesOptions(),
|
||||||
initialData: loaderData,
|
initialData: loaderData,
|
||||||
|
refetchInterval: 10000,
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const filteredVolumes =
|
const filteredVolumes =
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ export const scalarDescriptor = Scalar({
|
|||||||
const driver = new Hono().use(honoLogger()).route("/", driverController);
|
const driver = new Hono().use(honoLogger()).route("/", driverController);
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
.use(honoLogger())
|
.use(honoLogger())
|
||||||
.get("*", serveStatic({ root: "./assets/frontend" }))
|
.get("/healthcheck", (c) => c.json({ status: "ok" }))
|
||||||
.get("healthcheck", (c) => c.json({ status: "ok" }))
|
.route("/api/v1/volumes", volumeController)
|
||||||
.basePath("/api/v1")
|
.get("/assets/*", serveStatic({ root: "./assets/frontend" }))
|
||||||
.route("/volumes", volumeController);
|
.get("*", serveStatic({ path: "./assets/frontend/index.html" }));
|
||||||
|
|
||||||
app.get("/openapi.json", generalDescriptor(app));
|
app.get("/openapi.json", generalDescriptor(app));
|
||||||
app.get("/docs", scalarDescriptor);
|
app.get("/docs", scalarDescriptor);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
|
import { VOLUME_MOUNT_BASE } from "~/core/constants";
|
||||||
import { volumeService } from "../volumes/volume.service";
|
import { volumeService } from "../volumes/volume.service";
|
||||||
import { config } from "../../core/config";
|
|
||||||
|
|
||||||
export const driverController = new Hono()
|
export const driverController = new Hono()
|
||||||
.post("/VolumeDriver.Capabilities", (c) => {
|
.post("/VolumeDriver.Capabilities", (c) => {
|
||||||
@@ -30,8 +30,9 @@ export const driverController = new Hono()
|
|||||||
return c.json({ Err: "Volume name is required" }, 400);
|
return c.json({ Err: "Volume name is required" }, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
const volumeRoot = config.volumeRootHost;
|
const volumeName = body.Name.replace(/^im-/, "");
|
||||||
const mountpoint = `${volumeRoot}/${body.Name}/_data`;
|
|
||||||
|
const mountpoint = `${VOLUME_MOUNT_BASE}/${volumeName}/_data`;
|
||||||
|
|
||||||
return c.json({
|
return c.json({
|
||||||
Mountpoint: mountpoint,
|
Mountpoint: mountpoint,
|
||||||
@@ -54,13 +55,12 @@ export const driverController = new Hono()
|
|||||||
return c.json({ Err: "Volume name is required" }, 400);
|
return c.json({ Err: "Volume name is required" }, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
const volumeRoot = config.volumeRootHost;
|
const { volume } = await volumeService.getVolume(body.Name.replace(/^im-/, ""));
|
||||||
const { volume } = await volumeService.getVolume(body.Name);
|
|
||||||
|
|
||||||
return c.json({
|
return c.json({
|
||||||
Volume: {
|
Volume: {
|
||||||
Name: volume.name,
|
Name: `im-${volume.name}`,
|
||||||
Mountpoint: `${volumeRoot}/${volume.name}/_data`,
|
Mountpoint: `${VOLUME_MOUNT_BASE}/${volume.name}/_data`,
|
||||||
Status: {},
|
Status: {},
|
||||||
},
|
},
|
||||||
Err: "",
|
Err: "",
|
||||||
@@ -68,11 +68,10 @@ export const driverController = new Hono()
|
|||||||
})
|
})
|
||||||
.post("/VolumeDriver.List", async (c) => {
|
.post("/VolumeDriver.List", async (c) => {
|
||||||
const volumes = await volumeService.listVolumes();
|
const volumes = await volumeService.listVolumes();
|
||||||
const volumeRoot = config.volumeRootHost;
|
|
||||||
|
|
||||||
const res = volumes.map((volume) => ({
|
const res = volumes.map((volume) => ({
|
||||||
Name: volume.name,
|
Name: `im-${volume.name}`,
|
||||||
Mountpoint: `${volumeRoot}/${volume.name}/_data`,
|
Mountpoint: `${VOLUME_MOUNT_BASE}/${volume.name}/_data`,
|
||||||
Status: {},
|
Status: {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import Docker from "dockerode";
|
|||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { ConflictError, InternalServerError, NotFoundError } from "http-errors-enhanced";
|
import { ConflictError, InternalServerError, NotFoundError } from "http-errors-enhanced";
|
||||||
import slugify from "slugify";
|
import slugify from "slugify";
|
||||||
import { config } from "../../core/config";
|
|
||||||
import { VOLUME_MOUNT_BASE } from "../../core/constants";
|
import { VOLUME_MOUNT_BASE } from "../../core/constants";
|
||||||
import { db } from "../../db/db";
|
import { db } from "../../db/db";
|
||||||
import { volumesTable } from "../../db/schema";
|
import { volumesTable } from "../../db/schema";
|
||||||
@@ -32,14 +31,14 @@ const createVolume = async (name: string, backendConfig: BackendConfig) => {
|
|||||||
throw new ConflictError("Volume already exists");
|
throw new ConflictError("Volume already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
const volumePathHost = path.join(config.volumeRootHost);
|
const volumePathHost = path.join(VOLUME_MOUNT_BASE);
|
||||||
|
|
||||||
const val = await db
|
const val = await db
|
||||||
.insert(volumesTable)
|
.insert(volumesTable)
|
||||||
.values({
|
.values({
|
||||||
name: slug,
|
name: slug,
|
||||||
config: backendConfig,
|
config: backendConfig,
|
||||||
path: path.join(volumePathHost, slug),
|
path: path.join(volumePathHost, slug, "_data"),
|
||||||
type: backendConfig.backend,
|
type: backendConfig.backend,
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
@@ -210,7 +209,7 @@ const getContainersUsingVolume = async (name: string) => {
|
|||||||
const container = docker.getContainer(info.Id);
|
const container = docker.getContainer(info.Id);
|
||||||
const inspect = await container.inspect();
|
const inspect = await container.inspect();
|
||||||
const mounts = inspect.Mounts || [];
|
const mounts = inspect.Mounts || [];
|
||||||
const usesVolume = mounts.some((mount) => mount.Type === "volume" && mount.Name === name);
|
const usesVolume = mounts.some((mount) => mount.Type === "volume" && mount.Name === `im-${volume.name}`);
|
||||||
if (usesVolume) {
|
if (usesVolume) {
|
||||||
usingContainers.push({
|
usingContainers.push({
|
||||||
id: inspect.Id,
|
id: inspect.Id,
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
"module": "preserve",
|
"module": "preserve",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"lib": ["es2022"]
|
"lib": ["es2022"],
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./src/*"]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
"tsc": "turbo run tsc",
|
"tsc": "turbo run tsc",
|
||||||
"build": "turbo build",
|
"build": "turbo build",
|
||||||
"gen:api-client": "openapi-ts",
|
"gen:api-client": "openapi-ts",
|
||||||
"start:dev": "docker rm ironmount && docker compose up --build ironmount-dev",
|
"start:dev": "docker compose down && docker compose up --build ironmount-dev",
|
||||||
"start:prod": "docker rm ironmount && docker compose up --build ironmount-prod"
|
"start:prod": "docker compose down && docker compose up --build ironmount-prod"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*",
|
||||||
|
|||||||
Reference in New Issue
Block a user