From 81cc4f06abc644b047e0758309cfbd982dac18ed Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 12 Nov 2026 02:33:44 +0000 Subject: populate pipe: deliver changed output of the same size pipe sources get a fixed modification time, so rsync's quick check took changed output of the same size, e.g. a new commit hash or token, for unchanged, and didn't deliver it. pipe sources get synced comparing checksums now. An edge case changes a pipe source's output without changing its size. --- pkgs/populate/default.nix | 4 +++- tests/fixtures.sh | 8 ++++++++ tests/scenarios.nix | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pkgs/populate/default.nix b/pkgs/populate/default.nix index 0992b0c..5939742 100644 --- a/pkgs/populate/default.nix +++ b/pkgs/populate/default.nix @@ -773,7 +773,9 @@ let ${quote source.command} > "$out" ${coreutils}/bin/touch -t 300001010000 "$out" - ${rsync' target rsyncDefaultConfig /* sh */ "$out"} + # With the fixed modification time, only checksums tell outputs of the + # same size apart. + ${rsync' target (rsyncDefaultConfig // { useChecksum = true; }) /* sh */ "$out"} ''; # TODO rm -fR instead of ln -f? diff --git a/tests/fixtures.sh b/tests/fixtures.sh index 1f6c478..1b39b45 100755 --- a/tests/fixtures.sh +++ b/tests/fixtures.sh @@ -244,6 +244,14 @@ cat > /fixtures/usedata/flake.nix <<'NIX' NIX printf hello > /fixtures/data/value +# pipe2: a command for the pipe source type whose output the tests change. +cat > /fixtures/pipe2 <<'SH' +#! /bin/sh +cat /fixtures/pipe2-data +SH +chmod +x /fixtures/pipe2 +echo piped > /fixtures/pipe2-data + # 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 f1a5958..0e54054 100644 --- a/tests/scenarios.nix +++ b/tests/scenarios.nix @@ -919,6 +919,32 @@ assert !(krops.isLocalTarget (targets.remote "/")); ''; }; }) + # Output of the same length, which rsync's quick check doesn't notice. + (s "pipe-change" { + prepareDeployer = '' + echo piped > /fixtures/pipe2-data + ''; + phases = [ + { + sources.x.pipe = "/fixtures/pipe2"; + check = '' + expect_eq x "$(cat "$T"/x)" piped + ''; + mutateDeployer = '' + echo PIPED > /fixtures/pipe2-data + ''; + } + { + sources.x.pipe = "/fixtures/pipe2"; + check = '' + expect_eq x "$(cat "$T"/x)" PIPED + ''; + mutateDeployer = '' + echo piped > /fixtures/pipe2-data + ''; + } + ]; + }) ] ++ lib.optional (targetKind == "local") # The target has the path the input is locked to. (s "uselocal" { -- cgit v1.3.1