Skip to content

Commit 832e124

Browse files
committed
btrfs: cloning with subvolumes (fix permission issues)
1 parent 46ad996 commit 832e124

File tree

4 files changed

+28
-12
lines changed

4 files changed

+28
-12
lines changed

src/packages/file-server/btrfs/subvolume-snapshots.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class SubvolumeSnapshots {
2727
return;
2828
}
2929
await this.subvolume.fs.mkdir(SNAPSHOTS);
30-
await this.subvolume.fs.chmod(SNAPSHOTS, "0555");
30+
await this.subvolume.fs.chmod(SNAPSHOTS, "0550");
3131
};
3232

3333
create = async (name?: string) => {

src/packages/file-server/btrfs/subvolumes.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { SNAPSHOTS } from "./subvolume-snapshots";
55
import { exists } from "@cocalc/backend/misc/async-utils-node";
66
import { join, normalize } from "path";
77
import { btrfs } from "./util";
8-
import { rename, readdir, rm, stat } from "fs/promises";
8+
import { chmod, rename, readdir, rm, stat } from "fs/promises";
99
import { executeCode } from "@cocalc/backend/execute-code";
1010

1111
const RESERVED = new Set(["bup", SNAPSHOTS]);
@@ -48,14 +48,11 @@ export class Subvolumes {
4848
);
4949
const snapdir = join(this.filesystem.opts.mount, dest, SNAPSHOTS);
5050
if (await exists(snapdir)) {
51-
const snapshots = await readdir(snapdir);
52-
const f = async (x) => {
53-
await rm(join(this.filesystem.opts.mount, dest, SNAPSHOTS, x), {
54-
recursive: true,
55-
force: true,
56-
});
57-
};
58-
await Promise.all(snapshots.map(f));
51+
await chmod(snapdir, "0700");
52+
await rm(snapdir, {
53+
recursive: true,
54+
force: true,
55+
});
5956
}
6057
const src = await this.get(source);
6158
const dst = await this.get(dest);

src/packages/file-server/btrfs/test/filesystem.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,23 @@ describe("operations with subvolumes", () => {
8383
});
8484
});
8585

86+
describe("clone of a subvolume with snapshots should have no snapshots", () => {
87+
it("creates a subvolume, a file, and a snapshot", async () => {
88+
const x = await fs.subvolumes.get("my-volume");
89+
await x.fs.writeFile("abc.txt", "hi");
90+
await x.snapshots.create("my-snap");
91+
});
92+
93+
it("clones my-volume", async () => {
94+
await fs.subvolumes.clone("my-volume", "my-clone");
95+
});
96+
97+
it("clone has no snapshots", async () => {
98+
const clone = await fs.subvolumes.get("my-clone");
99+
expect(await clone.fs.readFile("abc.txt", "utf8")).toEqual("hi");
100+
expect(await clone.snapshots.ls()).toEqual([]);
101+
await clone.snapshots.create("my-clone-snap");
102+
});
103+
});
104+
86105
afterAll(after);

src/packages/file-server/btrfs/test/subvolume.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,11 @@ describe("the filesystem operations", () => {
125125

126126
it("make a file readonly, then change it back", async () => {
127127
await vol.fs.writeFile("c.txt", "hi");
128-
await vol.fs.chmod("c.txt", "444");
128+
await vol.fs.chmod("c.txt", "440");
129129
expect(async () => {
130130
await vol.fs.appendFile("c.txt", " there");
131131
}).rejects.toThrow("EACCES");
132-
await vol.fs.chmod("c.txt", "666");
132+
await vol.fs.chmod("c.txt", "660");
133133
await vol.fs.appendFile("c.txt", " there");
134134
});
135135

0 commit comments

Comments
 (0)