Add router-on-a-stick, commit-confirm rollback and an example config

- Allow the WAN link to also carry LANs when the uplink is PPPoE on a
  VLAN with IPv6 off; only the PPP device counts as an uplink then, so
  LAN traffic can never match WAN rules.
- Add router.rollback: router-arm / router-confirm / router-rollback
  plus `nix run .#deploy`, a commit-confirm deployment flow.
- Wait for the LAN devices instead of the uplink in networkd
  wait-online, so an unplugged uplink cannot block boot or activation.
- Add examples/desktop (single NIC, PPPoE on VLAN 1001) as
  nixosConfigurations.example, built as a flake check.

Covered by the onestick and rollback VM tests and new assertion cases.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-27 23:09:09 +01:00
co-authored by Claude Sonnet 5.5
parent 3f8f2f4199
commit 0653b5cf2f
14 changed files with 714 additions and 89 deletions
+60
View File
@@ -0,0 +1,60 @@
# Deploy a router configuration with commit-confirm.
#
# router-deploy <flake-attr> <user@host> [--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 <flake-attr> <user@host> [--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"