if test (count $argv) -ne 1 echo "usage: deploy-to " >&2 return 2 end set host $argv[1] git rev-parse --show-toplevel >/dev/null 2>&1 or begin echo "deploy-to: run this from a git checkout" >&2 return 2 end set repository_root (git rev-parse --show-toplevel) or return $status set untracked_nix_files (git -C $repository_root ls-files --others --exclude-standard -- '*.nix' flake.nix flake.lock) if test (count $untracked_nix_files) -gt 0 echo "deploy-to: warning: untracked Nix files are not part of Git flake evaluation" >&2 printf ' %s\n' $untracked_nix_files >&2 end set installable "$repository_root#nixosConfigurations.$host.config.system.build.toplevel" echo "deploy-to: building $installable" >&2 set system_path (nix build --no-link --print-out-paths $installable) or begin echo "deploy-to: build failed for $host" >&2 return $status end if test (count $system_path) -ne 1 echo "deploy-to: expected one build output, got "(count $system_path) >&2 return 1 end set closure_paths (nix-store -qR $system_path) or begin echo "deploy-to: closure query failed for $host" >&2 return $status end echo "deploy-to: checking which closure paths $host is missing" >&2 set missing_paths (printf '%s\n' $closure_paths | ssh $host 'xargs -r nix-store --check-validity --print-invalid') or begin echo "deploy-to: remote closure check failed for $host" >&2 return $status end if test (count $missing_paths) -gt 0 set nar_file (mktemp --suffix=.nar) or return $status set remote_nar "/tmp/deploy-to-$host-"(date +%s)"-$fish_pid.nar" echo "deploy-to: exporting "(count $missing_paths)" missing closure paths for $system_path" >&2 nix-store --export $missing_paths >$nar_file or begin set export_status $status rm -f $nar_file echo "deploy-to: closure export failed for $host" >&2 return $export_status end echo "deploy-to: copying closure archive to $host:$remote_nar" >&2 scp $nar_file $host:$remote_nar set scp_status $status rm -f $nar_file if test $scp_status -ne 0 echo "deploy-to: closure archive copy failed for $host" >&2 return $scp_status end echo "deploy-to: importing closure on $host" >&2 ssh -t $host "sudo sh -c 'nix-store --import < $remote_nar' && rm -f $remote_nar" or begin echo "deploy-to: closure import failed for $host" >&2 return $status end else echo "deploy-to: $host already has the full closure for $system_path" >&2 end echo "deploy-to: recording $system_path as the system profile on $host" >&2 ssh -t $host sudo nix-env --profile /nix/var/nix/profiles/system --set $system_path or begin echo "deploy-to: system profile update failed for $host" >&2 return $status end echo "deploy-to: activating $system_path on $host" >&2 ssh -t $host sudo "$system_path/bin/switch-to-configuration" switch or begin echo "deploy-to: activation failed for $host" >&2 return $status end