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