"""fg_b4_lib.py — the demo-box helpers fg_b4_member.py uses (deploy, the Család card, remove), product endpoints only.""" import json, os, secrets, subprocess, sys, time os.environ.setdefault("GUEST", "9201"); os.environ.setdefault("BASE", "https://192.168.0.155") sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts") import box_walk as w w.HP = "hp" DOM = w.DOMAIN; CTL = f"felhom.{DOM}"; DRIVE = "/mnt/felhom-drives/hdd_1" def _card(action, name): sess = open(f"{w.SC}/sess{os.getpid()}.txt").read().strip(); csrf = open(f"{w.SC}/csrf{os.getpid()}.txt").read().strip() r = subprocess.run(["curl", "-sk", "-H", f"Host: {CTL}", "-H", f"Cookie: {sess}", "-H", f"X-CSRF-Token: {csrf}", "-X", "POST", "--data", f"name={name}", f"{w.BASE}/family/members/{action}"], capture_output=True, text=True) return json.loads(r.stdout) def add_member(name, say): d = _card("add", name) say(f"Család card: add {name} -> ok={d['ok']} (password returned once, not printed)") return d["data"]["password"] def remove_member(name, say): d = _card("remove", name) say(f"Család card: remove {name} -> ok={d['ok']} members now {d['data'].get('members')}") def deploy(app, sub, say): code, d = w.ctl("GET", f"/api/stacks/{app}/deploy-fields") fields = (((d.get("data") or {}).get("metadata") or {}).get("deploy_fields")) or [] values = {"DOMAIN": DOM, "SUBDOMAIN": sub} for f in fields: ev, ty = f.get("env_var"), f.get("type") if ev in values or (not f.get("required") and ty != "password"): continue values[ev] = DRIVE if ty == "path" else ("Demo-" + secrets.token_hex(12) if ty in ("secret", "password") else (f.get("default") or app)) code, d = w.ctl("POST", f"/api/stacks/{app}/deploy", {"values": values}) say(f"deploy {app} -> {code}") for _ in range(120): time.sleep(5) st = w.stack(app) if st.get("deployed") and (st.get("app_config") or {}).get("pinned_images") and st.get("state") == "running": break say(f" state={st.get('state')}") def remove(app, say): w.ctl("POST", f"/api/stacks/{app}/stop") for _ in range(24): time.sleep(5) if w.stack(app).get("state") != "running": break code, d = w.ctl("POST", f"/api/stacks/{app}/remove", {"remove_hdd_data": True, "remove_backups": True}) say(f"remove {app} WITH data and backups -> {code} {str(d)[:200]}")