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
25 lines
2.0 KiB
Python
25 lines
2.0 KiB
Python
"""Part D — READ-ONLY watch of a demo box's real automatic night. Every 60 s until the box's update-leg summary AND
|
|
its whole-guest backup outcome are both in (or a hard stop time): the controller's night lines (off-site leg, update
|
|
leg, quiesce gate deferrals and runs, update events) and the agent's backup lines, appended to the evidence file.
|
|
Touches nothing on the box. Usage: python3 d_watch.py <ssh-host> <label> <until HH:MM local>"""
|
|
import subprocess, sys, time, datetime
|
|
host, label, until = sys.argv[1], sys.argv[2], sys.argv[3]
|
|
EV = "/mnt/5_hdd/felhom.eu/git/felhom.eu/documentation/audits/night-2026-09-25/D"
|
|
def sh(cmd):
|
|
return subprocess.run(["ssh", "-o", "ConnectTimeout=20", host, "export LC_ALL=C; " + cmd], capture_output=True, text=True, timeout=180).stdout
|
|
stop = datetime.datetime.combine(datetime.date.today() + (datetime.timedelta(days=1) if datetime.datetime.now().hour > 12 else datetime.timedelta()), datetime.time.fromisoformat(until))
|
|
start_epoch = int(time.time())
|
|
start_utc = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(start_epoch))
|
|
seen_leg = seen_bk = False
|
|
while datetime.datetime.now() < stop:
|
|
ctl = sh(f"pct exec 9201 -- bash -c \"docker logs --since {start_utc} felhom-controller 2>&1 | grep -E 'update-leg|Running job: offbox|Job offbox|\\[offbox\\]|\\[quiesce\\]|\\[stacks\\] update |event app_update|app_stopped_unhealthy|unhealthy' \"")
|
|
open(f"{EV}/{label}-controller.log", "w").write(ctl)
|
|
ag = sh(f"journalctl -u felhom-agent --since @{start_epoch} --no-pager | grep -E 'backup: completed|backup job complete|SKIPPED|space preflight|local-api: backup|failed|restore-test' | grep -v sudo")
|
|
open(f"{EV}/{label}-agent.log", "w").write(ag)
|
|
seen_leg = "update leg (" in ctl
|
|
seen_bk = "backup job complete" in ag and seen_leg
|
|
if seen_leg and seen_bk:
|
|
break
|
|
time.sleep(60)
|
|
open(f"{EV}/{label}-watch-end.txt", "w").write(f"watch ended {datetime.datetime.now().isoformat()} leg_summary={seen_leg} backup_done={seen_bk}\n")
|