From 055069c1f84f4520adfc16b6fd17100d378f4b9f Mon Sep 17 00:00:00 2001 From: chrisfu Date: Sun, 3 May 2026 00:31:43 -0700 Subject: [PATCH] fix(k3d): clean up prole-registry and fix registry running check k3d-prole-registry was squatting on port 5000, leaving k3d-knoe-registry in created state. Two bugs made this invisible: - k3d_registry.py: substring match (name in stdout) matched k3d-knoe-registry as already-exists without checking STATUS=running; add _k3d_registry_running() requiring last column == running, detect and delete prole-registry before creating knoe-registry, recreate if found in non-running state - status_common_services.sh: grep -qx 'knoe-registry' (exact) never matched k3d prefix 'k3d-knoe-registry'; fix with awk suffix match + STATUS==running Co-Authored-By: Claude Sonnet 4.6 --- etc/status_common_services.sh | 4 +++- knoe/core/ops/k3d_registry.py | 32 +++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/etc/status_common_services.sh b/etc/status_common_services.sh index a4169a2..fffa8ca 100755 --- a/etc/status_common_services.sh +++ b/etc/status_common_services.sh @@ -293,7 +293,9 @@ check_deploy_image() { check_k3d_registry() { if command -v k3d >/dev/null 2>&1; then - if k3d registry list --no-headers 2>/dev/null | awk '{print $1}' | grep -qx 'knoe-registry'; then + # k3d prefixes registry container names with "k3d-"; match by suffix and + # require STATUS == running (not just "created"). + if k3d registry list --no-headers 2>/dev/null | awk '$1 ~ /knoe-registry$/ && $NF == "running"' | grep -q .; then echo "[OK] registry/registry exists (k3d: knoe-registry)" return 0 fi diff --git a/knoe/core/ops/k3d_registry.py b/knoe/core/ops/k3d_registry.py index f201ae9..cb5c505 100644 --- a/knoe/core/ops/k3d_registry.py +++ b/knoe/core/ops/k3d_registry.py @@ -15,14 +15,40 @@ from ._services_common import ( ) +def _k3d_registry_running(raw_list: str, name: str) -> bool: + """Return True only if a line whose NAME ends with `name` has STATUS=running.""" + for line in raw_list.splitlines(): + parts = line.split() + if not parts: + continue + # k3d may prefix the name with "k3d-"; match the suffix. + if parts[0].endswith(name) and parts[-1].lower() == "running": + return True + return False + + def _ensure_k3d_registry(*, env: dict | None = None, log: _LogFn | None = None) -> None: name = str((env or {}).get("K3D_REGISTRY_NAME") or "knoe-registry") port = str((env or {}).get("REGISTRY_PORT") or "5000") + legacy_name = "prole-registry" listed = _k3d(["registry", "list"], env=env, timeout=60) - if listed.returncode == 0 and name in listed.stdout: - _log(log, f"[REGISTRY] k3d registry {name} already exists") - return + raw = listed.stdout if listed.returncode == 0 else "" + + # Remove legacy prole-registry that may be squatting on the port. + if legacy_name in raw: + _log(log, f"[REGISTRY] Removing legacy k3d registry {legacy_name}") + _k3d(["registry", "delete", legacy_name], env=env, timeout=60) + listed = _k3d(["registry", "list"], env=env, timeout=60) + raw = listed.stdout if listed.returncode == 0 else "" + + if name in raw: + if _k3d_registry_running(raw, name): + _log(log, f"[REGISTRY] k3d registry {name} already running") + return + # Exists but not running (e.g. "created" — port was unavailable). + _log(log, f"[REGISTRY] k3d registry {name} exists but not running; recreating") + _k3d(["registry", "delete", name], env=env, timeout=60) _log(log, f"[REGISTRY] Creating k3d registry {name} on port {port}") created = _k3d(["registry", "create", name, "--port", f"{port}:{port}"], env=env, timeout=180)