Files
felhom.eu/documentation/audits/ladder-2026-09-24/tools/liveC660.py
T

30 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""R-660 positive control: a throwaway app (actualbudget) stopped OUT OF BAND must raise app_start_failed
while the held nextcloud (held since 06:27:40Z) must not. Then the throwaway is removed through the product."""
import json, sys, time
sys.path.insert(0, ".")
import walk as w
w.login()
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
ok = w.deploy("actualbudget", "budget-c660")
w.wait_app("budget-c660", "/", tries=40, delay=3)
w.say("stopping the throwaway's container out of band (not through the product): " + w.guest("docker stop actualbudget 2>&1").strip())
found = None
for i in range(24):
time.sleep(10)
c, d = w.ctl("GET", "/api/debug/logs?level=DEBUG&lines=6000")
ents = ((d.get("data") or {}).get("entries") or []) if isinstance(d, dict) else []
evs = [e["timestamp"] + " " + e["message"] for e in ents if e.get("timestamp", "") >= t0 and
("app_start_failed" in e.get("message", "") or "currently down" in e.get("message", ""))]
if any("app_start_failed" in x for x in evs):
found = evs
break
w.say("events/heartbeats since the control started:\n " + "\n ".join(found or evs))
names = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -iE 'app_start_failed|not running|DeadApp|nem fut' | tail -8")
w.say("controller log lines:\n" + names)
st = w.stack("nextcloud")
w.say(f"nextcloud meanwhile: state={st.get('state')} held={bool(st.get('hold_reason'))}")
w.remove("actualbudget")
json.dump({"events": found or evs, "log": names, "nextcloud_state": st.get("state")}, open("../partB/03-r660-control.json", "w"), indent=2)
open("../partB/03-r660-control.log", "w").write("\n".join(w.LOG) + "\n")