{ "_comment": [ "STAGED, NOT APPLIED. Paste these two objects into", "kubernetes-deployment infra/vyos/subtrees/overrides.json -- but ONLY after", "migration/vrrp-wan-install has run on BOTH production routers.", "", "Ordering is not a nicety. Another agent runs `pulumi up` on that repo, so", "merging this file IS a production change, made by someone else, at a time", "you do not choose. Removing `interfaces pppoe pppoe0 disable` from vyos002", "before the gate exists there lets vyos002 dial the moment anything commits,", "and Vodafone is a single-session account: it would take the live session off", "vyos001 and drop the household's internet.", "", "Install the gate first. Verify `systemctl show ppp@pppoe0 -p ConditionResult`", "reads `no` on vyos002. Only then merge.", "", "Note there is deliberately NO override asserting `vif 53 disable`.", "applyTree is delete-then-set per subtree, so the model is authoritative and", "omission means deletion -- but the 10 gig resting state is RUNTIME state", "owned by vrrp-wan-reconcile, keyed on who holds the management VIP. Pinning", "it in the model would fight the reconciler on every apply. The rule is", "`npm run vyos:export && npm run vyos:render` immediately before any", "`pulumi up`, so the model follows whichever router actually holds the WAN." ], "overrides": [ { "id": "pppoe-gated-not-config-disabled", "routers": ["vyos002"], "reason": "PPPoE cannot live on the VyOS config plane. interfaces_pppoe.py treats `disable` and `delete` identically: both unlink /etc/ppp/peers/pppoe0, which is pppd's own options file (ExecStart=/usr/sbin/pppd call %I), call PPPoEIf.remove() to withdraw the FRR default route, and stop the unit. So the resting state destroyed exactly what the promotion path needed, and ppp@pppoe0 restart-looped against the missing file -- 47 restarts observed, zero sessions at the access concentrator -- without ever tripping systemd's limiter, because RestartSec=5s against the default 10s/5-burst window is only two restarts per interval. It also made op-mode `connect interface pppoe0` unusable and put every failover behind a priority-322 commit where one unrelated invalid node fails the whole thing. pppoe0 is now ENABLED on both routers so the peers file always exists, and dialling is gated by ppp@pppoe0.service.d/10-vrrp-wan-gate.conf on /run/vrrp-wan/may-dial, a lease renewed by vrrp-wan-reconcile and revoked by vrrp-wan-guard. /run is tmpfs, so the gate is shut at boot and neither box dials before VRRP has decided. This override encodes must-never-come-back: a re-run of migration/vyos-mode-delta.py or a stale import must not re-pin `disable`. PREREQUISITE: the gate drop-in must already be installed on vyos002, or removing `disable` lets it dial and steal the single ISP session. Proven in labsim across session-control replace/deny/disable; see lab migration/PPPOE-HA.md.", "remove": [["interfaces", "pppoe", "pppoe0", "disable"]] }, { "id": "vrrp-transition-scripts-wan-follows-master", "reason": "Gives the WAN a fast path on top of the 30s reconcile timer. Both hooks exec the same reconciler -- one code path, asked at different moments -- so a lost or duplicated transition cannot desynchronise anything; the timer remains the correctness guarantee and the scripts are only latency. `stop` and `fault` matter as much as `backup`: a stopped keepalived is a demotion too, and without those a box would keep the WAN while holding no VIPs, which is the 2026-09-02 outage shape. They go on the SYNC GROUP because VyOS refuses a per-group script while the group is in a sync group. Do not rely on these alone: on 2026-09-02 keepalived-fifo.py logged NOTHING for a promotion while Keepalived_vrrp logged all six instances entering MASTER, which is precisely why the reconcile timer exists.", "set": [ { "path": ["high-availability", "vrrp", "sync-group", "MAIN", "transition-script", "master"], "value": "/config/vrrp-wan-take" }, { "path": ["high-availability", "vrrp", "sync-group", "MAIN", "transition-script", "backup"], "value": "/config/vrrp-wan-release" }, { "path": ["high-availability", "vrrp", "sync-group", "MAIN", "transition-script", "fault"], "value": "/config/vrrp-wan-release" }, { "path": ["high-availability", "vrrp", "sync-group", "MAIN", "transition-script", "stop"], "value": "/config/vrrp-wan-release" } ] } ] }