Files
felhom.eu/documentation/audits/tester1-limits-filebrowser-2026-10-17/tools/t1teardown.py
T
admin fae8064557 Register: R-1022, R-1116, R-977 closed; R-1123..R-1128 filed; R-994 narrowed; duplicate ids fixed
b9c4f73b (the cc-creds session) committed this session's uncommitted register edits together with its own
R-1118..R-1122, so main carried two rows each for R-1118..R-1122. This session's five move to R-1124..R-1128
(R-1123 stays); the CLOSED-ITEMS section for the three closed rows lands here. Evidence:
audits/tester1-limits-filebrowser-2026-10-17/.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-17 11:58:18 +02:00

55 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""t1teardown.py — R-1022 on Tester 1 through its dashboard's own endpoints (operator word 2026-10-17 10:47).
Env: SC (0600 dir with .ctlpw = Tester 1's dashboard password), EV, TARGET=tester-1. Steps:
apps stop + remove each test app WITHOUT „delete data" (remove_hdd_data=false, remove_backups=false)
drives decommission media_a..media_d („anyway", type-to-confirm = the mount name), the dashboard's call
state deployed apps, storage paths, the controller image and repo_url (read-only)
"""
import json, os, sys, time
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
import box_walk as w # noqa: E402
EV = os.environ["EV"]
LOG = open(os.path.join(EV, "t1-console.txt"), "a", buffering=1)
_say = w.say
def say(*a):
_say(*a); LOG.write(time.strftime("%H:%M:%S ") + " ".join(str(x) for x in a) + "\n")
w.say = say
APPS = ["sonarr", "radarr", "qbittorrent", "transmission", "plex", "jellyfin", "prowlarr"]
DRIVES = ["media_a", "media_b", "media_c", "media_d"]
def state():
c, d = w.ctl("GET", "/api/stacks")
dep = sorted(s.get("name") for s in (d.get("data") or []) if s.get("deployed"))
say(f"deployed apps: {dep}")
say(w.guest("cat /etc/felhom-controller-image; grep -n repo_url /var/lib/docker/volumes/felhom-controller-data/_data/controller.yaml; "
"findmnt -rn -o TARGET | grep felhom-drives; python3 -c \"import json;d=json.load(open('/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json'));"
"print('storage paths:', [(p.get('path'), 'decommissioned' if p.get('decommissioned') else 'live') for p in d.get('storage_paths') or []])\""))
def main():
step = sys.argv[1]
w.login()
if step == "apps":
for a in APPS:
st = w.stack(a)
if not st.get("deployed"):
say(f"{a}: not deployed — skipped"); continue
c1, d1 = w.ctl("POST", f"/api/stacks/{a}/stop")
for _ in range(36):
time.sleep(5)
if w.stack(a).get("state") != "running":
break
c2, d2 = w.ctl("POST", f"/api/stacks/{a}/remove", {"remove_hdd_data": False, "remove_backups": False})
say(f"{a}: stop -> {c1}; remove (keep data, keep backups) -> {c2} {json.dumps(d2, ensure_ascii=False)[:260]}")
state()
elif step == "drives":
for m in DRIVES:
c, d = w.ctl("POST", "/api/storage/decommission", {"where": f"/mnt/felhom-drives/{m}", "mode": "anyway", "mount_name": m})
say(f"decommission {m} -> {c} {json.dumps(d, ensure_ascii=False)[:300]}")
time.sleep(5)
state()
elif step == "state":
state()
main()