b50289074d
gates / gates (push) Successful in 28s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
66 lines
4.0 KiB
Python
66 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""r773_live.py — R-773 on 9202 through the product's own endpoints: install Karakeep (the household passes the setup
|
|
gate and makes the first account — the fixture), see sign-up closed, take the app's backup with the night chain's debug
|
|
action (the sanctioned by-day trigger), REMOVE keeping backups, press restore, and ask as a STRANGER (no session, no gate
|
|
cookie, through traefik) whether sign-up is closed again. Env: SC (0600 scratch with .ctlpw), EV. Secrets never printed."""
|
|
import json, os, subprocess, sys, time
|
|
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
|
|
import box_walk as w
|
|
import upgrade_fixtures_box as fixtures
|
|
APP, SUB = "karakeep", "bookmarks"
|
|
HOST = f"{SUB}.{w.DOMAIN}"
|
|
os.makedirs(f"{w.EV}", exist_ok=True)
|
|
log = open(f"{w.EV}/r773-live.txt", "a", buffering=1)
|
|
def say(*a):
|
|
w.say(*a); log.write(" ".join(map(str, a)) + "\n")
|
|
|
|
def stranger():
|
|
def c(*a):
|
|
r = subprocess.run(["curl", "-sk", "--max-time", "10", "-o", "/dev/null", "-w", "%{http_code}", "-H", f"Host: {HOST}"] + list(a),
|
|
capture_output=True, text=True)
|
|
return r.stdout.strip()
|
|
body = json.dumps({"0": {"json": {"name": "stranger", "email": "stranger@example.com", "password": "Stranger-pass-123",
|
|
"confirmPassword": "Stranger-pass-123"}}})
|
|
return {"GET /signup": c(f"{w.BASE}/signup"),
|
|
"POST users.create": c("-X", "POST", "-H", "Content-Type: application/json", "--data", body,
|
|
f"{w.BASE}/api/trpc/users.create?batch=1")}
|
|
|
|
def record():
|
|
out = w.guest(f"grep -A8 '^setup_gate:' /opt/docker/stacks/{APP}/app.yaml 2>/dev/null; echo ---; "
|
|
f"ls /opt/docker/stacks/traefik/dynamic/ | grep -E 'signup-block-{APP}|setup-gate-{APP}' || echo 'no block/gate file'")
|
|
return " | ".join(l.strip() for l in out.strip().splitlines() if l.strip())
|
|
|
|
w.login()
|
|
say(f"##### R-773 live on 9202 — controller {w.guest('docker inspect felhom-controller --format {{.Config.Image}}').strip()} ({time.strftime('%FT%TZ', time.gmtime())})")
|
|
ok = w.deploy(APP, SUB)
|
|
say("deploy ->", ok)
|
|
tok = fixtures.FIXTURES[APP].seed(w, SUB, say) # the household: through the gate, the first account
|
|
say("seed (first account) ->", "ok" if tok else "FAILED")
|
|
for _ in range(60): # the gate opens by its probe → the block goes up
|
|
if "signup-block" in record(): break
|
|
time.sleep(5)
|
|
say("BEFORE remove — lock record + files:", record())
|
|
say("BEFORE remove — a stranger:", stranger())
|
|
code, d = w.ctl("POST", "/api/debug/backup/night-chain")
|
|
say("night chain (debug action) ->", code, str(d)[:160])
|
|
for _ in range(120):
|
|
if w.snapshots(APP): break
|
|
time.sleep(10)
|
|
say("restore points offered:", [(s.get("id") or s.get("snapshot_id"), s.get("time") or s.get("created")) for s in w.snapshots(APP)][:3])
|
|
for _ in range(90): # let the chain finish before the remove
|
|
out = w.guest("docker logs --since 30m felhom-controller 2>&1 | grep -c 'night-chain\\] update leg: done\\|night-chain.*chain done\\|night-chain\\] manual run.*done'").strip()
|
|
if out not in ("", "0"): break
|
|
time.sleep(10)
|
|
w.ctl("POST", f"/api/stacks/{APP}/stop"); time.sleep(10)
|
|
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)[:200]}")
|
|
time.sleep(8)
|
|
say("AFTER remove — lock record + files:", record())
|
|
r = w.restore(APP)
|
|
say("restore:", {k: r.get(k) for k in ("ok", "snapshot_id", "http", "seconds", "state_after", "hold_after", "why")})
|
|
w.wait_app(SUB, "/", tries=40)
|
|
say("AFTER remove + restore — lock record + files:", record())
|
|
say("AFTER remove + restore — a stranger:", stranger())
|
|
say("the household's data back:", fixtures.FIXTURES[APP].verify(w, SUB, tok, say) if tok else "no seed")
|
|
say("controller log:", w.guest("docker logs --since 40m felhom-controller 2>&1 | grep -E 'karakeep: (restored after a removal|the household|sign-up)|signup' | tail -6"))
|