Files
lab/migration/pulumi-override-pppoe-gated.json
Michal 9221c71ff0
Some checks failed
CI/CD / lint (push) Failing after 10s
CI/CD / test (push) Failing after 9s
CI/CD / typecheck (push) Failing after 24s
CI/CD / build (push) Has been skipped
CI/CD / publish-rpm (push) Has been skipped
CI/CD / publish-deb (push) Has been skipped
labsim: the session-control matrix was never setting session-control
T4 prints "--- session-control=deny ---" and then measures whatever policy the
AC already had. The setter was

  isp "vbash -c 'source script-template; configure; set ...; commit; save'"

and that form does not start a config session at all -- commit dies with
"Invalid command: [commit]" on stderr, which isp() discards. `show
configuration commands | grep session-control` on the ISP VM returned nothing
after a full matrix run: all three iterations had run against the accel-ppp
default. The labels were fiction, and a harness that reports coverage it does
not have is worse than one that reports a failure.

Driving it from a real script FILE works. isp_session_control() does that,
reads the value back, and fails the iteration if it disagrees rather than
measuring the wrong policy. `session-control` is a valid node here (checked
the template dir on VyOS 2026.08.12-0831-rolling), so this was purely the
invocation.

Staged the two Pulumi overrides in migration/ rather than adding them to
kubernetes-deployment: another agent runs `pulumi up` on that repo, so merging
`remove: pppoe0 disable` before the gate exists on vyos002 would let it dial
and take the single Vodafone session off the live master. Ordering is written
at the top of the file.
2026-09-06 00:15:45 +01:00

56 lines
4.5 KiB
JSON

{
"_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"
}
]
}
]
}