diff --git a/scripts/lib-hosts.sh b/scripts/lib-hosts.sh index 46dbba5..f75f0a9 100644 --- a/scripts/lib-hosts.sh +++ b/scripts/lib-hosts.sh @@ -64,6 +64,23 @@ # lands on br-ex, and the member NIC itself carries no L3 link. BREX_PARENT_NIC="enp2s0" +# THE CARVE IS NOT UNIFORM ACROSS ROLES -- measured 2026-07-30 from the +# pre-migration capture, and assuming uniformity would mis-carve the controller. +# ROLE NODES (the 9 openstack- machines): ALL SIX planes carved, plus an +# OVS br-ex bridge parented on enp2s0 carrying the provider-public static. +# enp2s0 itself holds NO L3 link. +# JUJU CONTROLLER (-juju-01): only TWO planes -- enp1s0 metal-admin and +# enp2s0 provider-public (raw NIC, WITH the gateway). NO br-ex, and +# enp3s0..enp6s0 are deliberately LEFT on their auto-created VLANs. It runs +# no workloads, so it needs no tenant/storage/replication legs; it needs a +# default route, which is what the provider-public leg with a gateway gives +# it (the under-carve that cost three bootstrap attempts on 2026-07-30). +# Evidence: capture rows for 7n87bt (controller, enp3-6 on vlans 5200-5203 = +# auto) versus 8mtpxq (storage-02, enp3-6 on 5190-5193 = named planes + br-ex). +NODE_CARVE_ROLE_PLANES=6 # role nodes: every plane +NODE_CARVE_JUJU_PLANES=2 # controller: metal-admin + provider-public only +JUJU_HOST_SUFFIX="juju-01" # how the controller is identified in HOSTS + # The per-region forms exist only for the VR1 DCs (D-132 q1). Declared EMPTY at # the flat/VR0 layer so a shell that never selects a VR1 DC cannot pick up a # neighbouring DC's address -- an empty value fails loud; a stale one powers off diff --git a/tests/dc-selector/run-tests.sh b/tests/dc-selector/run-tests.sh index 2ac5d5e..a6b3fd0 100644 --- a/tests/dc-selector/run-tests.sh +++ b/tests/dc-selector/run-tests.sh @@ -272,6 +272,28 @@ [ "$NIC0" != "$PC0" ] && ok "nic order DIFFERS from PLANE_CIDRS order at [0] (the enp1s0/enp2s0 trap)" \ || no "nic order DIFFERS from PLANE_CIDRS order at [0] -- both read '$NIC0', so the trap guard is vacuous" +# --- CARVE IS ROLE-DEPENDENT (measured 2026-07-30) ------------------------- +# Role nodes get all six planes + an OVS br-ex on enp2s0; the juju controller +# gets metal-admin + provider-public (raw, with gateway) and NOTHING else. +# Assuming uniformity would either strand the controller without a default route +# or give it four legs it must not have. +chk "role nodes carve six planes" "$NODE_CARVE_ROLE_PLANES" "6" +chk "juju controller carves only two planes" "$NODE_CARVE_JUJU_PLANES" "2" +chk "juju host suffix identifies the controller" "$JUJU_HOST_SUFFIX" "juju-01" +[ "$NODE_CARVE_ROLE_PLANES" != "$NODE_CARVE_JUJU_PLANES" ] \ + && ok "role and controller carve depths DIFFER (the uniformity trap)" \ + || no "role and controller carve depths DIFFER -- both read '$NODE_CARVE_ROLE_PLANES', guard is vacuous" +# The controller must be present in each VR1 DC's HOSTS under that suffix. +# Checked INSIDE a per-DC subshell: the main shell still holds the flat VR0 +# defaults, so testing it at top level would assert against the wrong fleet. +for _dc in vr1-dc0 vr1-dc1; do + _JF="$(lib_hosts_select_dc "$_dc" >/dev/null 2>&1; f=0; for h in "${HOSTS[@]}"; do case "$h" in *"$JUJU_HOST_SUFFIX") f=1 ;; esac; done; echo "$f")" + chk "$_dc HOSTS contains a *-$JUJU_HOST_SUFFIX controller" "$_JF" "1" +done +# and VR0 must NOT -- it has no dedicated juju controller node +_V0="$(lib_hosts_select_dc vr0-dc0 >/dev/null 2>&1; f=0; for h in "${HOSTS[@]}"; do case "$h" in *"$JUJU_HOST_SUFFIX") f=1 ;; esac; done; echo "$f")" +chk "vr0-dc0 HOSTS has NO juju-controller node (D-104 is VR1-only)" "$_V0" "0" + # --- ONE SELECTION PER SHELL (stale cross-DC guard, lib-net precedent) --- ( lib_hosts_select_dc vr1-dc0 >/dev/null 2>&1; lib_hosts_select_dc vr1-dc1 2>/dev/null ); \ chk "hosts dc0->dc1 re-select REFUSED (stale cross-DC values)" "$?" 1