# Deploy a router configuration with commit-confirm. # # router-deploy [--yes] # # Builds locally, arms the rollback timer on the router, activates the new # configuration without making it the boot default, and checks that the router # is still reachable. Confirmed (manually, or with --yes) it becomes the boot # default; otherwise the router rolls itself back when the timer expires. usage() { echo "usage: router-deploy [--yes]" >&2 exit 2 } [ $# -ge 2 ] || usage attr=$1 host=$2 auto=${3:-} ssh_opts=(-o ConnectTimeout=10 -o ServerAliveInterval=5 -o ServerAliveCountMax=3) remote() { ssh "${ssh_opts[@]}" "$host" "$@"; } echo ">> building .#$attr" nixos-rebuild build --flake ".#$attr" echo ">> arming rollback on $host" remote router-arm echo ">> activating (not the boot default yet)" if ! nixos-rebuild test --flake ".#$attr" --target-host "$host"; then echo "!! activation failed; the router rolls back by itself when the timer expires" >&2 echo " (or run: ssh $host router-rollback)" >&2 exit 1 fi echo ">> checking the router is still reachable" reachable=0 for _ in 1 2 3 4 5 6; do if remote true; then reachable=1 break fi sleep 5 done if [ "$reachable" -ne 1 ]; then echo "!! lost contact with $host; it will roll back when the timer expires" >&2 exit 1 fi if [ "$auto" != "--yes" ]; then echo "Check that everything works (LAN, internet, DNS), then confirm." read -r -p "Confirm and make it permanent? [y/N] " answer if [ "$answer" != "y" ]; then echo ">> not confirmed: rolling back" remote router-rollback remote systemctl stop router-rollback.timer exit 1 fi fi remote router-confirm echo ">> confirmed"