diff --git a/docs/charm-ip-family-compatibility.md b/docs/charm-ip-family-compatibility.md new file mode 100644 index 0000000..909f38d --- /dev/null +++ b/docs/charm-ip-family-compatibility.md @@ -0,0 +1,98 @@ +# Charm IPv4 / IPv6 compatibility reference (VR1 bundle, Caracal 2024.1) + +Created 2026-08-03 at operator request as a durable reference. Built from the repo's own +MEASURED research, not from general knowledge -- every IPv6 verdict cites its source. Where +the repo has NOT assessed a charm's IPv6 behaviour, the cell says **NOT ASSESSED** rather +than guessing (fabricating a compatibility claim is the cardinal sin, CLAUDE.md posture). + +Scope: the 33 distinct charms in `bundle.yaml` (56 applications; `hacluster` x12 and +`mysql-router` x12 are subordinate instances of one charm each). + +--- + +## READ THIS FIRST -- v6 is blocked at TWO independent layers + +A charm being "IPv6-capable" does not make the deployed cloud v6. Two separate things block +it, and they are at different layers: + +1. **JUJU CONTAINER ADDRESSING (charm-independent).** Juju's MAAS/LXD provider assigns each + container ONE address per NIC, family-blind, and lands v4 -- so API-charm containers get + NO global v6 address at all. **LP #1723240, `Triaged`/Low, open since 2017, NOT fixed in + juju 3.6 LTS or 4.0** (release notes checked 2026-08-03: no address-model change). This + alone blocks EVERY v6 VIP today, regardless of charm. Measured here: keystone, ceph-mon + and vault containers all hold zero global v6. +2. **PER-CHARM DEFECTS.** Even once a container HAS v6, the charms below marked "No"/"Partial" + have their own v6 gaps that would still bite. + +**IPv4 is the proven base for every charm** -- the entire cloud was built and verified on v4 +across VR0 and VR1, so the IPv4 column is "Full" throughout by deployment evidence. + +**Legend (IPv6 column):** +- **Capable** -- the charm code handles v6 correctly; the only thing stopping it is layer 1 (juju). +- **Partial** -- works in some paths / a fix has partly landed; caveats in Evidence. +- **No** -- the charm itself breaks on v6 at current pinned revision. +- **NOT ASSESSED** -- the repo has not measured this charm for v6; do not assume either way. +- **n/a** -- no VIP / not on a v6-relevant path. + +--- + +## Table + +| Charm | Inst. | IPv4 | IPv6 | Evidence (source) | +|---|---|---|---|---| +| barbican | 1 | Full | Capable | Frontend HAProxy binds v6 when `ipv6_enabled` (kernel sysctl, =0 on nodes); charms.openstack family. Blocked only by juju addressing. `stage5-prefer-ipv6-charm-research-20260731.txt` F1 | +| cinder | 1 | Full | Capable | charmhelpers HAProxy family, same as barbican. Same research | +| designate | 1 | Full | Capable | charms.openstack family. Same research | +| glance | 1 | Full | Capable | charmhelpers family. Same research | +| keystone | 1 | Full | Capable | charmhelpers family; MEASURED live 2026-08-03 -- v4 VIPs accepted, v6 VIPs rejected ONLY because container has no global v6 (`Invalid vips`), not a charm defect | +| magnum | 1 | Full | Capable | charms.openstack family. Same research | +| neutron-api | 1 | Full | Capable | charmhelpers family. Same research | +| nova-cloud-controller | 1 | Full | Capable | charmhelpers family. Same research | +| octavia | 1 | Full | Capable | charms.openstack family. Same research | +| openstack-dashboard | 1 | Full | Capable | charmhelpers family. Same research | +| placement | 1 | Full | Capable | charms.openstack family. Same research | +| hacluster | 12 | Full | **No** | Hard-writes `ip_version: ipv4` in `templates/corosync.conf`, 2.4/stable rev 166 (2026-06-29). **LP #2111852 `Fix Committed` but NOT RELEASED.** `CURRENT-STATE.md:2498-2500`. This is the VIP-manager itself -- it gates every API charm's HA VIP | +| mysql-innodb-cluster | 1 | Full | **No** | Builds bare `user:pw@addr` DB URIs invalid for a v6 literal without brackets. `CURRENT-STATE.md:2496-2498` | +| mysql-router | 12 | Full | **No** | Same bare-URI defect as mysql-innodb-cluster (x12 subordinate). Same source | +| ceph-osd | 1 | Full | **No** | Breaks on a v6-only plane BOTH ways: `prefer-ipv6:false` -> `inet_aton` then IPv4-only `IN A` lookup (**LP #2109798**, New); `true` -> bare `get_ipv6_addr()` returns only SLAAC, but VR1 nodes hold MAAS STATIC v6 (**LP #2061836**, New on ceph-osd). MEASURED here, rev 953. `CURRENT-STATE.md:2480-2489` | +| ceph-mon | 1 | Full | Partial | **LP #2061836 `Fix Committed` on charm-ceph-mon 2024-06-14** (the `get_ipv6_addr` half). The `inet_aton` half (LP #2109798) may still apply; ceph-mon not independently re-measured here -- verdict inferred from the LP, not from a live run | +| ovn-central | 1 | Full | **No** (data plane) | OVN documents the encap column as *"The IPv4 address of the encapsulation tunnel endpoint"* (`ovn-sb.xml:565`); every `ovn-encap-ip` in OVN 24.03's test suite is IPv4. `CURRENT-STATE.md:2501-2503`. Reported from capture, not independently re-verified | +| ovn-chassis | 2 | Full | **No** (data plane) | Same OVN encap IPv4-only constraint (ovn-chassis + ovn-chassis-octavia). Same source. NOTE: the `bridge-interface-mappings` / provider egress path is v4/v6-agnostic (MAC-based) and works | +| neutron-api-plugin-ovn | 1 | Full | NOT ASSESSED | Subordinate to neutron-api; its own v6 behaviour not separately measured. The OVN data-plane constraint above governs the encap, not this plugin's API path | +| ceph-radosgw | 1 | Full | NOT ASSESSED | Has a hacluster VIP (so inherits the hacluster "No" for its VIP), but the radosgw charm's own v6 handling was not measured | +| barbican-vault | 1 | Full | NOT ASSESSED | Subordinate; not measured for v6 | +| ceph-rbd-mirror | 1 | Full | NOT ASSESSED | Cross-DC replication charm; not measured for v6 | +| cinder-backup | 1 | Full | NOT ASSESSED | Subordinate; not measured for v6 | +| cinder-ceph | 1 | Full | NOT ASSESSED | Subordinate; not measured for v6 | +| designate-bind | 1 | Full | NOT ASSESSED | DNS backend; not measured for v6 | +| glance-simplestreams-sync | 1 | Full | NOT ASSESSED | Not measured for v6 | +| magnum-dashboard | 1 | Full | NOT ASSESSED | Horizon plugin; not measured for v6 | +| memcached | 1 | Full | NOT ASSESSED | Not measured for v6 | +| nova-compute | 1 | Full | NOT ASSESSED | Runs on the metal node (not a container), so the juju container-addressing blocker does not apply to it; its own v6 handling not measured | +| octavia-dashboard | 1 | Full | NOT ASSESSED | Horizon plugin; not measured for v6 | +| octavia-diskimage-retrofit | 1 | Full | n/a | Image-build helper; no VIP / not on a v6 network path | +| rabbitmq-server | 1 | Full | NOT ASSESSED | Messaging; not measured for v6 | +| vault | 1 | Full | NOT ASSESSED | Container measured to have no global v6 (layer-1 blocker applies); the vault charm's own v6 handling not separately assessed | + +--- + +## Bottom line for the revert-to-IPv4 decision + +- **Nothing about IPv4 was lost.** The current VIP overlay is DUAL-STACK -- every `vip:` line + carries the v4 triple AND the v6 triple (e.g. `10.12.4.50 10.12.8.50 10.12.12.50 2602:...`). + The v4 legs are live and already ACCEPTED by the charms; only the v6 legs are rejected. + "Back to IPv4" = drop the v6 legs from `render/values/vr1-dc0-vips.yaml` and re-render; the + working v4 config stays. Also recoverable from git at the parent of `a9e3258` (the D-139 GUA + move) and reconstructable from `scripts/lib-net.sh` + (`VIP_PREFIX_PROVIDER/ADMIN/INTERNAL = 10.12.4/8/12`). +- **The v6 work on the NODE PLANES is NOT wasted and should stay** -- node-to-node v6 is proven + (D-139, gate G19), and the node planes are dual-stack. What reverts is the VIP FAMILY on the + container-hosted API charms, not the node addressing. +- **Even a juju fix would not make this all-green today** -- hacluster, mysql, ceph-osd and OVN + each carry their own v6 defect above, three of them tracked as open/unreleased Launchpad bugs. + +## Maintenance + +Update a row only from a MEASURED source and cite it. When a Launchpad bug changes state, +update the cell AND the citation. Promote a **NOT ASSESSED** to a verdict only after a real +measurement (charm artifact read or live run), never from a general expectation.