a7971c4822
gates / gates (push) Successful in 25s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
36 lines
1.7 KiB
Python
36 lines
1.7 KiB
Python
"""A4: ONE whole-box backup of demo-hp 9201 by the product's own trigger (POST /api/guest-backup/trigger),
|
|
polled through /api/guest-backup/status, with the host root disk sampled. Evidence, not product."""
|
|
import json, time, subprocess, os
|
|
os.environ.setdefault("GUEST", "9201")
|
|
import walk as w
|
|
OUT = w.EV + "/A/A4-hp-backup-run.txt"
|
|
def host(cmd):
|
|
return subprocess.run(["ssh", "hp", "export LC_ALL=C; " + cmd], capture_output=True, text=True, timeout=120).stdout.strip()
|
|
lines = []
|
|
def say(s):
|
|
s = time.strftime("%H:%M:%S ") + s
|
|
print(s, flush=True); lines.append(s); open(OUT, "w").write("\n".join(lines) + "\n")
|
|
w.login()
|
|
say("root before: " + host("df -B1 / | tail -1"))
|
|
c, d = w.ctl("POST", "/api/guest-backup/trigger")
|
|
say(f"POST /api/guest-backup/trigger -> {c} {json.dumps(d, ensure_ascii=False)[:300]}")
|
|
peak = 0
|
|
t0 = time.time()
|
|
while time.time() - t0 < 3600:
|
|
time.sleep(20)
|
|
c, d = w.ctl("GET", "/api/guest-backup/status")
|
|
used = int(host("df -B1 / | tail -1 | awk '{print $3}'") or 0)
|
|
peak = max(peak, used)
|
|
st = json.dumps(d, ensure_ascii=False)[:400]
|
|
say(f"status {c}: {st} | root used {used}")
|
|
dd = (d or {}).get("data") or {}
|
|
if isinstance(dd, dict) and not dd.get("running", dd.get("active", True)) and time.time() - t0 > 60:
|
|
break
|
|
say(f"root peak used bytes: {peak}")
|
|
say("root after: " + host("df -B1 / | tail -1"))
|
|
say("local archives: " + host("pvesm list local | grep 9201"))
|
|
say("host journal: " + host("journalctl -u felhom-agent --since '-70min' --no-pager | grep -iE 'vzdump|backup (done|failed|started)|prune|No space' | tail -15"))
|
|
w.login()
|
|
c, d = w.ctl("GET", "/api/stacks")
|
|
say("apps after: " + str([(s['name'], s.get('state')) for s in (d or {}).get('data') or [] if s.get('deployed')]))
|