aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/populate
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-12 00:02:06 +0000
committertv <tv@krebsco.de>2026-11-12 00:02:06 +0000
commit69f0ab4533a6b233dca1193ee558de8994df1ffb (patch)
tree78a595d4584473b25bd9bc79c6589848306be26d /pkgs/populate
parenta018f44c9132ffa5c7b987369010868d0bc95c74 (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 'pkgs/populate')
-rw-r--r--pkgs/populate/default.nix41
1 files changed, 40 insertions, 1 deletions
diff --git a/pkgs/populate/default.nix b/pkgs/populate/default.nix
index 5472b5d..553183e 100644
--- a/pkgs/populate/default.nix
+++ b/pkgs/populate/default.nix
@@ -169,6 +169,44 @@ let
fi
'';
+ # Removes entries of the target directory that aren't sources, garbage
+ # collector roots of flake inputs of sources that aren't flake or
+ # flake-input sources, and uploads left behind by interrupted runs.
+ prune' = target: sources: let
+ pattern = names: concatMapStringsSep "|" quote names;
+ flakeNames = attrNames (filterAttrs
+ (_: source: elem source.type [ "flake" "flake-input" ])
+ sources);
+ in runShell target /* sh */ ''
+ set -efu
+ cd ${quote target.path}
+ ls -A | while read -r name; do
+ case $name in
+ ${pattern (attrNames sources ++ [ ".populate" ])}) ;;
+ *)
+ >&2 printf 'pruning %s\n' ${quote target.path}/"$name"
+ rm -fR ./"$name"
+ ;;
+ esac
+ done
+ roots=.populate/flake-inputs
+ if test -d "$roots"; then
+ ls -A "$roots" | while read -r name; do
+ case $name in
+ ${optionalString (flakeNames != []) "${pattern flakeNames}) ;;"}
+ *) rm -fR "$roots"/"$name" ;;
+ esac
+ done
+ if test -z "$(ls -A "$roots")"; then
+ rmdir "$roots"
+ fi
+ fi
+ if test -e .populate/flake-uploads; then
+ chmod -R u+w .populate/flake-uploads
+ rm -fR .populate/flake-uploads
+ fi
+ '';
+
pop.derivation = target: source: runShell target /* sh */ ''
nix-build -E ${quote source.text} -o ${quote target.path} >&2
'';
@@ -761,7 +799,7 @@ let
in
-{ backup ? false, force ? false, source, target }:
+{ backup ? false, force ? false, prune ? false, source, target }:
writers.writeDash "populate.${target.host}" ''
set -efu
@@ -776,6 +814,7 @@ writers.writeDash "populate.${target.host}" ''
${optionalString backup (do-backup { inherit target; })}
${concatStringsSep "\n" (mapAttrsToList (populate target) source)}
${flakes target source}
+ ${optionalString prune (prune' target source)}
# Stop the ssh master, if any source started one.
if ${ssh' target} -q -O check ${quote target.host} 2>/dev/null; then