"""e5.py — Part E's live proof on 9202 (controller 0.274.0-rc1, drill catalog), one step per call. Every act through the product's own endpoints (the ones the pages call). Evidence: E/E5-.txt.""" import json, sys, time, re import walk as w, fixtures step = sys.argv[1] OUT = open(f"{w.EV}/E/E5-{step}.txt", "w", buffering=1) def say(*a): w.say(*a); OUT.write(" ".join(map(str, a)) + "\n") HDD = "/mnt/felhom-drives/scratch_hdd" TOK = w.SC + "/seed-tokens.json" w.login() def kept_page(lang=""): h = w.page("/kept-data" + ("?lang=en" if lang else "")) t = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", h)) return t def deploy(choice=None, lang=""): vals = w.deploy_values("nextcloud", "c-nc"); vals["HDD_PATH"] = HDD body = {"values": vals} if choice: body["kept_data"] = choice return w.ctl("POST", "/api/stacks/nextcloud/deploy" + ("?lang=en" if lang else ""), body) def wait_deployed(limit=600): t0 = time.time() while time.time() - t0 < limit: st = w.stack("nextcloud") if st.get("deployed") and (st.get("app_config") or {}).get("pinned_images") and st.get("state") in ("running", "unhealthy", "degraded"): return round(time.time() - t0, 1), st.get("state") time.sleep(5) return None, w.stack("nextcloud").get("state") def g(cmd): return w.guest(cmd) say(f"# E5 {step} — {time.strftime('%FT%T%z')}; controller {g('cat /etc/felhom-controller-image').strip()}") if step == "1-list": say("drive:", g(f"ls -la {HDD}; ls -la {HDD}/appdata {HDD}/kept 2>&1; du -sh {HDD}/appdata/nextcloud 2>&1")) for lang in ("", "en"): t = kept_page(lang) i = t.find("extcloud") say(f"GET /kept-data{'?lang=en' if lang else ''}: ...{t[max(0,i-300):i+500]}...") elif step == "2-ask": for lang in ("", "en"): code, d = deploy(None, lang) say(f"deploy, no choice, lang={lang or 'hu'} -> {code}") say(json.dumps(d, ensure_ascii=False, indent=1)[:1600]) say("still not installed:", w.stack("nextcloud").get("deployed"), g(f"ls {HDD}/appdata")) elif step == "3-fresh": code, d = deploy("fresh") say(f"deploy kept_data=fresh -> {code} {str(d)[:200]}") say("deployed after", wait_deployed()) say("drive now:", g(f"ls -la {HDD}/appdata {HDD}/appdata/nextcloud 2>&1 | head -20; find {HDD}/kept -maxdepth 3 | head; du -sh {HDD}/kept/nextcloud/* 2>&1")) toks = json.load(open(TOK)); toks["nextcloud"] = fixtures.FIXTURES["nextcloud"].seed(w, "c-nc", say) json.dump(toks, open(TOK, "w"), default=str) say("seeded:", toks["nextcloud"] is not None) t = kept_page(); i = t.find("extcloud"); say("kept page:", t[max(0, i-200):i+600]) elif step == "4-remove-keep": code, d = w.ctl("POST", "/api/stacks/nextcloud/stop"); say("stop", code) time.sleep(15) code, d = w.ctl("POST", "/api/stacks/nextcloud/remove", {"remove_hdd_data": False, "remove_backups": False}) say(f"remove keep data + backups -> {code} {str(d)[:200]}") time.sleep(8) say("after:", w.stack("nextcloud").get("deployed"), g(f"ls {HDD}/appdata; ls -la --time-style=+%FT%T {HDD}/backups/primary/nextcloud {HDD}/backups/primary/nextcloud/db-dumps 2>&1 | tail -8")) elif step == "5-use": code, d = deploy(None) say(f"ask first -> {code} use_offered={(d.get('data') or {}).get('use_offered')} use_desc={(d.get('data') or {}).get('use_desc')}") since = g("date -u +%Y-%m-%dT%H:%M:%SZ").strip() code, d = deploy("use") say(f"deploy kept_data=use -> {code} {str(d)[:200]}") say("deployed after", wait_deployed(1200)) for i in range(60): if "after_load" in g(f"docker logs --since {since} felhom-controller 2>&1 | grep -c after_load") or i > 58: break time.sleep(5) time.sleep(20) say("controller lines:\n" + g(f"docker logs --since {since} felhom-controller 2>&1 | grep -iE 'kept|after_load|restore|unit|Restor' | grep -v DEBUG | cut -c1-300 | head -40")) toks = json.load(open(TOK)) say("seed (the account) reads back:", fixtures.FIXTURES["nextcloud"].verify(w, "c-nc", toks["nextcloud"], say)) elif step == "6-fresh-again": code, d = w.ctl("POST", "/api/stacks/nextcloud/stop"); time.sleep(15) code, d = w.ctl("POST", "/api/stacks/nextcloud/remove", {"remove_hdd_data": False, "remove_backups": False}) say(f"remove keep data + backups -> {code}") time.sleep(8) code, d = deploy("fresh"); say(f"deploy fresh -> {code} {str(d)[:160]}"); say("deployed after", wait_deployed()) say("kept now:", g(f"find {HDD}/kept -maxdepth 3 | head -20; du -sh {HDD}/kept/nextcloud/* 2>&1")) code, d = w.ctl("POST", "/api/stacks/nextcloud/stop"); time.sleep(15) code, d = w.ctl("POST", "/api/stacks/nextcloud/remove", {"remove_hdd_data": False, "remove_backups": True}) say(f"remove the fresh install (keep data, delete backups) -> {code} {str(d)[:160]}") time.sleep(8) for lang in ("", "en"): t = kept_page(lang); i = t.find("extcloud"); say(f"kept page {lang or 'hu'}:", t[max(0, i-200):i+1200])