cluster: stable hostname for mam-api, jq-based smoke test

mam-api self-heartbeat now reads NODE_HOSTNAME so primary rows survive container restarts instead of resurrecting with the random container ID. test-cluster.sh rewritten to use jq (the python f-strings had a parse bug that silently passed the IP check) and limited the docker-bridge alarm to 172.17.x since the user LAN occupies 172.18.0.0/16.
This commit is contained in:
Zac Gaetano 2026-05-21 11:50:52 +00:00
parent 8aa378348e
commit 4a3a672cbe
3 changed files with 14 additions and 17 deletions

View file

@ -72,7 +72,7 @@ nodes = json.load(sys.stdin)
seen = {}
dups = []
for n in nodes:
h = n.get("hostname")
h = n.get('hostname')
if h in seen: dups.append(h)
seen[h] = True
print(",".join(sorted(set(dups))))' 2>/dev/null)
@ -82,16 +82,16 @@ print(",".join(sorted(set(dups))))' 2>/dev/null)
fail "duplicate hostnames: $DUP — run migration 007"
fi
# No private docker IPs
BAD_IPS=$(echo "$NODES_JSON" | python3 -c '
import sys, json, re
docker = re.compile(r"^172\.(1[6-9]|2\d|3[01])\.")
bad = []
for n in json.load(sys.stdin):
ip = n.get("ip_address") or ""
if docker.match(ip):
bad.append(f"{n.get(\"hostname\")}={ip}")
print(",".join(bad))' 2>/dev/null)
# No private docker IPs (172.16.0.0/12 reserved for docker bridges)
BAD_IPS=""
while IFS=$'\t' read -r host ip; do
[[ -z "$ip" ]] && continue
first="${ip%%.*}"; rest="${ip#*.}"; second="${rest%%.*}"
if [[ "$first" == "172" && "$second" == "17" ]]; then
BAD_IPS+="${host}=${ip},"
fi
done < <(echo "$NODES_JSON" | jq -r '.[] | [.hostname, (.ip_address // "")] | @tsv')
BAD_IPS="${BAD_IPS%,}"
if [[ -z "$BAD_IPS" ]]; then
pass "all node IPs are real LAN addresses"
else
@ -162,11 +162,7 @@ BMD_JSON=$(api GET /api/v1/cluster/devices/blackmagic || echo '[]')
BMD_COUNT=$(echo "$BMD_JSON" | python3 -c 'import sys,json; print(len(json.load(sys.stdin)))' 2>/dev/null || echo 0)
if [[ "$BMD_COUNT" -gt 0 ]]; then
pass "$BMD_COUNT DeckLink port(s) registered"
echo "$BMD_JSON" | python3 -c '
import sys, json
for d in json.load(sys.stdin):
print(f" {d.get(\"hostname\")} port={d.get(\"index\")} model={d.get(\"model\") or \"unknown\"} online={d.get(\"online\")}")
'
echo "$BMD_JSON" | jq -r '.[] | " \(.hostname) port=\(.index) model=\(.model // "unknown") online=\(.online)"'
else
warn "no DeckLink devices reported by any node"
fi

View file

@ -48,6 +48,7 @@ services:
AUTH_ENABLED: ${AUTH_ENABLED:-false}
DOCKER_NETWORK: wild-dragon_wild-dragon
NODE_IP: ${NODE_IP}
NODE_HOSTNAME: ${NODE_HOSTNAME:-}
deploy:
resources:
reservations:

View file

@ -163,7 +163,7 @@ async function selfHeartbeat() {
capabilities = EXCLUDED.capabilities,
last_seen = NOW()`,
[
os.hostname(),
process.env.NODE_HOSTNAME || os.hostname(),
getLocalIp(),
process.env.npm_package_version || null,
`http://${getLocalIp()}:${PORT}`,