diff --git a/scripts/deploy b/scripts/deploy index 1e8f35f3a..c610e6b87 100755 --- a/scripts/deploy +++ b/scripts/deploy @@ -16,6 +16,7 @@ usage() { echo "- --reboot: reboot the target machine after deploying (if deployed with no errors)" echo "- --variant light|min|''|all (default: '')" echo "- --wireguard always|never|opportunistic: deploy over wireguard" + echo "- --deriv /nix/store/...: prebuilt store path to deploy instead of (re-)building the default target" echo "" echo "common idioms:" echo "- deploy all: deploy all hosts, sequentially" @@ -38,6 +39,7 @@ nixArgs=() doReboot= dryRun= wireguard=opportunistic +storePath= addHost() { if [ "$1" = all ]; then # order matters: @@ -64,6 +66,10 @@ parseArgs() { (--copy|--switch|--test) action=${arg/--/} ;; + (--deriv) + storePath="$1" + shift + ;; (--dry-run) dryRun=1 ;; @@ -154,16 +160,19 @@ deployOneHost() { local host="$1" local variant="$2" - # `nix-build -A foo` evals and then realizes foo, but it never unloads the memory used to eval foo. - # my exprs are heavyweight, we need that memory for building, so do the evals separately from the realizations: - info "evaluating $host$variant..." - local drvPath=$(nix eval --raw -f . "hosts.$host$variant.toplevel.drvPath") - info "building $host$variant ($drvPath)" - local storePath=$(destructive nix-store --realize "$drvPath" "${nixArgs[@]}") - if [ -z "$storePath" ]; then - return 1 + local myStorePath="$storePath" + if [ -z "$myStorePath" ]; then + # `nix-build -A foo` evals and then realizes foo, but it never unloads the memory used to eval foo. + # my exprs are heavyweight, we need that memory for building, so do the evals separately from the realizations: + info "evaluating $host$variant..." + local drvPath=$(nix eval --raw -f . "hosts.$host$variant.toplevel.drvPath") + info "building $host$variant ($drvPath)" + myStorePath=$(destructive nix-store --realize "$drvPath" "${nixArgs[@]}") + if [ -z "$myStorePath" ]; then + return 1 + fi + info "built $host$variant -> $myStorePath" fi - info "built $host$variant -> $storePath" # mimic `nixos-rebuild --target-host`, in effect: # - nix-copy-closure ... @@ -179,20 +188,20 @@ deployOneHost() { if [ -n "$host" ] && [ "$host" != "$SELF" ]; then if [ -e /run/secrets/nix_signing_key ]; then info "signing store paths ..." - destructive sudo nix store sign -r -k /run/secrets/nix_signing_key "$storePath" + destructive sudo nix store sign -r -k /run/secrets/nix_signing_key "$myStorePath" else info "not signing store paths: /run/secrets/nix_signing_key does not exist" fi # add more `-v` for more verbosity (up to 5). # builders-use-substitutes false: optimizes so that the remote machine doesn't try to get paths from its substituters. # we already have all paths here, and the remote substitution is slow to check and SERIOUSLY flaky on moby in particular. - ECHO_CMD=1 destructive nix copy -vv --option builders-use-substitutes false --to "ssh-ng://$netHost" "$storePath" || return 1 + ECHO_CMD=1 destructive nix copy -vv --option builders-use-substitutes false --to "ssh-ng://$netHost" "$myStorePath" || return 1 fi if [ -n "$action" ] && [ "$action" != "copy" ]; then info "activating profile... " - destructive runOnTarget "$netHost" sudo nix-env -p /nix/var/nix/profiles/system --set "$storePath" || return 1 - destructive runOnTarget "$netHost" sudo "$storePath/bin/switch-to-configuration" "$action" || return 1 + destructive runOnTarget "$netHost" sudo nix-env -p /nix/var/nix/profiles/system --set "$myStorePath" || return 1 + destructive runOnTarget "$netHost" sudo "$myStorePath/bin/switch-to-configuration" "$action" || return 1 if [ -n "$doReboot" ]; then info "rebooting $host" destructive runOnTarget "$netHost" sane-reboot "$host"