Files
felhom.eu/documentation/audits/n100-lived-in-2026-10-15/tools/read_wiring.py
T
admin 06e7cf8c3f
gates / gates (push) Successful in 6m59s
The N100 becomes the lived-in box (09 §3 decision 254): media apps installed and wired through the dashboard; films proven never off-site; the USB split NOT done (it is the whole-guest backup target)
- 09 §3 decision 254 (operator decisions 240/243 written down); target-selection: a "lived-in" tier, Tier 0 = demo-hp
  alone; nodes.md role + drive; 11-os-updates ring 0 wording; CLAUDE.md + docs.md: the diary.
- documentation/lived-in/n100.md (new diary); audits/n100-lived-in-2026-10-15/ (state, drive read, Part C capture sets,
  installs, wiring, stranger probes, demo-hp clean-up, the operator's SHEET.md).
- Register: R-1062 (the split, operator decides), R-1063 (decommission half-state on an agent refusal), R-1064 (path
  removal silent about cross-drive copies), R-1065 (a claimed Plex gets no libraries until a wiring run).
- demo-hp: /mnt/sizing-bench removed through the dashboard; the hub shows demo-hp OK (14:56 UTC).

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 16:59:15 +02:00

24 lines
2.0 KiB
Python

"""read_wiring.py — Part D2: what the box wired by itself, read from each app's OWN API inside its container (keys read
from the app's config at use, never printed) and from the controller's log. Read only."""
import json, shlex, n100
w = n100.w
def arr(app, port, path, ver="v3"):
script = ("K=$(sed -n 's:.*<ApiKey>\\(.*\\)</ApiKey>.*:\\1:p' /config/config.xml); "
f"curl -s -H \"X-Api-Key: $K\" http://127.0.0.1:{port}/api/{ver}{path}")
out = w.guest(f"docker exec {app} sh -c {shlex.quote(script)}")
try: return json.loads(out)
except Exception: return out[:200]
print("== the controller's wiring runs:")
print(w.guest("docker logs --since 10m felhom-controller 2>&1 | grep -E '\\[media\\] wiring|\\[mediawire\\]|media_library .*binds' | cut -c1-330"))
print("== per-drive binds (docker's own view):")
for a in ("qbittorrent", "sonarr", "radarr", "prowlarr"):
print(f" {a}:", w.guest(f"docker inspect {a} -f '{{{{range .Mounts}}}}{{{{.Source}}}} -> {{{{.Destination}}}}; {{{{end}}}}'").strip())
for a, port in (("sonarr", 8989), ("radarr", 7878)):
rf = arr(a, port, "/rootfolder"); tags = arr(a, port, "/tag"); dc = arr(a, port, "/downloadclient")
print(f"== {a}: root folders {[r.get('path') for r in rf] if isinstance(rf, list) else rf}")
print(f" tags {[t.get('label') for t in tags] if isinstance(tags, list) else tags}")
print(f" download clients {[(c.get('name'), c.get('implementation'), [f.get('value') for f in c.get('fields', []) if f.get('name') in ('host', 'tvCategory', 'movieCategory')], c.get('tags')) for c in dc] if isinstance(dc, list) else dc}")
apps = arr("prowlarr", 9696, "/applications", "v1")
print(f"== prowlarr: apps {[(a.get('name'), a.get('syncLevel'), next((f.get('value') for f in a.get('fields', []) if f.get('name') == 'baseUrl'), None)) for a in apps] if isinstance(apps, list) else apps}")
print("== qbittorrent categories:", w.guest("docker exec qbittorrent sh -c 'curl -s http://127.0.0.1:8080/api/v2/torrents/categories'").strip()[:600])