"""restorecase.py — checklist 2.5 on 9202: the per-app backup the guarded Update took (R-648: the only per-app backup press), then REMOVE keeping the backups, the household's restore button (`POST /backup/restore`), and the seed read back through the app's own front door. Evidence: box//restore.txt.""" import json, os, sys, time import walk as w sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts") import upgrade_fixtures_box as fixtures, upgrade_fixtures_box28 as _f28 FX = dict(_f28.FIXTURES28); FX.update(fixtures.FIXTURES) app, sub = sys.argv[1:3] EVD = f"{w.EV}/box/{app}"; os.makedirs(EVD, exist_ok=True) log = open(f"{EVD}/restore.txt", "a", buffering=1) def say(*a): w.say(*a); log.write(" ".join(map(str, a)) + "\n") w.login() toks = json.load(open(w.SC + "/seed-tokens-box.json")) if toks[app].get("__generated"): w.GENERATED[app] = toks[app]["__generated"] say("restore points offered BEFORE the remove:", [(s.get("id") or s.get("snapshot_id"), s.get("time") or s.get("created")) for s in w.snapshots(app)][:5]) w.ctl("POST", f"/api/stacks/{app}/stop") for _ in range(24): time.sleep(5) if w.stack(app).get("state") != "running": break code, d = w.ctl("POST", f"/api/stacks/{app}/remove", {"remove_hdd_data": False, "remove_backups": False}) say(f"remove KEEPING backups -> {code} {str(d)[:240]}") time.sleep(6) say("left after remove:", w.guest(f"docker ps -a --format '{{{{.Names}}}}' | grep -E '^{app}'; docker volume ls -q | grep -i {app}").strip() or "nothing (containers and volumes gone)") r = w.restore(app) say("restore:", {k: r.get(k) for k in ("ok", "snapshot_id", "http", "seconds", "state_after", "hold_after", "why")}) time.sleep(10) say(f"2.5 the seed reads back after remove + restore: {FX[app].verify(w, sub, toks[app], say)}")