87 lines
2.7 KiB
Bash
87 lines
2.7 KiB
Bash
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
BASE_URL="${AIOS_V2_BASE_URL:-http://127.0.0.1:18920}"
|
|
STATE_DIR="${AIOS_V2_STATE_DIR:-/var/lib/aios-v2}"
|
|
CONTROLLER_WT="${AIOS_GITOPS_CONTROLLER_WORKTREE:-/data/aios-gitops/worktrees/controller}"
|
|
SERVICE="${AIOS_V2_SERVICE:-aios-v2}"
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
pass() {
|
|
echo "PASS: $*"
|
|
}
|
|
|
|
command -v python3 >/dev/null || fail "python3 not installed"
|
|
|
|
if command -v systemctl >/dev/null && systemctl list-unit-files "$SERVICE.service" >/dev/null 2>&1; then
|
|
systemctl is-active --quiet "$SERVICE" || fail "$SERVICE is not active"
|
|
pass "$SERVICE is active"
|
|
fi
|
|
|
|
python3 - "$BASE_URL" <<'PY'
|
|
import json
|
|
import sys
|
|
import urllib.request
|
|
|
|
base_url = sys.argv[1].rstrip("/")
|
|
with urllib.request.urlopen(f"{base_url}/api/v2/health", timeout=5) as response:
|
|
payload = json.loads(response.read().decode("utf-8"))
|
|
if payload.get("status") not in {"ok", "healthy", "ready"}:
|
|
raise SystemExit(f"unexpected health payload: {payload}")
|
|
print(f"PASS: HTTP health status={payload.get('status')}")
|
|
PY
|
|
|
|
[[ -d "$STATE_DIR" ]] || fail "state directory missing: $STATE_DIR"
|
|
[[ -w "$STATE_DIR" ]] || fail "state directory not writable: $STATE_DIR"
|
|
pass "state directory writable"
|
|
|
|
if [[ -e "$STATE_DIR/control-plane.sqlite3" ]]; then
|
|
python3 - "$STATE_DIR/control-plane.sqlite3" <<'PY'
|
|
import sqlite3
|
|
import sys
|
|
|
|
path = sys.argv[1]
|
|
connection = sqlite3.connect(f"file:{path}?mode=ro", uri=True, timeout=5)
|
|
try:
|
|
row = connection.execute("PRAGMA quick_check").fetchone()
|
|
finally:
|
|
connection.close()
|
|
if not row or row[0] != "ok":
|
|
raise SystemExit(f"SQLite quick_check failed: {row}")
|
|
print("PASS: SQLite quick_check=ok")
|
|
PY
|
|
else
|
|
echo "WARN: control-plane.sqlite3 not created yet"
|
|
fi
|
|
|
|
if [[ -d "$CONTROLLER_WT" ]] && git -C "$CONTROLLER_WT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
branch="$(git -C "$CONTROLLER_WT" branch --show-current)"
|
|
dirty="$(git -C "$CONTROLLER_WT" status --porcelain=v1)"
|
|
[[ -z "$branch" ]] || fail "GitOps controller attached to branch: $branch"
|
|
[[ -z "$dirty" ]] || fail "GitOps controller workspace is dirty"
|
|
pass "GitOps controller detached and clean"
|
|
fi
|
|
|
|
python3 - "$STATE_DIR/executions" <<'PY'
|
|
import json
|
|
import pathlib
|
|
import sys
|
|
|
|
root = pathlib.Path(sys.argv[1])
|
|
if not root.exists():
|
|
print("WARN: execution evidence directory not created yet")
|
|
raise SystemExit(0)
|
|
for path in root.glob("*/*.json"):
|
|
value = json.loads(path.read_text(encoding="utf-8"))
|
|
for key in ("execution_id", "tenant_id", "task_id", "executor", "status"):
|
|
if not value.get(key):
|
|
raise SystemExit(f"invalid execution evidence {path}: missing {key}")
|
|
print("PASS: execution evidence files valid")
|
|
PY
|
|
|
|
pass "AIOS V2 candidate healthcheck complete"
|