update: offload eval to the server too via remote nix build + --store-path

This commit is contained in:
rope 2026-08-13 11:49:19 +01:00
parent a6eacab7fb
commit dafd23d159
2 changed files with 23 additions and 3 deletions

View file

@ -9,6 +9,22 @@ let
# 146%. Plain `-L` output there; the other hosts can afford the pretty one. # 146%. Plain `-L` output there; the other hosts can afford the pretty one.
buildLog = lib.optionalString (!isMacbook) buildLog = lib.optionalString (!isMacbook)
" --log-format internal-json 2>&1 | nom --json"; " --log-format internal-json 2>&1 | nom --json";
flake = "git+https://forg.gregersen.it/rope/nixos";
post = "nvd diff $OLD_SYSTEM /run/current-system && (command -v record-update &>/dev/null && record-update $OLD_SYSTEM /run/current-system || true)";
# The server evaluates and builds for itself.
localUpdate = "bash -c 'set -o pipefail && OLD_SYSTEM=$(readlink /run/current-system) && sudo nixos-rebuild switch $@ --refresh --flake ${flake} -L${buildLog} && ${post}' --";
# The clients offload the *evaluation* too, not just the build. nixos-rebuild
# always evaluates on the machine it runs on (--build-host ships the
# derivation, not the expression), so the only way to move eval off a client
# is to run nix on the server over SSH and hand the resulting closure to
# --store-path, which skips eval and build entirely. Same lantian substituter
# as services/prebuild.nix, and --out-link keeps a gc root on the server so
# `clean` there can't reap the closure mid-copy.
remoteUpdate = "bash -c 'set -o pipefail && OLD_SYSTEM=$(readlink /run/current-system) && NEW=$(sudo ssh fred@nordhammer.it \"nix build --refresh --print-out-paths --out-link prebuild-${config.networking.hostName} --option extra-substituters https://attic.xuyh0120.win/lantian --option extra-trusted-public-keys lantian:EeAUQ+W+6r7EtwnmYjeVwx5kOGEBpjlBfPlzGlTNvHc= ${flake}#nixosConfigurations.${config.networking.hostName}.config.system.build.toplevel\") && sudo nix copy --from ssh://fred@nordhammer.it $NEW && sudo nixos-rebuild switch --store-path $NEW && ${post}'";
in in
{ {
imports = [ imports = [
@ -122,7 +138,10 @@ in
# Shell aliases (work in both bash and fish) # Shell aliases (work in both bash and fish)
environment.shellAliases = { environment.shellAliases = {
update = "bash -c 'set -o pipefail && OLD_SYSTEM=$(readlink /run/current-system) && sudo nixos-rebuild switch $@ --refresh --flake git+https://forg.gregersen.it/rope/nixos -L${buildLog} && nvd diff $OLD_SYSTEM /run/current-system && (command -v record-update &>/dev/null && record-update $OLD_SYSTEM /run/current-system || true)' --"; update =
if config.networking.hostName == "FredOS-Mediaserver"
then localUpdate
else remoteUpdate;
clean = "sudo nix-collect-garbage -d"; clean = "sudo nix-collect-garbage -d";
# Throw away the VM's disk first so every run is a real first boot — # Throw away the VM's disk first so every run is a real first boot —
# greeter, Plasma first-run, the lot. Builds into ./result in $PWD. # greeter, Plasma first-run, the lot. Builds into ./result in $PWD.

View file

@ -3,8 +3,9 @@
# Both laptops/desktops offload builds to this host (nix.buildMachines in # Both laptops/desktops offload builds to this host (nix.buildMachines in
# common.nix), and the Macbook can't build at all (max-jobs = 0). Realising # common.nix), and the Macbook can't build at all (max-jobs = 0). Realising
# their toplevels here ahead of time turns `update` on those machines into a # their toplevels here ahead of time turns `update` on those machines into a
# pure copy: the offloaded build finds the path already in this store and just # pure copy: the client's `update` alias re-runs this exact nix build over SSH
# ships it back over SSH. # (so eval happens here too, against a warm eval cache), finds the path already
# realised, and only copies the closure back.
# #
# --out-link doubles as the gc root, so `clean` doesn't reap the closures # --out-link doubles as the gc root, so `clean` doesn't reap the closures
# before the other machines ever ask for them. # before the other machines ever ask for them.