diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/default.nix | 1 | ||||
| -rwxr-xr-x | tests/fixtures.sh | 10 | ||||
| -rw-r--r-- | tests/scenarios.nix | 34 |
3 files changed, 44 insertions, 1 deletions
diff --git a/tests/default.nix b/tests/default.nix index a6b9356..285ed86 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -21,6 +21,7 @@ let remoteHost = "target"; agePath = "${pkgs.age}/bin/age"; inherit gitHead gitFirst; + rsyncVersion = pkgs.rsync.version; }; flakeJq = import ../pkgs/populate/flake-jq.nix; in diff --git a/tests/fixtures.sh b/tests/fixtures.sh index 833df77..b57dcc5 100755 --- a/tests/fixtures.sh +++ b/tests/fixtures.sh @@ -258,6 +258,16 @@ cat > /fixtures/alt2/flake.nix <<'NIX' { outputs = _: { greeting = "alt2"; who = "alt2"; }; } NIX +# filtered, filtered-link: a directory with an .rsync-filter, and a symlink to +# it that neither root nor the user deploying owns, through which rsync 3.5.0 +# and later can't read that file. +mkdir /fixtures/filtered +printf -- '- /garbage\n' > /fixtures/filtered/.rsync-filter +echo keep > /fixtures/filtered/keep +echo garbage > /fixtures/filtered/garbage +ln -s filtered /fixtures/filtered-link +chown -h nobody /fixtures/filtered-link + # noflake: a directory without flake.nix. mkdir /fixtures/noflake echo noflake > /fixtures/noflake/README diff --git a/tests/scenarios.nix b/tests/scenarios.nix index 4838b74..efad151 100644 --- a/tests/scenarios.nix +++ b/tests/scenarios.nix @@ -26,6 +26,8 @@ # HEAD of /fixtures/gitsrc, and its parent. gitHead, gitFirst, + # Version of rsync on the deploying machine. + rsyncVersion, }: let @@ -269,7 +271,37 @@ assert !(krops.isLocalTarget (targets.remote "/")); targetKind = "local"; phases = [ (builtins.head args.phases) ]; })) - ]; + ] + # A source whose .rsync-filter rsync 3.5.0 and later can't read, because + # it's reached through a symlink that neither root nor the user deploying + # owns. (Running as root, the scenarios can't use the other common + # cause, a directory on the way that the user may enter but not read.) + ++ concatMap (targetKind: map (insecureLinks: let + affected = lib.versionAtLeast rsyncVersion "3.5.0"; + excluded = !affected || insecureLinks == true; + in scenario { + name = "file-${targetKind}-insecureLinks" + + (if insecureLinks == null then "Null" else if insecureLinks then "True" else "False"); + inherit targetKind; + prepare = '' + mkdir -p "$T"/x + echo old > "$T"/x/garbage + ''; + phases = twice ({ + sources.x.file = { path = "/fixtures/filtered-link"; inherit insecureLinks; }; + } // (if affected && insecureLinks == null then { + expect.fail = "can't read /fixtures/filtered-link/.rsync-filter, so it would sync /fixtures/filtered-link/ without it."; + } else { + check = '' + expect_eq keep "$(cat "$T"/x/keep)" keep + ${if excluded then '' + test ! -e "$T"/x/garbage || fail "garbage not excluded" + '' else '' + expect_eq garbage "$(cat "$T"/x/garbage)" garbage + ''} + ''; + })); + }) [ null true false ]) targetKinds; flake = matrix "flake" { kind = [ "git" "path" "subdir" "remote" ]; |
