diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 32b698e..d16d609 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -1411,6 +1411,13 @@ a container with no global v6, and whether that leg is ROUTABLE is UNVERIFIED** -- not a regression, but the thing the v6 completion work must close. **The v6 completion is DC1's standup scope, folded back to DC0 afterwards, per the operator direction above.** + **CORRECTION, owned: the ruling-note commit was pushed RED-LINT.** `repo-lint | tail -2 &&` + masks the lint's exit code with `tail`'s, so the `&&` proceeded on a FAIL -- the same + silenced-pipeline trap already recorded here (`| grep -q` under pipefail; `git pull -q &&`). + Two defects in that commit, both fixed in the next one: the note used a `### D-NNN --` + heading, which L5 reads as a second DEFINITION of D-101 (collision), and it was appended + after D-136 instead of beside the other D-101 notes. Re-titled to the established + `### RULING NOTE -- D-101:` form and moved to sit after note (a). **memcached SCALED to 3 in `overlays/dc-ha-scaleup.yaml`** (operator-directed 2026-07-31); its exclusion comment is RE-POINTED rather than left stale. **`ceph-rbd-mirror` is PINNED, NOT SETTLED** -- gap register **item 22** carries four options and the recommendation diff --git a/docs/design-decisions.md b/docs/design-decisions.md index 423d2b6..3cdbfa4 100644 --- a/docs/design-decisions.md +++ b/docs/design-decisions.md @@ -2499,6 +2499,59 @@ --- +### RULING NOTE 2026-07-31 (b) -- D-101: `prefer-ipv6` is set on NO application until IPv6 is operational + +**Status:** RULED 2026-07-31 (operator, GA-R5). **OPS under GA-R3** -- it changes no +address-family policy, only which charms receive an option that does not do what R2 assumed. +D-101's matrix is UNAMENDED and every dual-family VIP is retained. + +This SUPERSEDES the emission half of the 2026-07-31 (a) note (the six that never declared the +option). The direction is the same and now covers all thirteen. + +Question as presented: DC0's deploy is blocked -- all SEVEN charms carrying `prefer-ipv6: true` +are in `error` with `Exception: Interface 'eth0' does not have a scope global non-temporary +ipv6 address`. MEASURED cause: `get_relation_ip()` returns early with `get_ipv6_addr()[0]` +when the option is true, and the LXD containers the API charms run in hold ONLY a link-local +v6 (`keystone/0 eth0 -> fe80::216:3eff:feb4:5518/64`) even though the HOSTS are fully +dual-stacked. Options: set it false on the seven and keep every v6 VIP leg; or stop and build +the missing v6 layers on DC0 first. + +**Operator answer, exact utterance: "Set it false on the seven, keep every v6 VIP leg +(Recommended)".** Standing context from the same exchange, verbatim: **"The dual stack was +only a safety net instead of jumping straight into a ipv6 only deployment but it appears that +more items were not configured with IPv6 like they should have been"**, and **"We have DC1 to +stand up with the IPv6 configuration changes. Lets continue with the IPv4/6 stand up on DC0. +We will fold in all lessons learned from the DC0 stand up into the DC1 stand up."** + +**Effect.** No application receives `prefer-ipv6`. Every `vip` stays dual-family; node v6 +statics, the six per-plane host bridges, both-family spaces and the Octavia v6 SANs are all +untouched. IPv6 remains the TARGET -- D-101's own rationale is "v6 wherever possible, v4 only +where forced" -- and v4 is the safety net it was ruled to be. + +**WHY THIS IS NOT ABANDONING v6, stated because it would be easy to read it that way.** The +option is a unit ADDRESS-FAMILY switch, not a listener switch (measured from the charm source +2026-07-31): HAProxy's `:::port` bind is gated on `ipv6_enabled = not is_ipv6_disabled()`, and +pacemaker selects `ocf:heartbeat:IPv6addr` by address-family detection. Neither consults it. + +**HONEST RESIDUAL, recorded not glossed:** pacemaker will place a v6 VIP on a container whose +`eth0` has no global v6. Whether that leg is ROUTABLE is **UNVERIFIED**. It is not a +regression -- it is true today -- but it is precisely what the v6 completion work must close. + +**THE REAL FINDING BEHIND THIS RULING is a "RULED IS NOT BUILT" instance, and it is bigger +than the charm layer.** A systematic dc0 sweep found the v6 half carved as ADDRESSES but never +made OPERATIONAL: all six v6 plane subnets carry ZERO allocatable ip ranges; the rack holds NO +global v6 at all, so the mirror, node-DNS forwarder and MAAS rack agent are v4-only by +construction; the mirror does not answer over v6; and nodes have no v6 default route. Those +are the layers DC1 is to be stood up with, and then folded back to DC0. + +**GATE CONSEQUENCE.** `provider-bundle-check` invariant 9b coupled the option to the v6 legs +for declaring charms; with the option absent and the legs retained it would FAIL. It is +RE-POINTED to the new invariant -- the option must be ABSENT from every application -- and +re-proven able to fail. NOT deleted. When IPv6 becomes operational and the option is +reinstated, 9b returns to its coupling form and this note is the record of why it left. + +--- + ## D-102: IPv6 tenant addressing and MTU sub-policy (VR1) **Status:** MERGED INTO D-101 (2026-07-09, operator ruling). Content below is retained for numbering/history only, per this repo's append-only decision-record discipline -- D-101 is now the current, authoritative text for this sub-policy. Do not amend the body below; amend D-101 instead. @@ -5925,59 +5978,6 @@ --- -### D-101 -- RULING NOTE 2026-07-31 (b): `prefer-ipv6` is set on NO application until IPv6 is operational - -**Status:** RULED 2026-07-31 (operator, GA-R5). **OPS under GA-R3** -- it changes no -address-family policy, only which charms receive an option that does not do what R2 assumed. -D-101's matrix is UNAMENDED and every dual-family VIP is retained. - -This SUPERSEDES the emission half of the 2026-07-31 (a) note (the six that never declared the -option). The direction is the same and now covers all thirteen. - -Question as presented: DC0's deploy is blocked -- all SEVEN charms carrying `prefer-ipv6: true` -are in `error` with `Exception: Interface 'eth0' does not have a scope global non-temporary -ipv6 address`. MEASURED cause: `get_relation_ip()` returns early with `get_ipv6_addr()[0]` -when the option is true, and the LXD containers the API charms run in hold ONLY a link-local -v6 (`keystone/0 eth0 -> fe80::216:3eff:feb4:5518/64`) even though the HOSTS are fully -dual-stacked. Options: set it false on the seven and keep every v6 VIP leg; or stop and build -the missing v6 layers on DC0 first. - -**Operator answer, exact utterance: "Set it false on the seven, keep every v6 VIP leg -(Recommended)".** Standing context from the same exchange, verbatim: **"The dual stack was -only a safety net instead of jumping straight into a ipv6 only deployment but it appears that -more items were not configured with IPv6 like they should have been"**, and **"We have DC1 to -stand up with the IPv6 configuration changes. Lets continue with the IPv4/6 stand up on DC0. -We will fold in all lessons learned from the DC0 stand up into the DC1 stand up."** - -**Effect.** No application receives `prefer-ipv6`. Every `vip` stays dual-family; node v6 -statics, the six per-plane host bridges, both-family spaces and the Octavia v6 SANs are all -untouched. IPv6 remains the TARGET -- D-101's own rationale is "v6 wherever possible, v4 only -where forced" -- and v4 is the safety net it was ruled to be. - -**WHY THIS IS NOT ABANDONING v6, stated because it would be easy to read it that way.** The -option is a unit ADDRESS-FAMILY switch, not a listener switch (measured from the charm source -2026-07-31): HAProxy's `:::port` bind is gated on `ipv6_enabled = not is_ipv6_disabled()`, and -pacemaker selects `ocf:heartbeat:IPv6addr` by address-family detection. Neither consults it. - -**HONEST RESIDUAL, recorded not glossed:** pacemaker will place a v6 VIP on a container whose -`eth0` has no global v6. Whether that leg is ROUTABLE is **UNVERIFIED**. It is not a -regression -- it is true today -- but it is precisely what the v6 completion work must close. - -**THE REAL FINDING BEHIND THIS RULING is a "RULED IS NOT BUILT" instance, and it is bigger -than the charm layer.** A systematic dc0 sweep found the v6 half carved as ADDRESSES but never -made OPERATIONAL: all six v6 plane subnets carry ZERO allocatable ip ranges; the rack holds NO -global v6 at all, so the mirror, node-DNS forwarder and MAAS rack agent are v4-only by -construction; the mirror does not answer over v6; and nodes have no v6 default route. Those -are the layers DC1 is to be stood up with, and then folded back to DC0. - -**GATE CONSEQUENCE.** `provider-bundle-check` invariant 9b coupled the option to the v6 legs -for declaring charms; with the option absent and the legs retained it would FAIL. It is -RE-POINTED to the new invariant -- the option must be ABSENT from every application -- and -re-proven able to fail. NOT deleted. When IPv6 becomes operational and the option is -reinstated, 9b returns to its coupling form and this note is the record of why it left. - ---- - ## D-136: NetBox-coupled per-DC render pipeline for bundle overlays and tfvars [ARCH] **Status:** **ADOPTED 2026-07-27 -- option (D)** (GA-R5). Question as presented: options (A)