Files
felhom.eu/documentation/audits/release-monday-2026-10-26/tools/later_probe.py
T

46 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""later_probe.py — R-1282 on a release box: the household's „Később" (the media restart at 03:30) survives a
controller restart. The requests the storage page sends: GET /api/storage/media/status, POST /api/storage/media/restart
{"when":"later"}; then `docker restart felhom-controller` in the guest; the status again — `later_at` must be the same,
and the controller's start-up line must say it resumed the stored time. No secret is printed.
usage: SC=<dir with .ctlpw> SWEEP_EV=<evidence dir> TARGET=tester-1 python3 later_probe.py"""
import json, os, sys, time
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../catalog-sweep-2026-10-24/tools"))
import sweep as sw # noqa: E402
w = sw.w
def status():
code, body = w.ctl("GET", "/api/storage/media/status", raw=True)
try:
d = json.loads(body).get("data") or {}
except ValueError:
d = {}
return code, d.get("later_at", "")
def main():
w.login()
print("1. status before ->", status())
code, body = w.ctl("POST", "/api/storage/media/restart", {"when": "later"}, raw=True)
print("2. POST „Később\" ->", code, body[:160])
before = status()
print("3. status after Később ->", before)
t = int(time.time())
print("4. docker restart felhom-controller ->", sw.g("docker restart felhom-controller >/dev/null && echo restarted").strip())
for _ in range(40):
time.sleep(5)
if "healthy" in sw.g("docker ps --filter name=felhom-controller --format '{{.Status}}'") and \
"starting" not in sw.g("docker ps --filter name=felhom-controller --format '{{.Status}}'"):
break
after = status()
print("5. status after restart ->", after)
print("6. start-up lines ->", sw.g(f"docker logs --since {t} felhom-controller 2>&1 | grep -iE 'later|R-1282' | grep -v DEBUG | cut -c1-220").strip())
print("VERDICT:", "KEPT" if before[1] and before[1] == after[1] else "LOST")
if __name__ == "__main__":
main()