1import ./make-test-python.nix ({ pkgs, ... }: let
2 inherit (import ./ssh-keys.nix pkgs)
3 snakeOilPrivateKey snakeOilPublicKey;
4
5 commonConfig = { pkgs, ... }: {
6 virtualisation.emptyDiskImages = [ 2048 ];
7 boot.supportedFilesystems = [ "zfs" ];
8 environment.systemPackages = [ pkgs.parted ];
9 };
10in {
11 name = "sanoid";
12 meta = with pkgs.lib.maintainers; {
13 maintainers = [ lopsided98 ];
14 };
15
16 nodes = {
17 source = { ... }: {
18 imports = [ commonConfig ];
19 networking.hostId = "daa82e91";
20
21 programs.ssh.extraConfig = ''
22 UserKnownHostsFile=/dev/null
23 StrictHostKeyChecking=no
24 '';
25
26 services.sanoid = {
27 enable = true;
28 templates.test = {
29 hourly = 12;
30 daily = 1;
31 monthly = 1;
32 yearly = 1;
33
34 autosnap = true;
35 };
36 datasets."pool/sanoid".use_template = [ "test" ];
37 extraArgs = [ "--verbose" ];
38 };
39
40 services.syncoid = {
41 enable = true;
42 sshKey = "/var/lib/syncoid/id_ecdsa";
43 commands = {
44 # Sync snapshot taken by sanoid
45 "pool/sanoid" = {
46 target = "root@target:pool/sanoid";
47 extraArgs = [ "--no-sync-snap" "--create-bookmark" ];
48 };
49 # Take snapshot and sync
50 "pool/syncoid".target = "root@target:pool/syncoid";
51 };
52 };
53 };
54 target = { ... }: {
55 imports = [ commonConfig ];
56 networking.hostId = "dcf39d36";
57
58 services.openssh.enable = true;
59 users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
60 };
61 };
62
63 testScript = ''
64 source.succeed(
65 "mkdir /mnt",
66 "parted --script /dev/vdb -- mklabel msdos mkpart primary 1024M -1s",
67 "udevadm settle",
68 "zpool create pool -R /mnt /dev/vdb1",
69 "zfs create pool/sanoid",
70 "zfs create pool/syncoid",
71 "udevadm settle",
72 )
73 target.succeed(
74 "mkdir /mnt",
75 "parted --script /dev/vdb -- mklabel msdos mkpart primary 1024M -1s",
76 "udevadm settle",
77 "zpool create pool -R /mnt /dev/vdb1",
78 "udevadm settle",
79 )
80
81 source.succeed(
82 "mkdir -m 700 -p /var/lib/syncoid",
83 "cat '${snakeOilPrivateKey}' > /var/lib/syncoid/id_ecdsa",
84 "chmod 600 /var/lib/syncoid/id_ecdsa",
85 "chown -R syncoid:syncoid /var/lib/syncoid/",
86 )
87
88 assert len(source.succeed("zfs allow pool")) == 0, "Pool shouldn't have delegated permissions set before snapshotting"
89 assert len(source.succeed("zfs allow pool/sanoid")) == 0, "Sanoid dataset shouldn't have delegated permissions set before snapshotting"
90 assert len(source.succeed("zfs allow pool/syncoid")) == 0, "Syncoid dataset shouldn't have delegated permissions set before snapshotting"
91
92 # Take snapshot with sanoid
93 source.succeed("touch /mnt/pool/sanoid/test.txt")
94 source.systemctl("start --wait sanoid.service")
95
96 assert len(source.succeed("zfs allow pool")) == 0, "Pool shouldn't have delegated permissions set after snapshotting"
97 assert len(source.succeed("zfs allow pool/sanoid")) == 0, "Sanoid dataset shouldn't have delegated permissions set after snapshotting"
98 assert len(source.succeed("zfs allow pool/syncoid")) == 0, "Syncoid dataset shouldn't have delegated permissions set after snapshotting"
99
100 # Sync snapshots
101 target.wait_for_open_port(22)
102 source.succeed("touch /mnt/pool/syncoid/test.txt")
103 source.systemctl("start --wait syncoid-pool-sanoid.service")
104 target.succeed("cat /mnt/pool/sanoid/test.txt")
105 source.systemctl("start --wait syncoid-pool-syncoid.service")
106 target.succeed("cat /mnt/pool/syncoid/test.txt")
107
108 assert len(source.succeed("zfs allow pool")) == 0, "Pool shouldn't have delegated permissions set after syncing snapshots"
109 assert len(source.succeed("zfs allow pool/sanoid")) == 0, "Sanoid dataset shouldn't have delegated permissions set after syncing snapshots"
110 assert len(source.succeed("zfs allow pool/syncoid")) == 0, "Syncoid dataset shouldn't have delegated permissions set after syncing snapshots"
111 '';
112})