Newer
Older
openstack-caracal-dc-dc / docs / audit / lp-draft-20260801-ceph-osd-ipv6-static.md

LP draft 2026-08-01 -- charm-ceph-osd, IPv6 static addresses (LP #2061836)

STATUS: DRAFT. The operator files this; Claude does not post to Launchpad. Precedent: docs/audit/lp-draft-20260721-maas-agent-resolver.md.

Target: add a comment to the EXISTING bug LP #2061836 and ask for the charm-ceph-osd task to be closed. Do NOT file a new bug -- the defect is already reported there, the charm-ceph-mon task is Fix Committed (2024-06-14), and only the charm-ceph-osd task remains New and unfixed.

Ruled under D-139 "B plus C" (2026-08-01, operator: "B plus C"): pursue the upstream fix, because it is one word and already merged on the sibling charm.


Suggested comment text

Confirming this is still present in charm-ceph-osd and asking whether the ceph-osd task can be closed the same way the ceph-mon task was.

Measured against the published ceph-osd revision 953 (the current 2024.1/stable artifact), get_ipv6_addr() is still called without dynamic_only=False at two sites:

  • hooks/utils.py:205 -- inside get_host_ip():

    def get_host_ip(hostname=None):
        if config('prefer-ipv6'):
            return get_ipv6_addr()[0]
  • hooks/ceph_hooks.py:547 -- inside the prefer-ipv6 branch that builds the ceph context:

    if config('prefer-ipv6'):
        cephcontext['ms_bind_ipv4'] = False
        cephcontext['ms_bind_ipv6'] = True
        dynamic_ipv6_address = get_ipv6_addr()[0]

The default dynamic_only=True restricts the result to dynamically-assigned (SLAAC/RA) addresses. On a deployment where the provisioning layer assigns static IPv6 addresses -- in our case MAAS assigning a static per node on each of six bound spaces -- there is no dynamic address to find, so the lookup does not return the address the node actually holds.

This matches the original report on this bug, where the reporter noted: "I replaced all the get_ipv6_addr() calls with get_ipv6_addr(dynamic_only=False) ... The machines have a single global static ipv6 address. Everything works correctly."

The equivalent change has already landed on charm-ceph-mon. Is there anything blocking the same one-word change on charm-ceph-osd, or can that task be moved to Fix Committed as well?

Context on why this matters beyond cosmetics. With prefer-ipv6=false the alternative path is also IPv4-only: get_host_ip() falls through to socket.inet_aton(hostname) and then dns.resolver.query(hostname, 'A') (hooks/utils.py:208-217), which cannot resolve an IPv6 literal -- the code's own comment acknowledges this "may throw an NXDOMAIN exception ... just let it kill the hook". So on a genuinely IPv6-only storage/cluster network, both settings of prefer-ipv6 currently fail, in different ways. That second path appears to be what LP #2109798 is reporting.


Notes for the operator, NOT part of the comment

  • Every code claim above was read from the artifact, not from a repo note: the ceph-osd_953.charm was downloaded and hooks/utils.py / hooks/ceph_hooks.py extracted and quoted. Line numbers are from that revision and should be re-checked if a newer revision has published before filing.
  • Do not cite LP #1590598 in support. It is Fix Released and about IPv6-only host interfaces not being bridged into containers -- a different defect. Citing it here would be an inverted citation, which this repo has been bitten by before.
  • This bug is not, by itself, what blocks a v6-only Ceph plane for us. Measured separately: setting the charm's ceph-public-network / ceph-cluster-network options to the v6 CIDRs means the buggy call is never used for address selection, because both assignments are guarded by if not public_network: / if not cluster_network:. The fix is still worth pursuing -- it removes a config-dependent workaround and closes a real defect -- but the local path does not depend on it landing.
  • Filing this is the "C" half of the 2026-08-01 ruling. The "B" half (the storage+replication v6-only experiment) is independent and does not wait on it.