aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-12 02:33:44 +0000
committertv <tv@krebsco.de>2026-11-12 02:33:44 +0000
commit352dd5ce3107e2547db56802d773b919df03690f (patch)
tree1e5f6a3030e9eefee520728b1599f5ff6acf1f80
parentd63531d2d42524f5150d138000bec42fd49d1e71 (diff)
populate, krops writeDeploy: refer to generated flakes as path:
Generated flakes got locked with a bare nix flake lock in their directory, and writeDeploy deployed them by their path. Nix takes both for the enclosing Git work tree, if the target directory lies in one, e.g. a home directory kept in Git, and fails, because generated flakes aren't tracked there. Both refer to generated flakes as path: now. An edge case deploys into a Git work tree, and the deploy test covers deploying generated flakes.
-rw-r--r--pkgs/krops/default.nix6
-rw-r--r--pkgs/populate/default.nix3
-rw-r--r--tests/scenarios.nix43
3 files changed, 41 insertions, 11 deletions
diff --git a/pkgs/krops/default.nix b/pkgs/krops/default.nix
index e4f72cd..46ca66f 100644
--- a/pkgs/krops/default.nix
+++ b/pkgs/krops/default.nix
@@ -15,7 +15,11 @@ in
(lib.shell.requireFlakes "deploying a flake")}
NIX_PATH=${lib.escapeShellArg target.path} \
nixos-rebuild ${lib.escapeShellArgs (args ++ lib.optionals (flake != null) [
- "--flake" "${target.path}/${flake}"
+ "--flake"
+ # Generated flakes as path:, not just their paths, which Nix takes
+ # for the enclosing Git work tree, if any.
+ (lib.optionalString (lib.hasPrefix ".populate/flakes/" flake) "path:" +
+ "${target.path}/${flake}")
])} ${lib.optionalString (flake == null)
# nixos-rebuild deploys /etc/nixos/flake.nix if it exists. Any
# nixos-rebuild doing so supports --no-flake.
diff --git a/pkgs/populate/default.nix b/pkgs/populate/default.nix
index 08a624b..0992b0c 100644
--- a/pkgs/populate/default.nix
+++ b/pkgs/populate/default.nix
@@ -120,7 +120,8 @@ let
printf ' outputs = inputs: inputs.%s;\n' ${quote (toJSON name)}
echo '}'
} > flake.nix
- nix flake lock >&2
+ # Not just ., which Nix takes for the enclosing Git work tree, if any.
+ nix flake lock ${quote "path:${flakesDir}/${name}"} >&2
)
'';
in
diff --git a/tests/scenarios.nix b/tests/scenarios.nix
index eeeb665..f1a5958 100644
--- a/tests/scenarios.nix
+++ b/tests/scenarios.nix
@@ -455,7 +455,7 @@ assert !(krops.isLocalTarget (targets.remote "/"));
# writeDeploy's arguments to nixos-rebuild, which a stand-in records.
deploy = matrix "deploy" {
- flake = [ false true ];
+ flake = [ "none" "source" "generated" ];
etcFlake = [ false true ];
buildTarget = [ false true ];
} (flags: ctx: let
@@ -468,8 +468,14 @@ assert !(krops.isLocalTarget (targets.remote "/"));
"--target-host" "${target.user}@${target.host}"
]
++ optional (flags.buildTarget && target.sudo) "--use-remote-sudo"
- ++ optionals flags.flake [ "--flake" "${build.path}/x" ]
- ++ optional (flags.etcFlake && !flags.flake) "--no-flake";
+ ++ {
+ none = [];
+ source = [ "--flake" "${build.path}/x" ];
+ # Generated flakes as path:, which an enclosing Git work tree doesn't
+ # capture.
+ generated = [ "--flake" "path:${build.path}/.populate/flakes/x" ];
+ }.${flags.flake}
+ ++ optional (flags.etcFlake && flags.flake == "none") "--no-flake";
in
# The local target can't have another build target.
if flags.buildTarget && ctx.targetKind == "local" then null else {
@@ -485,17 +491,20 @@ assert !(krops.isLocalTarget (targets.remote "/"));
''}
'';
phases = twice {
- sources.x =
- if flags.flake then {
- flake = {
+ sources =
+ if flags.flake == "none" then {
+ x.file = "/fixtures/alt";
+ } else alt // {
+ x.flake = {
flake = "/fixtures/top";
fetchOnTarget = ctx.targetKind == "sudo";
+ inputs = optionalAttrs (flags.flake == "generated") {
+ dep.follows = "alt";
+ };
};
- } else {
- file = "/fixtures/alt";
};
deploy = {
- flake = if flags.flake then "x" else null;
+ flake = if flags.flake == "none" then null else "x";
} // optionalAttrs flags.buildTarget {
inherit buildTarget;
};
@@ -894,6 +903,22 @@ assert !(krops.isLocalTarget (targets.remote "/"));
'';
};
})
+ # The target directory in a Git work tree.
+ (s "gitdir" {
+ prepare = ''
+ mkdir -p "$T"
+ git -C "$T" init -q
+ '';
+ phases = twice {
+ sources = alt // {
+ x.file = { path = "/fixtures/filesrc"; inputs.dep.follows = "alt"; };
+ };
+ check = ''
+ # Not just the path, which Nix takes for the enclosing work tree.
+ expect_eq msg "$(nix_eval_online path:"$T"/.populate/flakes/x#msg)" top:alt,sub
+ '';
+ };
+ })
] ++ lib.optional (targetKind == "local")
# The target has the path the input is locked to.
(s "uselocal" {