syncoid: handle syncing dataset without a parent

This commit is contained in:
Jörg Thalheim 2022-07-04 12:46:37 +02:00
parent 03d52eed55
commit 2c3f6055fb
2 changed files with 24 additions and 16 deletions

View file

@ -16,11 +16,11 @@ let
lib.concatMapStrings (s: if lib.isList s then "-" else s)
(builtins.split "[^a-zA-Z0-9_.\\-]+" name);
# Function to build "zfs allow" commands for the filesystems we've
# delegated permissions to. It also checks if the target dataset
# exists before delegating permissions, if it doesn't exist we
# delegate it to the parent dataset. This should solve the case of
# provisoning new datasets.
# Function to build "zfs allow" commands for the filesystems we've delegated
# permissions to. It also checks if the target dataset exists before
# delegating permissions, if it doesn't exist we delegate it to the parent
# dataset (if it exists). This should solve the case of provisoning new
# datasets.
buildAllowCommand = permissions: dataset: (
"-+${pkgs.writeShellScript "zfs-allow-${dataset}" ''
# Here we explicitly use the booted system to guarantee the stable API needed by ZFS
@ -38,15 +38,17 @@ let
(concatStringsSep "," permissions)
dataset
]}
else
${lib.escapeShellArgs [
"/run/booted-system/sw/bin/zfs"
"allow"
cfg.user
(concatStringsSep "," permissions)
# Remove the last part of the path
(builtins.dirOf dataset)
]}
${lib.optionalString ((builtins.dirOf dataset) != ".") ''
else
${lib.escapeShellArgs [
"/run/booted-system/sw/bin/zfs"
"allow"
cfg.user
(concatStringsSep "," permissions)
# Remove the last part of the path
(builtins.dirOf dataset)
]}
''}
fi
''}"
);
@ -67,14 +69,14 @@ let
(concatStringsSep "," permissions)
dataset
]}
${lib.escapeShellArgs [
${lib.optionalString ((builtins.dirOf dataset) != ".") (lib.escapeShellArgs [
"/run/booted-system/sw/bin/zfs"
"unallow"
cfg.user
(concatStringsSep "," permissions)
# Remove the last part of the path
(builtins.dirOf dataset)
]}
])}
''}"
);
in

View file

@ -48,6 +48,9 @@ in {
};
# Take snapshot and sync
"pool/syncoid".target = "root@target:pool/syncoid";
# Test pool without parent (regression test for https://github.com/NixOS/nixpkgs/pull/180111)
"pool".target = "root@target:pool/full-pool";
};
};
};
@ -105,6 +108,9 @@ in {
source.systemctl("start --wait syncoid-pool-syncoid.service")
target.succeed("cat /mnt/pool/syncoid/test.txt")
source.systemctl("start --wait syncoid-pool.service")
target.succeed("[[ -d /mnt/pool/full-pool/syncoid ]]")
assert len(source.succeed("zfs allow pool")) == 0, "Pool shouldn't have delegated permissions set after syncing snapshots"
assert len(source.succeed("zfs allow pool/sanoid")) == 0, "Sanoid dataset shouldn't have delegated permissions set after syncing snapshots"
assert len(source.succeed("zfs allow pool/syncoid")) == 0, "Syncoid dataset shouldn't have delegated permissions set after syncing snapshots"