fix(docker-volume): clarify comment and add remote tests for read/write

This commit is contained in:
detail-app[bot]
2026-09-04 03:08:11 +00:00
parent ac309104fd
commit 9595a936bb
2 changed files with 34 additions and 4 deletions
@@ -126,4 +126,34 @@ describe("docker-volume service commands", () => {
expect(hasToken(delCommand, READWRITE)).toBe(true);
expect(delCommand).not.toContain(" -v ");
});
it("readVolumeFile uses execAsyncRemote and mounts read-only on remote calls", async () => {
await readVolumeFile("myvol", "/file.txt", "srv-3");
expect(mocks.execAsync).not.toHaveBeenCalled();
expect(mocks.execAsyncRemote).toHaveBeenCalledOnce();
const [serverId, command] = mocks.execAsyncRemote.mock.calls[0] as [
string,
string,
];
expect(serverId).toBe("srv-3");
expect(hasToken(command, READONLY)).toBe(true);
expect(command).not.toContain(" -v ");
expect(command).toContain("busybox cat");
});
it("writeVolumeFile uses execAsyncRemote and mounts read-write on remote calls", async () => {
await writeVolumeFile("myvol", "/file.txt", "hello", "srv-4");
expect(mocks.execAsync).not.toHaveBeenCalled();
expect(mocks.execAsyncRemote).toHaveBeenCalledOnce();
const [serverId, command] = mocks.execAsyncRemote.mock.calls[0] as [
string,
string,
];
expect(serverId).toBe("srv-4");
expect(hasToken(command, READWRITE)).toBe(true);
expect(hasToken(command, READONLY)).toBe(false);
expect(command).not.toContain("readonly");
expect(command).not.toContain(" -v ");
expect(command).toContain("busybox sh -c");
});
});
@@ -14,10 +14,10 @@ import { z } from "zod";
import { audit } from "@/server/api/utils/audit";
import { createTRPCRouter, withPermission } from "../trpc";
// Docker only treats a `-v`/`--mount` source as a *named volume* when it starts
// with an alphanumeric character; a leading "." or "-" makes the CLI resolve it
// as a (client-relative) bind-mount path instead. Forbid those leading
// characters so a crafted volumeName can never escape into bind-mount mode.
// Docker's `-v` syntax interprets a source starting with "." or "-" as a
// client-relative bind-mount path. Forbid those leading characters so a
// crafted volumeName cannot escape into bind-mount mode. The service also uses
// `--mount type=volume` so Docker rejects invalid volume names as a second layer.
export const volumeNameRegex = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/;
const volumePathSchema = z