Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos-rebuild: Allow remote building when using flakes #119540

Merged
merged 2 commits into from
May 8, 2021

Conversation

chvp
Copy link
Member

@chvp chvp commented Apr 15, 2021

Motivation for this change

Remotely building hosts when using flakes should be possible. See also #119448, https://discourse.nixos.org/t/building-a-flake-based-nixos-system-remotely/11309/4, and https://nixos.wiki/wiki/Flakes#Using_nix_flakes_with_NixOS

Things done

I rebuilt my system with this PR, and then used nixos-rebuild to build a host on itself, build a host on another remote host and build the local host on a remote host.

  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Apr 15, 2021
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/building-a-flake-based-nixos-system-remotely/11309/5

@chvp chvp force-pushed the nixos-rebuild-remote-flakes branch from cc5e29e to c4a1855 Compare April 16, 2021 08:05
@chvp chvp force-pushed the nixos-rebuild-remote-flakes branch from c4a1855 to 9241a4d Compare April 16, 2021 09:46
if [ -a "$drv" ]; then
NIX_SSHOPTS=$SSHOPTS nix "${flakeFlags[@]}" copy --derivation --to "ssh://$buildHost" "$drv"
# The 'nix-command flakes' part in "${flakeFlags[@]}" is seen as two separate args over SSH
buildHostCmd nix --experimental-features "'nix-command flakes'" build "${buildArgs[@]}" --out-link "${tmpDir}/result" "$drv"
Copy link
Contributor

@asymmetric asymmetric Apr 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now requires that the remote host has nix.package = pkgs.nixUnstable, due to the --experimental-features flag. I think we should mention that somewhere.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❯ ../nix/nixos-rebuild.sh switch --target-host monitor --flake ~/code/foo#monitor --use-remote-sudo
warning: Git tree '/home/asymmetric/code/foo' is dirty
building the system configuration...
warning: Git tree '/home/asymmetric/code/foo' is dirty
error: unrecognised flag '--experimental-features'
Try 'nix --help' for more information.
error: getting status of '/tmp/nixos-rebuild.u96Og6/result': No such file or directory

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's true? As I understand it, nixos-rebuild uses it's own nix by default. I guess it could be documented for when --no-build-nix, --build-host and flakes are combined, but that seems like a rare use-case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, posted before I saw your later comments. I wonder if the --use-remote-sudo flag is responsible?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already code that builds the latest Nix before attempting to rebuild to exactly avoid that situation, however, currently that is limited to the local machine.

if [[ -n $buildNix && -z $flake ]]; then
echo "building Nix..." >&2
nixDrv=
if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then
if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then
if ! nixStorePath="$(nix-instantiate --eval '<nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix>' -A $(nixSystem) | sed -e 's/^"//' -e 's/"$//')"; then
nixStorePath="$(prebuiltNix "$(uname -m)")"
fi
if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \
--option extra-binary-caches https://cache.nixos.org/; then
echo "warning: don't know how to get latest Nix" >&2
fi
# Older version of nix-store -r don't support --add-root.
[ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix
if [ -n "$buildHost" ]; then
remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")"
remoteNix="$remoteNixStorePath/bin"
if ! buildHostCmd nix-store -r $remoteNixStorePath \
--option extra-binary-caches https://cache.nixos.org/ >/dev/null; then
remoteNix=
echo "warning: don't know how to get latest Nix" >&2
fi
fi
fi
fi
if [ -a "$nixDrv" ]; then
nix-store -r "$nixDrv"'!'"out" --add-root $tmpDir/nix --indirect >/dev/null
if [ -n "$buildHost" ]; then
nix-copy-closure --to "$buildHost" "$nixDrv"
# The nix build produces multiple outputs, we add them all to the remote path
for p in $(buildHostCmd nix-store -r "$(readlink "$nixDrv")" "${buildArgs[@]}"); do
remoteNix="$remoteNix${remoteNix:+:}$p/bin"
done
fi
fi
PATH="$tmpDir/nix/bin:$PATH"
fi

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, same thing:

❯ ../nix/nixos-rebuild.sh switch --target-host monitor --flake ~/code/foo#monitor
warning: Git tree '/home/asymmetric/code/foo' is dirty
building the system configuration...
warning: Git tree '/home/asymmetric/code/foo' is dirty
error: unrecognised flag '--experimental-features'
Try 'nix --help' for more information.
error: getting status of '/tmp/nixos-rebuild.Aa5unK/result': No such file or directory

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation for the --build-host option says that it is also built remotely.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the nix build only happens if flakes aren't used. That's annoying.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to use old-style nix commands on the build host. It seemed like the most frictionless change to me.

@chvp chvp force-pushed the nixos-rebuild-remote-flakes branch from 9241a4d to 456aa2d Compare April 16, 2021 09:59
@asymmetric
Copy link
Contributor

@chvp I think it would be a bit easier to review if you didn't force-push, so we could look at the diff in each commit ❤️

@hmenke
Copy link
Member

hmenke commented Apr 27, 2021

@edolstra @worldofpeace @obadz @volth @domenkozar @Mic92
Could someone please review this? Having working remote builds with flakes would be a nice feature for 21.05. (You were pinged because you previously committed to this file)

@chvp
Copy link
Member Author

chvp commented May 8, 2021

Just wanted to mention that I've been using this to build my systems remotely since I created this PR without any issues.

@domenkozar
Copy link
Member

This PR doesn't change behavior if host is not defined and a few people reported success with it, so let's merge it.

@domenkozar domenkozar merged commit be91d80 into NixOS:master May 8, 2021
@chvp chvp deleted the nixos-rebuild-remote-flakes branch May 8, 2021 19:24
jonringer added a commit to jonringer/nixpkgs that referenced this pull request Jun 11, 2021
Prior to NixOS#119540, the toplevel output was built
locally then pushed to the remote host when using
the command:

nixos-rebuild --flake <flake> --target-host remote.host

However, buildHost would default to targetHost when
only --target-host was supplied. This caused the .drv
closure to always be transferred unless --build-host=localhost
is supplied.

This change restores the previous build local default behavior.
TargetHost can still build the outputs, if explicitly mentioned:

nixos-rebuild --flake <flake> \
  --target-host remote.host \
  --build-host  remote.host
@jonringer
Copy link
Contributor

This PR doesn't change behavior if host is not defined and a few people reported success with it, so let's merge it.

This wasn't correct because of the following lines:

if [ -z "$buildHost" -a -n "$targetHost" ]; then
    buildHost="$targetHost"
fi
if [ "$targetHost" = localhost ]; then
    targetHost=
fi
if [ "$buildHost" = localhost ]; then
    buildHost=
fi

A previous nixos-rebuild --target-host remote.host --flake <flake> would build the outputs locally, then nix-copy them over. New behavior would be instantiate the .drv and nix copy the entire .drv closure.

The consequences was that 2000-4400 store paths would need be transferred instead of the previous 100-400 realised paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants