95 lines
3.0 KiB
Fish
95 lines
3.0 KiB
Fish
if test (count $argv) -ne 1
|
|
echo "usage: deploy-to <host>" >&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
|
|
|
|
set remote_nar
|
|
|
|
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 the closure, recording $system_path, and activating it on $host" >&2
|
|
else
|
|
echo "deploy-to: $host already has the full closure for $system_path" >&2
|
|
echo "deploy-to: recording $system_path and activating it on $host" >&2
|
|
end
|
|
|
|
set remote_script (
|
|
string join '; ' \
|
|
'system_path=$1' \
|
|
'remote_nar=$2' \
|
|
'if test -n "$remote_nar"; then nix-store --import < "$remote_nar"; rm -f "$remote_nar"; fi' \
|
|
'nix-env --profile /nix/var/nix/profiles/system --set "$system_path"' \
|
|
'"$system_path/bin/switch-to-configuration" switch'
|
|
)
|
|
|
|
ssh -t $host sudo sh -e -c (string escape -- $remote_script) sh (string escape -- $system_path $remote_nar)
|
|
or begin
|
|
echo "deploy-to: deployment failed for $host" >&2
|
|
return $status
|
|
end
|