Files
Open_Ultra_SAST/src/openultrasast/plane/doctor.py
T

53 lines
2.3 KiB
Python
Raw Normal View History

"""``ousast plane doctor``: four checks of this host's ax before a Run is submitted (ai-service-plane Req 3.5).
A sibling of ``reconciler.py`` (tasks.md task 0 allows either), which re-exports :func:`doctor`.
"""
from __future__ import annotations
import os
import re
import subprocess
UP = "ops/ax/up.sh brings it up"
# --- checks ----------------------------------------------------------------------------------------------
def _sh(*args: str) -> tuple[bool, str]:
try:
proc = subprocess.run(args, capture_output=True, text=True, timeout=60, check=False)
except (OSError, subprocess.TimeoutExpired) as exc:
return False, str(exc)
return proc.returncode == 0, (proc.stdout + proc.stderr).strip()
def _pods_ready(namespace: str, context: str) -> tuple[bool, str]:
ok, out = _sh("kubectl", "--context", context, "-n", namespace, "get", "pods", "--no-headers")
if not ok or not out:
return False, out or "no pods"
rows = [r for r in (line.split() for line in out.splitlines()) if len(r) > 2 and re.fullmatch(r"\d+/\d+", r[1])]
if not rows: # "No resources found" is not a ready namespace
return False, f"no pods in {namespace}"
bad = [r[0] for r in rows if r[2] not in ("Completed", "Succeeded") and r[1].split("/")[0] != r[1].split("/")[1]]
return not bad, f"not ready: {', '.join(bad)}" if bad else f"{len(rows)} pods ready"
def doctor() -> list[tuple[str, bool, str]]:
"""Four checks of the host's ax: kind, Agent Substrate, the ax controller, the runner image (Req 3.5)."""
context = "kind-" + (os.environ.get("KIND_CLUSTER_NAME") or "ousast")
ok, out = _sh("kubectl", "--context", context, "cluster-info")
checks = [("kind cluster", ok, "reachable" if ok else f"context {context} unreachable ({out[:80]}); {UP}")]
for label, ns in (("agent substrate (ate-system)", "ate-system"), ("ax controller (ax-system)", "ax-system")):
ok, out = _pods_ready(ns, context)
checks.append((label, ok, out if ok else f"{out}; {UP}"))
ok, out = _sh("curl", "-s", "localhost:5001/v2/_catalog")
present = ok and "ousast-runner" in out
text = "ousast-runner present" if present else f"missing from localhost:5001 ({out[:80]}); {UP} and loads it"
checks.append(("runner image in kind registry", present, text))
return checks
__all__ = ["doctor"]