Media apps on every drive — the rig on the Tester 1 box (2026-10-14)
Task: TASK-media-all-drives (operator rulings 2026-10-14, 09 §3). Box: Tester 1 (VM 341 on demo-hp, guest 9201,
enkicsifelhom.hu), controller 0.310.0, agent 0.156.1. Design written from this: architecture/15-media-library.md.
Predictions were written before each measurement: A-drives/PREDICTIONS-A4-A6.md, S-PREDICTIONS.md.
| Part | Result | Evidence |
|---|---|---|
| A1 | Tester 1 read first: one drive adatlemez (default; not the backup target — that is local), apps bookstack, paperless-ngx, privatebin; guest 4096 MB (max 5824), host VM 8 GB; off-site on; demo-hp /mnt/hdd_1 764 G free of 938 G |
A-drives/A1-*.txt |
| A2 | Two 100 GB disks hot-added as scsi2/scsi3, backup=0, on nvme-scratch (/mnt/hdd_1 root). Worst case (every sparse image full) leaves ≥ 391 G free = 42 %. Memory NOT raised: the six media apps' summed peaks are 1199 MB (sizing.json); with the box's three apps and the platform ~2.7 GB < 4096 MB |
A-drives/A2-disks-added.txt |
| A4 | Both enrolled through POST /api/storage/init (the wizard's call), ~2 s each: media_a (sdc), media_b (sdd). Neither became the default (sent set_default:false; the wizard's checkbox is ON by default) nor the backup target (target: local before and after) |
A-drives/A4-*.txt |
| A5 | Skeleton on both (userdata/{documents,downloads,media/{movies,tv,torrents,transmission,photos,books,…},roms}); FileBrowser recreated with both drives (/srv/media_a, /srv/media_b). The dashboard: „Aktív", „Nincs alkalmazás ezen a tárolón" — nothing about apps that would need a restart |
A-drives/A5-*.txt |
| A6 | (1) demo-hp has no backup job at all; backup=0 read back. (2) Tester 1's whole-guest backups — local AND off-site PBS — log „excluding bind mount point mp8 ('/mnt/felhom-drives')". (3) The controller's own classifier over the test templates: no media bind in any capture set (control: the live templates DO capture — and a decoy with unlisted writable binds is captured mandatory) |
A-drives/A6-*.txt |
| B1 | Tester 1 points at a local mirror of the drill catalog (file:///opt/docker/felhom-controller/drill-catalog.git) — no credential on the box (R-992: a read-only token could not be minted, the 403 is quoted in tools/repoint.py). Three controls pass: Tester 1's cache = drill 0ad6383; demo-hp 9201, 9202 and the N100 guest = live 8ee687e; live main unchanged |
B1-*.txt |
| B2 | Drill commit 0ad6383: six templates bind /mnt/felhom-drives/{media_a,media_b}/userdata/media at the same path (:ro for Plex/Jellyfin); images unchanged |
tools/make_drill.py |
| B4 | qBittorrent, Transmission, Sonarr, Radarr deployed through POST /api/stacks/<app>/deploy; plain host paths accepted, no warning |
B4-deploy.txt |
| C | tools/wire.py: per drive a qBittorrent category, Sonarr/Radarr root folder + tag + two client entries; min free space 10 GB; hardlinks on (default) |
C-wire-run*.txt |
| C | API key: read from /config/config.xml; it CAN be set at install: SONARR__AUTH__APIKEY / RADARR__AUTH__APIKEY env → 200 with that key, 401 with another |
C-apikey-at-install.txt |
| S1 | Today's two-bind shape: ln: … Cross-device link (EXDEV) on one filesystem → copy (2 inodes). One bind per drive: link count 2, one inode |
S1-hardlink.txt |
| S2 | One public-domain film (archive.org, CC PD Mark) on drive B: through Transmission and through qBittorrent → hardlink in media_b/…/movies. archive.org's web seed failed the last piece for qBittorrent; a local peer (the same torrent in Transmission) finished it — recorded |
S2-*.txt |
| S3 | Tag drive-a, no client forced → „Transmission drive-a", hardlink on A. Mismatch (root B, tag A) → download on A, copy on B (link count 1 each) | S3-*.txt |
| — | 17:25 CEST: demo-hp was power-cut by another session's Immich drill (plugcut.py --plug hp) — Tester 1 went down with it and came back by itself; the boot gate recreated the four media apps onto drive A; all test films then removed (0 files left) |
AFTER-power-cut-1725.txt |
| H | Prowlarr (drill-only template b0fd3a0, version-2.6.5.5623, config volume only) deployed through the dashboard; wire.py adds Sonarr and Radarr as Prowlarr apps with „Full Sync” (both pass Prowlarr's test; the sync completes; 0 indexers so far). Sonarr now refuses a bare IP (the operator set „Allowed hosts”) — wire.py sends Host: <app> |
H-*.txt |
| G | Sign-in with „Disabled for Local Addresses”: outsiders ARE asked (the public address arrives in X-Forwarded-For; Sonarr/Radarr redirect to /login); the home network and other containers are not (200 + API key) — R-1030. The box's setup gate also blocks outsiders until setup is marked done |
G-auth/ |
| E1 | The operator's test: 18 imports from Sonarr and Radarr. Every show/film whose tag matched its drive → a hardlink on that drive (13), through both download apps on both drives; the two mismatches (Slow Horses ×5, „Who") → a full copy on B while A seeds. Plex was empty until one manual scan (R-1037) | E1-*.txt, E3-who.txt, K-plex-empty.txt |
| S5 | Media B pulled 20:10:23 for 30 min: 0 apps stopped; the guest kept a DEAD mount (I/O errors); hub event + operator mail in 24 s; Plex/Jellyfin removed nothing; Sonarr/Radarr health silent | S5-S6/ |
| S6 | Re-attached 20:41:00: the host re-mounted in 24 s; every running container — FileBrowser too — kept the dead view; „restart" did nothing; stop+start fixed the six apps; FileBrowser is protected and stays broken (R-1038) | S5-S6/ |