Skip to content

Instantly share code, notes, and snippets.

@noonien
Created February 24, 2025 07:59
Show Gist options
  • Save noonien/60c46c4dc7e80cc500a4e5f447b2c99d to your computer and use it in GitHub Desktop.
Save noonien/60c46c4dc7e80cc500a4e5f447b2c99d to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
buildAddr=khan.sx.gl
host=$(hostname)
hostAddr=
signKey=
action=
extraEvalFlags=()
while [ "$#" -gt 0 ]; do
arg="$1"; shift 1
case "$arg" in
switch|boot|test|dry-activate)
action="$arg"
;;
-local)
buildAddr=localhost
;;
-build)
buildAddr="$1"; shift
;;
-sign)
signKey="$1"; shift
;;
-host)
host="$1"; shift
;;
-addr)
hostAddr="$1"; shift
;;
*)
extraEvalFlags+=("$arg")
;;
esac
done
[ -z "$action" ] && {
echo "no action specified"
exit 1
}
if [ "$host" = "$(hostname)" ]; then
hostAddr=localhost
fi
[ -z "$action" ] && {
echo "no action specified"
exit 1
}
[ -z "$hostAddr" ] && {
echo "no addr specified"
exit 1
}
echo "deploying $host, building on $buildAddr"
buildAttr=toplevel
if [ "$action" = build-vm ]; then
buildAttr=vm
elif [ "$action" = build-vm-with-bootloader ]; then
buildAttr=vmWithBootLoader
fi
drv=$(nix eval "${extraEvalFlags[@]}" --raw ".#nixosConfigurations.${host}.config.system.build.${buildAttr}.drvPath")
[ ! -e "$drv" ] && {
echo "nix eval failed"
exit 1
}
if [ "$buildAddr" = "localhost" ]; then
echo "building derivation"
# build derivation
out=$(nix-store -r "$drv")
if [ "$hostAddr" != "localhost" ]; then
# sign output
if [ -n "$signKey" ]; then
echo "signing"
sudo nix store sign -k "$signKey" -r "$out"
fi
# copy output to target
echo "copy output to target"
nix copy --substitute-on-destination --to "ssh-ng://$hostAddr" "$out"
fi
else
# copy derivation to build host
echo "copy derivation to build host"
nix copy --substitute-on-destination --derivation --to "ssh-ng://$buildAddr" "$drv^*"
# build derivation remotely
echo "build derivation remotely"
out=$(ssh "$buildAddr" "nix-store -r '$drv' ")
# copy derivation to target host
echo "copy derivation to target host"
if [ "$hostAddr" = "localhost" ]; then
nix copy --substitute-on-destination --from "ssh-ng://$buildAddr" "$out"
elif [ "$hostAddr" != "$buildAddr" ]; then
nix copy --substitute-on-destination --from "ssh-ng://$buildAddr" --to "ssh-ng://$hostAddr" "$out"
fi
fi
activateCmd=
# activate profile
if [ "$action" = switch ] || [ "$action" = boot ]; then
activateCmd="nix-env -p /nix/var/nix/profiles/system --set '$out'"
fi
# switch to configuration
[ -n "$activateCmd" ] && activateCmd+=" && "
activateCmd+="'$out/bin/switch-to-configuration' '$action'"
echo "activating profile"
if [ "$hostAddr" = "localhost" ]; then
sudo sh -c "$activateCmd"
else
ssh -t "$hostAddr" -- "sudo sh -c '$activateCmd'"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment