mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
fix(cnpg/k3d): skip reinitialize when cluster already healthy
install_barman_plugin() fetches from GitHub on every run (up to 6×120 s retries), stalling the installer worker thread even when the CNPG cluster is already at 'Cluster in healthy state' with all pods 2/2 Ready. Add a fast-path at the top of initialize(): check .status.phase for 'healthy' then verify all pods show 2/N ready — if both pass, return immediately. Full pipeline (ensure_operator, install_barman_plugin, _apply_manifest, _wait_cnpg_pods) is only entered when needed. Also adds test_cnpg_initialize_skips_when_cluster_healthy to test_deployment_mode_isolation.py to guard against regression. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5295e47753
commit
2f98a5afd2
@ -1823,6 +1823,28 @@ def initialize(
|
|||||||
"""
|
"""
|
||||||
_log(log, f"Initializing CNPG cluster '{cluster_name}' in namespace '{namespace}'...")
|
_log(log, f"Initializing CNPG cluster '{cluster_name}' in namespace '{namespace}'...")
|
||||||
|
|
||||||
|
# Fast-path: if cluster already healthy and all pods Ready, skip the full pipeline.
|
||||||
|
# install_barman_plugin() fetches from GitHub (up to 6 × 120 s attempts) — pure waste
|
||||||
|
# when the cluster is already running. We check phase then pod readiness.
|
||||||
|
_phase_r = _kubectl(
|
||||||
|
["-n", namespace, "get", "cluster", cluster_name, "-o", "jsonpath={.status.phase}"],
|
||||||
|
env=env, timeout=15,
|
||||||
|
)
|
||||||
|
if _phase_r.returncode == 0 and "healthy" in (_phase_r.stdout or "").lower():
|
||||||
|
_pods_r = _kubectl(
|
||||||
|
["-n", namespace, "get", "pods", "--no-headers",
|
||||||
|
"-l", f"cnpg.io/cluster={cluster_name}"],
|
||||||
|
env=env, timeout=20,
|
||||||
|
)
|
||||||
|
_pod_lines = [ln for ln in (_pods_r.stdout or "").splitlines() if ln.strip()]
|
||||||
|
_not_ready = [
|
||||||
|
ln for ln in _pod_lines
|
||||||
|
if len(ln.split()) < 2 or not ln.split()[1].startswith("2/")
|
||||||
|
]
|
||||||
|
if _pod_lines and not _not_ready:
|
||||||
|
_log(log, f"[CNPG] Cluster '{cluster_name}' already healthy with all pods Ready — skipping reinitialize")
|
||||||
|
return
|
||||||
|
|
||||||
_log(log, "[CNPG] Ensuring operator is installed and healthy...")
|
_log(log, "[CNPG] Ensuring operator is installed and healthy...")
|
||||||
ensure_operator(
|
ensure_operator(
|
||||||
env=env,
|
env=env,
|
||||||
|
|||||||
@ -125,6 +125,45 @@ def test_port_forward_argocd_excluded_when_disabled():
|
|||||||
assert "dashboard" not in ids, "dashboard must be excluded when dashboard_enabled=False"
|
assert "dashboard" not in ids, "dashboard must be excluded when dashboard_enabled=False"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 7f — CNPG initialize() fast-path: skip when cluster already healthy
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_cnpg_initialize_skips_when_cluster_healthy(monkeypatch):
|
||||||
|
"""Regression: initialize() must return immediately when the cluster is healthy.
|
||||||
|
|
||||||
|
Formerly it always ran install_barman_plugin() which fetches from GitHub
|
||||||
|
(up to 6 × 120 s), stalling the installer even when CNPG was already running.
|
||||||
|
"""
|
||||||
|
import types
|
||||||
|
from knoe.core.ops import cloudnative_pg as cnpg
|
||||||
|
|
||||||
|
calls: list[str] = []
|
||||||
|
|
||||||
|
def _fake_kubectl(args, env=None, timeout=None):
|
||||||
|
cmd = " ".join(str(a) for a in args)
|
||||||
|
calls.append(cmd)
|
||||||
|
result = types.SimpleNamespace(returncode=0, stdout="", stderr="")
|
||||||
|
if "jsonpath={.status.phase}" in cmd:
|
||||||
|
result.stdout = "Cluster in healthy state"
|
||||||
|
elif "get pods" in cmd:
|
||||||
|
result.stdout = "knoe-db-1 2/2 Running 0 5d\nknoe-db-2 2/2 Running 0 5d\n"
|
||||||
|
return result
|
||||||
|
|
||||||
|
monkeypatch.setattr(cnpg, "_kubectl", _fake_kubectl)
|
||||||
|
|
||||||
|
logged: list[str] = []
|
||||||
|
cnpg.initialize("knoe-db", "knoe-db", log=lambda msg: logged.append(msg))
|
||||||
|
|
||||||
|
assert any("skipping reinitialize" in m for m in logged), (
|
||||||
|
"Expected fast-path log message not found"
|
||||||
|
)
|
||||||
|
# ensure_operator / install_barman_plugin / _apply_manifest must NOT be called
|
||||||
|
assert not any("apply" in c and "barman" in c.lower() for c in calls), (
|
||||||
|
"install_barman_plugin must not be called when cluster is already healthy"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_port_forward_grafana_uses_monitoring_release():
|
def test_port_forward_grafana_uses_monitoring_release():
|
||||||
from knoe.core.env import _build_required_port_forwards
|
from knoe.core.env import _build_required_port_forwards
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user