fix(migration): poll for WAN health instead of sampling once at 25s

A real cutover attempt reported failure and reverted a configuration that may
well have been fine. The health check waited a fixed 25 seconds and then judged:

  [switch] committed. Waiting 25s for PPPoE and services to settle...
  [switch]   FAIL  pppoe0 has an address

25s is far too short for a WAN. PPPoE alone is PADI/PADO/PADR/PADS followed by
LCP, authentication and IPCP -- routinely 15-30s on its own. Both lines had also
just been released by the USG seconds earlier, and ISPs commonly hold the
previous session and MAC binding for minutes before leasing to the "same" CPE
again, which is exactly what a cloned MAC looks like from their side. The one
thing the design could not tolerate was being impatient, and it was.

Now polls every 15s up to HEALTH_BUDGET (default 180s), reporting progress, and
stops early the moment everything is healthy. The budget deliberately finishes
long before commit-confirm fires -- 180s against a 10 minute timer leaves 420s
of margin -- so the decision to confirm or revert stays ours rather than being
made by the timer.

Also recorded while chasing this: the earlier claim that VLANs 51/53 are not
trunked to the firewalls was WRONG, and the UniFi port settings disprove it --
those LAG ports are Native VLAN Management (1) with Tagged VLAN Management set
to Allow All. My evidence never supported the claim: a passive RX count cannot
distinguish an absent VLAN from a quiet one, because switches do not flood
unicast, and the active DHCP probe used a random MAC that an ISP binding to its
registered CPE would ignore regardless. Both observations fit a perfectly
healthy trunk.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DMVzWZgiKW2wquf5z8S1yH
This commit is contained in:
Michal
2026-08-18 01:10:50 +01:00
parent ff86a421f4
commit 54b21fa9ff

View File

@@ -224,8 +224,32 @@ to_vyos() {
fi
rm -f "$tmp"
say "committed. Waiting 25s for PPPoE and services to settle..."
sleep 25
# Poll, do not sample once.
#
# A cutover attempt failed here on a fixed 25s wait. That is far too short for
# a WAN: PPPoE is PADI/PADO/PADR/PADS then LCP, auth and IPCP, routinely 15-30s
# by itself, and both lines had just been released by the USG seconds earlier.
# ISPs commonly hold the previous session and MAC binding for minutes before
# leasing to the "same" CPE again -- which is precisely what a cloned MAC looks
# like to them. One sample at 25s reported a healthy setup as broken and
# reverted it.
#
# There is still a deadline, because commit-confirm is running: stop well
# before it so the decision is ours rather than the timer's.
local budget="${HEALTH_BUDGET:-180}" waited=0 step=15
say "committed. Polling health for up to ${budget}s (commit-confirm has ${CONFIRM_MINUTES} min)..."
while :; do
sleep "$step"; waited=$(( waited + step ))
if health_checks >/dev/null 2>&1; then
say "healthy after ${waited}s"
break
fi
if [ "$waited" -ge "$budget" ]; then
say "still unhealthy after ${waited}s -- final check:"
break
fi
say " not healthy yet at ${waited}s, still waiting..."
done
say "health checks:"
if health_checks; then