Files
felhom.eu/documentation/audits/catalog-sweep-2026-10-24/tools/putback.py
T
admin 67053335d1
gates / gates (push) Successful in 13m17s
Catalog sweep 2026-10-24: all 65 catalog apps on a fresh box (52 work, 10 with a problem, 0 broken); register 208 -> 217 (R-1269..R-1277 opened; notes on R-739, R-1267); STATUS + D46; map B1 re-checked; evidence
Every catalog app installed, used, backed up, removed keeping data, reinstalled, restored and removed with data on a
fresh box from the public ISO (demo-hp VM 9360, Tester4), endpoint-level. Worst: a reinstall's capture rewrites the
kept unit so its restore breaks the app (R-1269, P2), the restore still reports success (R-1270, P2), and „use my kept
data" loaded another box's future-dated database (R-1271, P2). Drill catalog fixes for the morning list (n8n usage
data; OpenGist 256M, proven by a cgroup probe). VM 9360 and LXC 9361 destroyed; hub host Tester4-aa9466 left for the
operator. REPORT-catalog-sweep-2026-10-24.md.
2026-10-25 00:13:05 +02:00

61 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""putback.py — D22 (the put-back covers every restore) on the sweep box, the 10-21 night's method
(`audits/night-2026-10-21/P3-restore/`): install, seed one item through the front door, „Mentés most", then the FAULT —
the recovery unit's largest volume archive truncated to half (a damaged backup, the only hand-made change) — then the
household's „Visszaállítás" of that unit. Expected: the restore reports failure, the LIVE data and definition are put
back, the app runs, and the item reads back. Then remove with data.
usage: SC=… SWEEP_EV=… DRIVE_ROOT=… python3 putback.py <app> (evidence: <SWEEP_EV>/_putback/<app>/)
"""
import json, os, sys, time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import sweep as sw # noqa: E402
w, fxm = sw.w, sw.fxm
def main(app):
d = os.path.join(sw.EV, "_putback", app)
os.makedirs(d, exist_ok=True)
log = open(os.path.join(d, "walk.log"), "a")
def say(*a):
line = time.strftime("%H:%M:%SZ", time.gmtime()) + " " + " ".join(str(x) for x in a)
print(line, flush=True)
log.write(sw.scrub(line) + "\n")
log.flush()
w.say = say
fx = fxm.FIXTURES[app]
sub = getattr(fx, "sub", app)
rec = {"app": app}
w.login()
try:
rec["install"] = w.deploy(app, sub) and w.wait_app(sub, "/", tries=90, delay=5)
tok = fx.seed(w, sub, say)
rec["seed"] = bool(tok)
sw.backup_now(rec, say)
units = sw.g(f"ls -la --time-style=+%T /mnt/sys_drive/felhom-data/backups/primary/{app}/volume-dumps/ 2>&1")
say(" unit before the fault:\n" + units)
big = sw.g(f"ls -S /mnt/sys_drive/felhom-data/backups/primary/{app}/volume-dumps/*.tar 2>/dev/null | head -1").strip()
size = sw.g(f"stat -c %s {big}").strip()
sw.g(f"truncate -s $(( {size} / 2 )) {big}")
after = sw.g(f"stat -c %s {big}").strip()
say(f" THE FAULT: {big} {size} -> {after}")
rec["fault"] = {"file": big, "from": size, "to": after}
sw.restore_unit(app, rec, say)
rec["state_after"] = w.stack(app).get("state")
rec["item_after"] = bool(tok) and bool(fx.verify(w, sub, tok, say))
rec["controller_log"] = sw.g("docker logs --since 10m felhom-controller 2>&1 | grep -iE 'put back|R-893|restore failed|put-back' | tail -5")
say(" controller: " + rec["controller_log"].strip()[:600])
finally:
sw.remove(app, keep=False, say=say)
rec["after_remove"] = sw.leftovers(app, sub)
json.dump(rec, open(os.path.join(d, "record.json"), "w"), ensure_ascii=False, indent=1)
say(" == putback " + json.dumps({k: rec.get(k) for k in ("seed", "state_after", "item_after")}))
if __name__ == "__main__":
main(sys.argv[1])