88aecf55b6
gates / gates (push) Successful in 7m23s
Live on demo-hp (--rotate-recovery-only): vault time moved, new value 200, old 401. Harness 52/0; the R1145 cases fail against HEAD. Publishes only with the next installer tag.
48 lines
2.2 KiB
Python
48 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""hostinstall_harness_gate.py — runs scripts/hostinstall-mode-harness.sh as a gate (R-1146, 2026-10-18).
|
|
|
|
WHY. The harness (bash -n, shellcheck, the argument-refusal matrix, the mode invariants, the --rotate-recovery-only cases
|
|
R1141-*, and the vault-first order R1145-*) was RED on `main` for weeks — SC2066 and a stale GL8-F6 check — because no
|
|
gate ran it: `repo_gates.py` ran only `hostinstall_gates.py`. The R-29 shape. It is fast (no network: its hub is a closed
|
|
port; no container; its PVE tier skips itself off a PVE host), so it runs in `--fast` and in the pre-push hook.
|
|
|
|
THE CI RUNNER HAS NO bash (python3 and git only, `.gitea/workflows/gates.yml`). There the gate says so and exits 0 — the
|
|
same out-loud skip as check-onboarding.py's absent sibling — and the pre-push hook on DooPlex is where it bites.
|
|
Exit 0 harness green (or no bash, said) · 1 a harness case failed.
|
|
"""
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
HARNESS = os.path.join(ROOT, "scripts", "hostinstall-mode-harness.sh")
|
|
|
|
|
|
def main():
|
|
if not os.path.isfile(HARNESS):
|
|
print("hostinstall-harness: FAIL — %s is missing" % HARNESS)
|
|
return 1
|
|
bash = shutil.which("bash")
|
|
if not bash:
|
|
print("hostinstall-harness: NOT CHECKED here — no bash on this runner; the pre-push hook on DooPlex runs it")
|
|
return 0
|
|
p = subprocess.run([bash, HARNESS, os.path.join(ROOT, "scripts", "felhom-host-install.sh")], cwd=ROOT,
|
|
capture_output=True, text=True, errors="replace")
|
|
out = p.stdout + p.stderr
|
|
fails = [l for l in out.splitlines() if l.startswith("FAIL ")]
|
|
tail = [l for l in out.splitlines() if l.startswith("=== ") and "passed" in l]
|
|
for l in fails:
|
|
print(" " + l)
|
|
print("hostinstall-harness: %s" % (tail[-1] if tail else "(no summary line)"))
|
|
if p.returncode != 0 or fails or not tail:
|
|
print("hostinstall-harness: CONVICTED (rc=%d, %d failing case(s))" % (p.returncode, len(fails)))
|
|
return 1
|
|
print("hostinstall-harness OK")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|