diff options
| author | tv <tv@krebsco.de> | 2026-11-12 00:02:06 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-12 00:02:06 +0000 |
| commit | 69f0ab4533a6b233dca1193ee558de8994df1ffb (patch) | |
| tree | 78a595d4584473b25bd9bc79c6589848306be26d /tests/scenarios.nix | |
| parent | a018f44c9132ffa5c7b987369010868d0bc95c74 (diff) | |
populate: add prune
Populate never removes what it delivered for sources that aren't
configured anymore. For flake and flake-input sources, that keeps their
garbage collector roots, so what they delivered never gets collected.
With prune, populate removes everything from the target directory that
isn't a source, except .populate, after syncing the sources. It also
removes the roots in .populate/flake-inputs of names that aren't flake or
flake-input sources, and uploads left behind by interrupted runs.
Pruning is opt-in, because the target directory may contain other things
worth keeping, or be shared by deployments with different sources.
writeDeploy, writeTest, and writeCommand pass prune on to populate.
A feature scenario deploys sources, deploys fewer without pruning, then
with pruning, and checks that the removed sources' entries and roots are
gone, while the remaining sources and .populate stay.
Diffstat (limited to 'tests/scenarios.nix')
| -rw-r--r-- | tests/scenarios.nix | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/tests/scenarios.nix b/tests/scenarios.nix index 22431a2..c9774bf 100644 --- a/tests/scenarios.nix +++ b/tests/scenarios.nix @@ -64,10 +64,10 @@ let path = "/var/krops/${name}"; target = targets.${targetKind} path; vars = "T=${path}\n"; - phase = { sources, expect ? "success", check ? "", mutate ? null }: let + phase = { sources, prune ? false, expect ? "success", check ? "", mutate ? null }: let command = populate { source = krops.evalSource [ sources ]; - inherit target; + inherit prune target; force = true; }; evaluated = builtins.tryEval (builtins.seq (toString command) true); @@ -480,6 +480,55 @@ in { } ]; }) + # Pruning removes everything sources don't deliver anymore, including + # garbage collector roots, and keeps everything else. + (s "prune" (let + sources = { + a.file = "/fixtures/alt"; + b.flake = { flake = "/fixtures/top"; inherit fetchOnTarget; }; + c.flake-input = { flake = "/fixtures/top"; name = "dep"; inherit fetchOnTarget; }; + d.symlink = "a"; + }; + in { + prepare = '' + mkdir -p "$T" + echo other > "$T"/other + ''; + phases = [ + { + inherit sources; + check = '' + test -e "$T"/.populate/flake-inputs/b || fail "roots of b missing" + test -e "$T"/.populate/flake-inputs/c || fail "roots of c missing" + ''; + } + { + # Without pruning, nothing gets removed. + sources = { inherit (sources) a; }; + check = '' + for name in b c d other .populate/flake-inputs/b .populate/flake-inputs/c; do + test -e "$T"/$name || fail "$name removed" + done + ''; + } + { + # b changes its type, so its roots go, while b stays. + sources = { inherit (sources) a; b.symlink = "a"; }; + prune = true; + check = '' + test -e "$T"/a/flake.nix || fail "a removed" + expect_eq b "$(readlink "$T"/b)" a + test -d "$T"/.populate || fail ".populate removed" + for name in c d other .populate/flake-inputs; do + test ! -e "$T"/$name || fail "$name not pruned" + done + if nix-store --gc --print-roots 2>/dev/null | grep -F "$T/"; then + fail "garbage collector roots remain" + fi + ''; + } + ]; + })) (s "cycle" { phases = [{ sources = { |
