diff options
| author | tv <tv@krebsco.de> | 2026-11-12 20:25:15 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-13 03:24:29 +0100 |
| commit | 32eeb3aeda1519acbc15c120693aebc95cbd5c38 (patch) | |
| tree | 38f7d19ce5ca0dd5e99ae9aeb4fb3eb7b9ee91f1 /pkgs | |
| parent | 1880ceb3544de8cf194163394c8291b60924a2e6 (diff) | |
krops writeDeploy: deploy every flake by a URL Nix can't misread
nixos-rebuild gets generated flakes as path: URLs, but other flakes by
their bare paths, which Nix takes for the enclosing Git work tree, if the
target directory lies in one. A file source there fails to deploy,
because the work tree doesn't track it. Every flake gets deployed by a
URL: a Git work tree as git+file:, with submodules if it has any, like
populate refers to it, and anything else as path:.
The path gets resolved on the build target, because Nix refuses URLs
with symlinks on the way, which the target directory may be, and
percent-encoded.
--build-host and --target-host name no user if the target has none,
instead of failing to evaluate.
The deploy test also deploys flakes from file and git sources. Its
scenarios evaluate without LOGNAME.
Diffstat (limited to 'pkgs')
| -rw-r--r-- | pkgs/krops/default.nix | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/pkgs/krops/default.nix b/pkgs/krops/default.nix index 3aa68cf..ac2d9a2 100644 --- a/pkgs/krops/default.nix +++ b/pkgs/krops/default.nix @@ -8,22 +8,41 @@ in flake ? null, useNixOutputMonitor }: - args: target: + args: target: let + # The flake's directory in the target directory, and the name of the + # NixOS configuration with its #, if any. + flakeDir = lib.head (lib.splitString "#" flake); + flakeAttr = lib.removePrefix flakeDir flake; + in runShell target {} (withNixOutputMonitor target useNixOutputMonitor /* sh */ '' - ${lib.optionalString (flake != null) - (lib.shell.requireFlakes "deploying a flake")} + ${lib.optionalString (flake != null) /* sh */ '' + ${lib.shell.requireFlakes "deploying a flake"} + ${lib.shell.urlPath} + # A Git work tree gets deployed as such. Anything else gets + # deployed as path:, not just by its path, which Nix takes for the + # enclosing Git work tree, if any. Nix refuses URLs with symlinks + # on the way, which the target directory may be, or the source. + flake=$(readlink -f ${lib.escapeShellArg "${target.path}/${flakeDir}"}) + if test -e "$flake"/.git; then + if test -e "$flake"/.gitmodules; then + flake=git+file:$(url_path "$flake")?submodules=1 + else + flake=git+file:$(url_path "$flake") + fi + else + flake=path:$(url_path "$flake") + fi + ''} NIX_PATH=${lib.escapeShellArg target.path} \ - nixos-rebuild ${lib.escapeShellArgs (args ++ lib.optionals (flake != null) [ - "--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. - "$(test -e /etc/nixos/flake.nix && echo --no-flake)"} + nixos-rebuild ${lib.escapeShellArgs args} ${ + if flake != null then + ''--flake "$flake"${lib.escapeShellArg flakeAttr}'' + else + # nixos-rebuild deploys /etc/nixos/flake.nix if it exists. Any + # nixos-rebuild doing so supports --no-flake. + "$(test -e /etc/nixos/flake.nix && echo --no-flake)" + } ''); runShell = target: { @@ -117,6 +136,11 @@ in then target' else lib.mkTarget buildTarget; target' = lib.mkTarget target; + # A host as nixos-rebuild takes it. Without a user, ssh decides. + userHost = target: + lib.optionalString (target.user != null && target.user != "") + "${target.user}@" + + target.host; # The source's generated flake, if it draws inputs from other sources. flake' = let name = lib.head (lib.splitString "#" flake); @@ -140,8 +164,8 @@ in ] ++ lib.optionals crossDeploy [ "--no-build-nix" ] ++ lib.optionals (buildTarget' != target') [ - "--build-host" "${buildTarget'.user}@${buildTarget'.host}" - "--target-host" "${target'.user}@${target'.host}" + "--build-host" (userHost buildTarget') + "--target-host" (userHost target') ] ++ lib.optionals (buildTarget' != target' && target'.sudo) [ # nixos-rebuild runs on the target itself via sudo otherwise. "--use-remote-sudo" |
