#!/usr/bin/env python3 """b8.py — the household's restore buttons, endpoint-level (the same POSTs the backups pages send), B8. b8.py points STACK — the restore points the page offers b8.py unit STACK [SNAPSHOT_ID] — „Visszaállítás" (POST /backup/restore), then the status until done Env: CTL_BASE, CTL_DOMAIN, CTL_PW_ENV.""" import json, os, subprocess, sys, time sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))); import ctl def say(*a): print(time.strftime("%H:%M:%SZ", time.gmtime()), *a, flush=True) def points(stack): c, d = ctl.call("GET", f"/api/backup/snapshots?stack={stack}", timeout=90) data = d.get("data") if isinstance(d, dict) else None return data if isinstance(data, list) else next((data[k] for k in ("snapshots", "items", "restore_points") if isinstance(data, dict) and isinstance(data.get(k), list)), []) def unit(stack, sid=None): pts = points(stack); say("points offered:", json.dumps(pts, ensure_ascii=False)[:500]) sid = sid or (pts[0].get("short_id") or pts[0].get("id")) if ctl._SESS is None: ctl.login() out = subprocess.run(["curl", "-sk", "-D", "-", "-o", "/dev/null", "-H", ctl.HOST, "-H", "Cookie: " + ctl._SESS, "-X", "POST", "--data-urlencode", "_csrf=" + ctl._CSRF, "--data-urlencode", "stack_name=" + stack, "--data-urlencode", "snapshot_id=" + sid, ctl.BASE + "/backup/restore"], capture_output=True, text=True).stdout say("POST /backup/restore", sid, "->", out.splitlines()[0] if out else "?", [l for l in out.splitlines() if l.lower().startswith("location")][:1]) t0, last = time.time(), None while time.time() - t0 < 1800: c, d = ctl.call("GET", "/api/backup/restore-status", timeout=90); dd = (d.get("data") or {}) if isinstance(d, dict) else {} s = json.dumps(dd, ensure_ascii=False)[:700] if s != last: say("status:", s); last = s if not dd.get("running") and time.time() - t0 > 8: break time.sleep(5) c, d = ctl.call("GET", f"/api/stacks/{stack}"); say("app state:", (d.get("data") or {}).get("state")) if __name__ == "__main__": {"points": lambda *a: print(json.dumps(points(*a), ensure_ascii=False, indent=1)), "unit": unit}[sys.argv[1]](*sys.argv[2:])