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)
gates / gates (push) Successful in 6m59s

- 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
This commit is contained in:
admin committed 2026-10-15 16:59:15 +02:00
1 parent 3263bb26bc
commit 06e7cf8c3f
30 files changed
+614 -12

No files matched your search

@@ -0,0 +1,46 @@
== host
demo-felhom
felhom-agent 0.156.1
total used free shared buff/cache available
Mem: 15772 2408 8108 66 5664 13363
NAME SIZE TYPE FSTYPE MOUNTPOINT MODEL SERIAL
sda 476.9G disk AirDisk 512GB SSD QDF922W009654S30EX
|-sda1 1007K part
|-sda2 1G part vfat /boot/efi
`-sda3 475.9G part LVM2_member
|-pve-swap 8G lvm swap [SWAP]
|-pve-root 96G lvm ext4 /
|-pve-data_tmeta 3.6G lvm
| `-pve-data-tpool 348.8G lvm
| |-pve-data 348.8G lvm
| |-pve-vm--9201--disk--2 32G lvm ext4
| `-pve-vm--9201--disk--3 250G lvm ext4
`-pve-data_tdata 348.8G lvm
`-pve-data-tpool 348.8G lvm
|-pve-data 348.8G lvm
|-pve-vm--9201--disk--2 32G lvm ext4
`-pve-vm--9201--disk--3 250G lvm ext4
sdb 931.5G disk ext4 /mnt/hdd_1 TOSHIBA MQ04ABF100 65NOP3HDT
VMID Status Lock Name
9201 running demo-felhom
== guest
cores: 3
memory: 12288
mp0: local-lvm:vm-9201-disk-3,mp=/var/lib/felhom,backup=1,size=250G
mp8: /mnt/felhom-drives,mp=/mnt/felhom-drives
mp9: /var/lib/felhom-agent/guests/9201/bootstrap,mp=/etc/felhom-bootstrap,ro=1
rootfs: local-lvm:vm-9201-disk-2,size=32G
swap: 512
gitea.dooplex.hu/admin/felhom-controller:0.314.0
192.168.0.149 169.254.253.2 172.16.253.1 172.17.0.1 172.18.0.1
total used free shared buff/cache available
Mem: 12288 222 10945 8 1128 12065
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/pve-vm--9201--disk--2 32G 1.2G 29G 4% /
/dev/sdb 916G 6.2G 864G 1% /mnt/felhom-drives/hdd_1
ls: cannot access '/dev/dri': No such file or directory
cloudflared Up 41 hours (healthy)
felhom-controller Up 2 hours (healthy)
filebrowser Up 21 hours (healthy)
opengist Up 12 hours (healthy)
traefik Up 12 hours
@@ -0,0 +1,26 @@
NAME TRAN VENDOR MODEL SERIAL SIZE
sdb usb ADATA TOSHIBA MQ04ABF100 65NOP3HDT 931.5G
ID_BUS=ata
ID_MODEL=TOSHIBA_MQ04ABF100
ID_SERIAL=TOSHIBA_MQ04ABF100_65NOP3HDT
ID_USB_MODEL=HD710_PRO
ID_USB_VENDOR=ADATA
by-path
card0
renderD128
== top
total 32
drwxr-xr-x 5 root root 4096 Jul 28 21:25 .
drwxr-xr-x 5 root root 4096 Aug 3 09:15 ..
drwxr-xr-x 2 root root 4096 Oct 15 04:59 dump
drwxr-xr-x 6 100000 100000 4096 Jul 18 22:11 felhom-data
drwx------ 2 root root 16384 Jul 18 18:41 lost+found
== du
2.7G /mnt/hdd_1/dump
3.5G /mnt/hdd_1/felhom-data
16K /mnt/hdd_1/lost+found
== felhom-data
32K /mnt/hdd_1/felhom-data/shares
528K /mnt/hdd_1/felhom-data/userdata
422M /mnt/hdd_1/felhom-data/appdata
3.1G /mnt/hdd_1/felhom-data/backups
@@ -0,0 +1,47 @@
Name Type Status Total (KiB) Used (KiB) Available (KiB) %
felhom-backup dir active 960303848 6435888 905013448 0.67%
felhom-pbs pbs active 0 0 0 0.00%
local dir active 98497780 32496832 60951400 32.99%
local-lvm lvmthin active 365760512 9290317 356470194 2.54%
dir: felhom-backup
== dump
-rw-r--r-- 1 root root 950588793 Oct 13 04:53 vzdump-lxc-9201-2026_10_13-04_52_51.tar.zst
-rw-r--r-- 1 root root 16 Oct 13 04:53 vzdump-lxc-9201-2026_10_13-04_52_51.tar.zst.notes
-rw-r--r-- 1 root root 1505 Oct 14 04:54 vzdump-lxc-9201-2026_10_14-04_54_24.log
-rw-r--r-- 1 root root 951109351 Oct 14 04:54 vzdump-lxc-9201-2026_10_14-04_54_24.tar.zst
-rw-r--r-- 1 root root 16 Oct 14 04:54 vzdump-lxc-9201-2026_10_14-04_54_24.tar.zst.notes
-rw-r--r-- 1 root root 1504 Oct 15 04:59 vzdump-lxc-9201-2026_10_15-04_59_17.log
-rw-r--r-- 1 root root 951089306 Oct 15 04:59 vzdump-lxc-9201-2026_10_15-04_59_17.tar.zst
-rw-r--r-- 1 root root 16 Oct 15 04:59 vzdump-lxc-9201-2026_10_15-04_59_17.tar.zst.notes
== backups
4.0K /mnt/hdd_1/felhom-data/backups/offsite-proof
1.6G /mnt/hdd_1/felhom-data/backups/offsite-restore
1.3G /mnt/hdd_1/felhom-data/backups/primary
274M /mnt/hdd_1/felhom-data/backups/secondary
== appdata
12K /mnt/hdd_1/felhom-data/appdata/romm
24K /mnt/hdd_1/felhom-data/appdata/paperless
63M /mnt/hdd_1/felhom-data/appdata/nextcloud
360M /mnt/hdd_1/felhom-data/appdata/immich
== userdata
/mnt/hdd_1/felhom-data/userdata
/mnt/hdd_1/felhom-data/userdata/media
/mnt/hdd_1/felhom-data/userdata/media/nzbget
/mnt/hdd_1/felhom-data/userdata/media/usenet
/mnt/hdd_1/felhom-data/userdata/media/movies
/mnt/hdd_1/felhom-data/userdata/media/music
/mnt/hdd_1/felhom-data/userdata/media/comics
/mnt/hdd_1/felhom-data/userdata/media/podcasts
/mnt/hdd_1/felhom-data/userdata/media/audiobooks
/mnt/hdd_1/felhom-data/userdata/media/transmission
/mnt/hdd_1/felhom-data/userdata/media/transmission/watch
/mnt/hdd_1/felhom-data/userdata/media/grimmory
/mnt/hdd_1/felhom-data/userdata/media/torrents
/mnt/hdd_1/felhom-data/userdata/media/tv
/mnt/hdd_1/felhom-data/userdata/media/photos
/mnt/hdd_1/felhom-data/userdata/media/metube
/mnt/hdd_1/felhom-data/userdata/media/books
/mnt/hdd_1/felhom-data/userdata/media/books/metadata.db
/mnt/hdd_1/felhom-data/userdata/media/books/metadata.db-shm
/mnt/hdd_1/felhom-data/userdata/media/books/metadata.db-wal
@@ -0,0 +1,7 @@
standing now: typical 27 MB, peak 68 MB; rule (platform 470 + peak) x 1.5 = 807 MB vs guest 12288 MB -> fits
standing + the five: typical 636 MB, peak 841 MB; rule (platform 470 + peak) x 1.5 = 1966 MB vs guest 12288 MB -> fits
plex: typical 232 MB, peak 234 MB (measured)
qbittorrent: typical 163 MB, peak 318 MB (onboarding)
prowlarr: typical 41 MB, peak 44 MB (onboarding)
sonarr: typical 77 MB, peak 77 MB (onboarding)
radarr: typical 96 MB, peak 100 MB (measured)
@@ -0,0 +1,16 @@
/api/storage/paths -> 404 {"_raw": "404 page not found\n"}
/api/disks -> 200 {"data": {"vmid": 9201, "disks": [{"name": "felhom-backup", "type": "local-dir", "state": "attached", "backing_device": "/dev/sdb", "mount_path": "/mnt/hdd_1", "class": "slow", "role": "user-data", "data_bearing": true, "data_reason": "device is mounted", "total_bytes": 983351140352, "used_bytes": 6590349312, "used_fraction": 0.00670192878369056, "durable_id": "uuid:47a3361a-91e0-4831-a69d-27f540ed3f48", "wipe_durable_id": "byid:wwn-0x5000039ddb108568", "guest_attached": false, "backup_target": true, "guest_path": "/mnt/felhom-drives/hdd_1", "bound_under_parent": true, "smart": {"health": "PASSED", "model_name": "TOSHIBA MQ04ABF100", "temperature_c": 35, "power_on_hours": 5449, "reallocated_sectors": 0, "pending_sectors": 0, "offline_uncorrectable": 0, "udma_crc_errors": 0, "critical_warning": null, "media_errors": null, "percentage_used": null}}, {"name": "local", "type": "local", "stat
/api/backup/status -> 200 {"ok": true, "data": {"enabled": true, "running": false}}
/api/offbox/status -> 404 {"ok": false, "error": "endpoint not found"}
/api/backup/offsite/status -> 404 {"ok": false, "error": "endpoint not found"}
/api/selfupdate/status -> 200 {"ok": true, "data": {"running": false, "last_check": {"current_version": "0.314.0", "latest_version": "0.314.0", "update_available": false, "checked_at": "2026-10-15T12:56:24Z"}, "last_state": {"status": "success", "previous_version": "0.313.0", "previous_image": "gitea.dooplex.hu/admin/felhom-controller:0.313.0", "target_version": "0.314.0", "target_image": "gitea.dooplex.hu/admin/felhom-controller:0.314.0", "initiated_at": "2026-10-15T12:55:48Z", "initiated_by": "auto-floor", "completed_at": "2026-10-15T12:55:54Z"}}}
/api/storage/backup-target -> 200 {"data": {"degraded": false, "known": true, "label": "Külső tárhely (hdd_1)", "target": "felhom-backup"}, "ok": true}
/api/storage/media/status -> 200 {"data": {"pending": false, "drives": null, "apps": null}, "ok": true}
/api/storage/ -> 404 {"_raw": "404 page not found\n"}
{'path': '/mnt/felhom-drives/hdd_1', 'label': 'Külső tárhely (hdd_1)', 'schedulable': True}
keys: ['password_hash', 'filebrowser_admin_state', 'filebrowser_admin_decided_at', 'claimed', 'claim_code_hash', 'claim_code_generation', 'claim_code_issued_at', 'claim_consumed_generation', 'offbox_enlarge_notice_seeded', 'app_update_events_seeded', 'unhealthy_stop_event_seeded', 'hub_escrow_identity_present', 'hub_escrow_superseded_present', 'hub_escrow_superseded_at', 'hub_escrow_key_sha256', 'hub_escrow_key_checked_at', 'app_backup', 'offsite_data_at', 'backup_window_start', 'storage_paths', 'last_guest_boot_id', 'hub_verified', 'hub_verified_at', 'hub_last_check', 'applied_config_version', 'offbox']
offbox: {"enabled": true, "host": "u629488-sub1.your-storagebox.de", "port": 23, "user": "u629488-sub1", "repo_path": "/home/felhom-repo", "schedule": "daily", "quota_gb": 50, "transport": "rclone-pinned", "last_run": "2026-10-15T02:15:10Z", "last_status": "ok", "last_success": "2026-10-15T02:15:10Z", "last_integrity_check": "2026-10-11T04:00:00Z", "last_integrity_ok": true, "last_integrity_depth": "100%", "proved_snapshots": {"opengist": "0ef3edb5"}, "last_proof_run": "2026-10-15T03:30:00Z", "last_proof_stack": "opengist", "last_proof_snapshot": "0ef3edb5", "last_proof_result": "pass", "last_duration": "7s", "repo_size_human": "181.6 KB", "repo_size_bytes": 185936, "snapshot_count": 15, "stats_know
app_backup: {"opengist": {"enabled": false, "cross_drive": {"enabled": true, "method": "rsync", "destination_path": "/mnt/felhom-drives/hdd_1", "schedule": "daily", "last_run": "2026-10-15T01:30:00Z", "last_status": "ok", "last_success": "2026-10-15T01:30:00Z", "success_tracked": true, "unit_package_date": "2026-10-15T00:30:00Z", "last_duration": "0s", "last_size_human": "202.8 KB"}, "offbox": true}}
offsite_data_at: {'opengist': {'pushed_at': '2026-10-15T02:15:05Z', 'data_at': '2026-10-15T02:15:00Z'}}
@@ -0,0 +1,10 @@
qbittorrent 200 [('DOMAIN', 'domain', True, None), ('SUBDOMAIN', 'subdomain', True, None), ('HDD_PATH', 'path', True, None), ('QBT_ADMIN_PASSWORD', 'password', True, None)]
deployed: False
prowlarr 200 [('DOMAIN', 'domain', True, None), ('SUBDOMAIN', 'subdomain', True, None)]
deployed: False
sonarr 200 [('DOMAIN', 'domain', True, None), ('SUBDOMAIN', 'subdomain', True, None), ('HDD_PATH', 'path', True, None)]
deployed: False
radarr 200 [('DOMAIN', 'domain', True, None), ('SUBDOMAIN', 'subdomain', True, None), ('HDD_PATH', 'path', True, None)]
deployed: False
plex 200 [('DOMAIN', 'domain', True, None), ('SUBDOMAIN', 'subdomain', True, None), ('PLEX_CLAIM', 'text', True, True), ('HDD_PATH', 'path', True, None)]
deployed: False
@@ -0,0 +1,18 @@
16:36:53 qbittorrent: deploy (fields sent: ['DOMAIN', 'QBT_ADMIN_PASSWORD', 'SUBDOMAIN']) -> 202 {"ok": true, "message": "Telepítés elindítva – az állapot a kártyán követhető"}
qbittorrent: state=running after 13s; pinned={'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.4-1'}; HDD_PATH: /mnt/felhom-drives/hdd_1
16:37:06 prowlarr: deploy (fields sent: ['DOMAIN', 'SUBDOMAIN']) -> 202 {"ok": true, "message": "Telepítés elindítva – az állapot a kártyán követhető"}
prowlarr: state=running after 28s; pinned={'prowlarr': 'lscr.io/linuxserver/prowlarr:version-2.6.5.5623'};
16:37:34 sonarr: deploy (fields sent: ['DOMAIN', 'SUBDOMAIN']) -> 202 {"ok": true, "message": "Telepítés elindítva – az állapot a kártyán követhető"}
sonarr: state=running after 33s; pinned={'sonarr': 'lscr.io/linuxserver/sonarr:4.0.20'}; HDD_PATH: /mnt/felhom-drives/hdd_1
16:38:07 radarr: deploy (fields sent: ['DOMAIN', 'SUBDOMAIN']) -> 202 {"ok": true, "message": "Telepítés elindítva – az állapot a kártyán követhető"}
radarr: state=running after 28s; pinned={'radarr': 'lscr.io/linuxserver/radarr:6.4.4'}; HDD_PATH: /mnt/felhom-drives/hdd_1
cloudflared Up 41 hours (healthy)
felhom-controller Up 2 hours (healthy)
filebrowser Up 21 hours (healthy)
opengist Up 12 hours (healthy)
prowlarr Up About a minute (healthy)
qbittorrent Up About a minute (healthy)
radarr Up 15 seconds (healthy)
sonarr Up 56 seconds (healthy)
traefik Up 12 hours
@@ -0,0 +1,23 @@
14:38:45 qbittorrent / -> HTTP/2 404
14:38:46 qbittorrent /api/v3/system/status -> HTTP/2 404
14:38:46 qbittorrent /api/v1/system/status -> HTTP/2 404
14:38:46 qbittorrent /initialize.json -> HTTP/2 404
14:38:46 qbittorrent /api/v2/app/version -> HTTP/2 404
14:38:46 prowlarr / -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fprowlarr.demo-felhom.eu%2F
14:38:47 prowlarr /api/v3/system/status -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fprowlarr.demo-felhom.eu%2Fapi%2Fv3%2Fsystem%2Fstatus
14:38:47 prowlarr /api/v1/system/status -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fprowlarr.demo-felhom.eu%2Fapi%2Fv1%2Fsystem%2Fstatus
14:38:47 prowlarr /initialize.json -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fprowlarr.demo-felhom.eu%2Finitialize.json
14:38:47 prowlarr /api/v2/app/version -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fprowlarr.demo-felhom.eu%2Fapi%2Fv2%2Fapp%2Fversion
14:38:48 sonarr / -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fsonarr.demo-felhom.eu%2F
14:38:48 sonarr /api/v3/system/status -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fsonarr.demo-felhom.eu%2Fapi%2Fv3%2Fsystem%2Fstatus
14:38:48 sonarr /api/v1/system/status -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fsonarr.demo-felhom.eu%2Fapi%2Fv1%2Fsystem%2Fstatus
14:38:48 sonarr /initialize.json -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fsonarr.demo-felhom.eu%2Finitialize.json
14:38:49 sonarr /api/v2/app/version -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fsonarr.demo-felhom.eu%2Fapi%2Fv2%2Fapp%2Fversion
14:38:49 radarr / -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fradarr.demo-felhom.eu%2F
14:38:49 radarr /api/v3/system/status -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fradarr.demo-felhom.eu%2Fapi%2Fv3%2Fsystem%2Fstatus
14:38:49 radarr /api/v1/system/status -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fradarr.demo-felhom.eu%2Fapi%2Fv1%2Fsystem%2Fstatus
14:38:50 radarr /initialize.json -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fradarr.demo-felhom.eu%2Finitialize.json
14:38:50 radarr /api/v2/app/version -> HTTP/2 302 location: https://felhom.demo-felhom.eu/__gate/start?rd=https%3A%2F%2Fradarr.demo-felhom.eu%2Fapi%2Fv2%2Fapp%2Fversion
(the qbittorrent lines above used the wrong name; its address is torrent.demo-felhom.eu)
14:39:24 torrent / -> HTTP/2 200 body: <!DOCTYPE html><html lang="C"><head> <meta charset="UTF-8"> <meta nam
14:39:25 torrent /api/v2/app/version -> HTTP/2 403 body: Forbidden
@@ -0,0 +1,27 @@
== the controller's wiring runs:
2026/10/15 14:36:47 [INFO] [stacks] media_library qbittorrent: per-drive binds 0 []; drives not bound: []
2026/10/15 14:37:28 [INFO] [stacks] media_library sonarr: per-drive binds 0 []; drives not bound: []
2026/10/15 14:38:01 [INFO] [stacks] media_library radarr: per-drive binds 0 []; drives not bound: []
2026/10/15 14:39:15 [INFO] [media] wiring the drives into the media apps (a media app came up: radarr)
2026/10/15 14:39:18 [INFO] [mediawire] 1 drive(s) wired in 3.504s: folders=done(0) qbittorrent=done(3) sonarr=done(4) radarr=done(4) prowlarr=done(2)
== per-drive binds (docker's own view):
qbittorrent: /var/lib/docker/volumes/qbittorrent_qbittorrent_config/_data -> /config; /mnt/felhom-drives/hdd_1/userdata/media/torrents -> /downloads; /mnt/felhom-drives/hdd_1/userdata/media/torrents -> /mnt/felhom-drives/hdd_1/userdata/media/torrents;
sonarr: /var/lib/docker/volumes/sonarr_sonarr_config/_data -> /config; /mnt/felhom-drives/hdd_1/userdata/media -> /mnt/felhom-drives/hdd_1/userdata/media;
radarr: /var/lib/docker/volumes/radarr_radarr_config/_data -> /config; /mnt/felhom-drives/hdd_1/userdata/media -> /mnt/felhom-drives/hdd_1/userdata/media;
prowlarr: /var/lib/docker/volumes/prowlarr_prowlarr_config/_data -> /config;
== sonarr: root folders ['/mnt/felhom-drives/hdd_1/userdata/media/tv']
tags ['hdd-1']
download clients [('qBittorrent hdd-1', 'QBittorrent', ['qbittorrent', 'tv-hdd-1'], [1])]
== radarr: root folders ['/mnt/felhom-drives/hdd_1/userdata/media/movies']
tags ['hdd-1']
download clients [('qBittorrent hdd-1', 'QBittorrent', ['qbittorrent', 'movies-hdd-1'], [1])]
== prowlarr: apps [('Radarr', 'fullSync', 'http://radarr:7878'), ('Sonarr', 'fullSync', 'http://sonarr:8989')]
== qbittorrent categories: Forbidden
== qbittorrent (its own API, after its login):
{"movies-hdd-1":{"download_path":"/mnt/felhom-drives/hdd_1/userdata/media/torrents/.temp","inactive_seeding_time_limit":-2,"name":"movies-hdd-1","ratio_limit":-2,"savePath":"/mnt/felhom-drives/hdd_1/userdata/media/torrents/movies","seeding_time_limit":-2,"share_limit_action":"Default"},"tv-hdd-1":{"download_path":"/mnt/felhom-drives/hdd_1/userdata/media/torrents/.temp","inactive_seeding_time_limit":-2,"name":"tv-hdd-1","ratio_limit":-2,"savePath":"/mnt/felhom-drives/hdd_1/userdata/media/torrents/tv","seeding_time_limit":-2,"share_limit_action":"Default"}}
"auto_tmm_enabled":true
"save_path":"/mnt/felhom-drives/hdd_1/userdata/media/torrents"
"save_path_changed_tmm_enabled":false
"temp_path":"/mnt/felhom-drives/hdd_1/userdata/media/torrents/.temp"
"temp_path_enabled":true
@@ -0,0 +1,35 @@
{
"opengist": {
"enabled": false,
"cross_drive": {
"enabled": true,
"method": "rsync",
"destination_path": "/mnt/felhom-drives/hdd_1",
"schedule": "daily",
"last_run": "2026-10-15T01:30:00Z",
"last_status": "ok",
"last_success": "2026-10-15T01:30:00Z",
"success_tracked": true,
"unit_package_date": "2026-10-15T00:30:00Z",
"last_duration": "0s",
"last_size_human": "202.8 KB"
},
"offbox": true
},
"prowlarr": {
"enabled": false,
"offbox": true
},
"qbittorrent": {
"enabled": false,
"offbox": true
},
"radarr": {
"enabled": false,
"offbox": true
},
"sonarr": {
"enabled": false,
"offbox": true
}
}
@@ -0,0 +1,23 @@
== qbittorrent: 1 classifiable bind(s), classified=true
bind userdata:media/torrents class=optional origin=explicit
tier offsite takes []
tier secondary takes [/mnt/felhom-drives/hdd_1/felhom-data/userdata/media/torrents (optional)]
== sonarr: 1 classifiable bind(s), classified=true
bind userdata:media class=excluded origin=explicit
tier offsite takes []
tier secondary takes []
== radarr: 1 classifiable bind(s), classified=true
bind userdata:media class=excluded origin=explicit
tier offsite takes []
tier secondary takes []
== prowlarr: 0 classifiable bind(s), classified=true
tier offsite takes []
tier secondary takes []
--- PASS: TestN100CaptureSetTmp (0.00s)
2026-10-15 04:59:17 INFO: including mount point mp0 ('/var/lib/felhom') in backup
2026-10-15 04:59:17 INFO: excluding bind mount point mp8 ('/mnt/felhom-drives') from backup (not a volume)
2026-10-15 04:59:17 INFO: excluding bind mount point mp9 ('/etc/felhom-bootstrap') from backup (not a volume)
mp0: local-lvm:vm-9201-disk-3,mp=/var/lib/felhom,backup=1,size=250G
mp8: /mnt/felhom-drives,mp=/mnt/felhom-drives
mp9: /var/lib/felhom-agent/guests/9201/bootstrap,mp=/etc/felhom-bootstrap,ro=1
Tier 2 with ONE data drive (backup/tier2.go selectTier2TargetFrom): no other drive -> the internal SSD, STATE-ONLY set (never the optional media/torrents), and only if the SSD has headroom; so no film or download reaches tier 2 on the N100 today.
@@ -0,0 +1,9 @@
{'path': '/mnt/felhom-drives/hdd_1', 'label': 'NVME 1TB', 'is_default': True, 'schedulable': True}
{'path': '/mnt/sizing-bench', 'label': 'Tárhely (sizing-bench)', 'schedulable': True}
total 16
drwxr-xr-x 4 root root 4096 Oct 15 01:30 .
drwxr-xr-x 5 root root 4096 Oct 14 20:43 ..
drwxr-xr-x 3 root root 4096 Oct 15 01:30 backups
drwxrwsr-x 6 root 1000 4096 Oct 14 20:43 userdata
2026/10/15 14:41:46 info.go:13: [DEBUG] [system] GetDiskUsage: path="/mnt/sizing-bench" total=31.2 GB used=1.3 GB avail=28.3GB (4.3%)
2026/10/15 14:42:21 info.go:13: [DEBUG] [system] GetDiskUsage: path="/mnt/sizing-bench" total=31.2 GB used=1.3 GB avail=28.3GB (4.3%)
@@ -0,0 +1,9 @@
16:44:24 POST /settings/storage/remove storage_path=/mnt/sizing-bench -> HTTP/2 302 | location: /storage?storage_msg=success&storage_detail=Adatt%C3%A1rol%C3%B3+elt%C3%A1vol%C3%ADtva%3A+%2Fmnt%2Fsizing-bench
2
2026/10/15 14:44:24 settings.go:1632: [INFO] [settings] Removed storage path: /mnt/sizing-bench
2026/10/15 14:44:24 handlers.go:3527: [INFO] [web] Storage path removed: /mnt/sizing-bench
2026/10/15 14:44:25 handlers.go:3805: [INFO] [web] FileBrowser mounts synced (recreated) — 1 storage path(s), config updated
/app_backup/calibre-web/cross_drive/destination_path = /mnt/sizing-bench
/app_backup/paperless-ngx/cross_drive/destination_path = /mnt/sizing-bench
storage paths now: ['/mnt/felhom-drives/hdd_1']
@@ -0,0 +1,3 @@
14:56:26 atus-dot-nominal"> Demo HP OK 1 1 just now 28% 26% 27%/22% 17/17 –
[exited with code 0]
@@ -0,0 +1,19 @@
# The N100 becomes the lived-in box (2026-10-15)
Rule: `architecture/09-update-architecture.md` §3 decision 254. Diary: `documentation/lived-in/n100.md`.
Read first: `runbooks/target-selection.md`, `operations/nodes.md`, `07-backup-architecture.md`, `15-media-library.md`.
| folder | what |
|---|---|
| `B/01-state.txt` | the host and guest: versions, memory, disks, `/dev/dri` (host yes, guest no) |
| `B/02-drive.txt`, `B/03-drive-detail.txt` | the USB drive (ADATA HD710 PRO / TOSHIBA MQ04ABF100 `65NOP3HDT`) and its 6.2 GB: vzdumps, app backups, leftovers — no family files; PVE storage `felhom-backup` = the whole-guest backup target |
| `B/04-sizing.txt` | the five media apps by the estimator's rule: ~2 GB needed of 12 GB |
| `B/05-dashboard-view.txt` | the dashboard's own view: one enrolled drive, `backup_target: true`, off-site on (182 KB) |
| `B/06-deploy-fields.txt` | the install fields per app |
| `D/01-install.txt` | qBittorrent, Prowlarr, Sonarr, Radarr through the deploy call — no drive sent; the box chose `hdd_1` |
| `D/02-stranger.txt` | a stranger from the internet: the gate on Prowlarr/Sonarr/Radarr; qBittorrent's own login page and 403 API |
| `D/03-wiring.txt` | what the box wired, from the apps' own APIs |
| `D/04-app-backup-settings.txt`, `D/05-capture-sets.txt` | **Part C:** the controller's classifier over the deployed files — off-site takes no media; tier 2 only qBittorrent's downloads and only if switched on (not on; with one drive state-only to the SSD); vzdump excludes the drives |
| `F/` | demo-hp: `/mnt/sizing-bench` removed through the dashboard; the hub's next report |
| `SHEET.md` | the operator's sheet |
| `tools/` | `n100.py` (the box-walk library pointed at the N100), `install_media.py`, `read_wiring.py` |
@@ -0,0 +1,50 @@
# Your sheet — the N100 becomes the lived-in box (about 30 minutes)
Do these when it suits you. Use one browser. Sign in to the dashboard first: then the apps let you through.
## 1. The addresses
- Dashboard: **https://felhom.demo-felhom.eu**
- qBittorrent: **https://torrent.demo-felhom.eu**
- Prowlarr: **https://prowlarr.demo-felhom.eu**
- Sonarr: **https://sonarr.demo-felhom.eu**
- Radarr: **https://radarr.demo-felhom.eu**
- Plex (after you install it): **https://plex.demo-felhom.eu**
## 2. Plex
1. Dashboard → Alkalmazások → Plex → install. It asks no code.
2. Wait until Plex runs. Open Plex's page in the dashboard.
3. Open **plex.tv/claim**. Copy the code. Paste it on Plex's page within 4 minutes.
4. The box opens Plex by itself when Plex is claimed. If it asks, press „Kész, beállítottam".
5. Wait 2 minutes. Open Plex. **If Plex shows no library,** press „Bekötés most" on the dashboard (the card about the
drives and the apps), and tell me that you had to. (I expect this; it is R-1065.)
## 3. Prowlarr, Sonarr, Radarr
1. Open each address. The app asks you to make its admin login. Make one for each.
2. On each app's page in the dashboard, press „Kész, beállítottam". Until you do, only you can reach the app.
3. Add your download sources **in Prowlarr only.** They reach Sonarr and Radarr by themselves (the box linked them).
## 4. One show, one film
1. Sonarr: add one show. Radarr: add one film.
2. When they finish, open Plex. Check that both are there.
## 5. Passwords
- qBittorrent: user `admin`. The password is on qBittorrent's page in the dashboard (the password row, show button).
The same value is in a private file on DooPlex: `~/.felhom-demofelhom/qbittorrent-admin`.
- Prowlarr, Sonarr, Radarr, Plex: the logins you make. None is written here.
## 6. qBittorrent — the legal line
„Csak olyan tartalmat tölts le, amihez jogod van. A letöltés a háztartásod internetcíméről történik, és a torrent
természetéből adódóan a többi résztvevő látja a címedet."
## 7. Anything odd
Tell any CC session. It goes into the diary (`documentation/lived-in/n100.md`) and the register.
When you are done, say „done". I then read back: Plex claimed, its libraries, the show and the film imported as
hardlinks, and visible in Plex.
@@ -0,0 +1,26 @@
"""install_media.py — Part D1: qBittorrent, Prowlarr, Sonarr, Radarr through the dashboard's deploy call, with the fields
the wizard sends (no HDD_PATH for a media app — the box picks its drive). Admins and indexers are the operator's."""
import json, os, time, n100
w = n100.w
w.login()
for app in ("qbittorrent", "prowlarr", "sonarr", "radarr"):
if w.stack(app).get("deployed"):
print(f"{app}: already installed — skipped"); continue
c, d = w.ctl("GET", f"/api/stacks/{app}/deploy-fields")
fields = (((d.get("data") or {}).get("metadata") or {}).get("deploy_fields")) or []
sub = next((f.get("default") for f in fields if f.get("env_var") == "SUBDOMAIN"), None) or app
values = {"DOMAIN": w.DOMAIN, "SUBDOMAIN": sub}
if any(f.get("env_var") == "QBT_ADMIN_PASSWORD" for f in fields):
values["QBT_ADMIN_PASSWORD"] = open(os.path.expanduser("~/.felhom-demofelhom/qbittorrent-admin")).read().strip()
t0 = time.time()
code, d = w.ctl("POST", f"/api/stacks/{app}/deploy", {"values": values})
print(f"{time.strftime('%H:%M:%S')} {app}: deploy (fields sent: {sorted(values)}) -> {code} {json.dumps(d, ensure_ascii=False)[:120]}")
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") in ("running", "unhealthy"):
break
st = w.stack(app)
hdd = w.guest(f"grep -E '^\\s*HDD_PATH:' /opt/docker/stacks/{app}/app.yaml | head -1").strip()
print(f" {app}: state={st.get('state')} after {time.time()-t0:.0f}s; pinned={(st.get('app_config') or {}).get('pinned_images')}; {hdd}")
print(w.guest("docker ps --format '{{.Names}} {{.Status}}' | sort"))
@@ -0,0 +1,12 @@
"""n100.py — the box-walk library pointed at the N100 (demo-felhom guest 9201). Import this, not box_walk, for the N100.
box_walk.py has no demo-felhom row; this overrides the target AFTER import (no catalog change). Every call is the
dashboard's own endpoint, as box_walk documents."""
import os, sys
os.environ.setdefault("TARGET", "9201")
os.environ.setdefault("SC", os.path.expanduser("~/.felhom-demofelhom"))
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
import box_walk as w # noqa: E402
w._T = {"hp": "demo-felhom", "ssh": "felhom-pve", "jump": None, "guest": "9201",
"base": "https://192.168.0.149", "domain": "demo-felhom.eu"}
w.GUEST, w.BASE, w.DOMAIN, w.HP = "9201", "https://192.168.0.149", "demo-felhom.eu", "demo-felhom"
w.HOSTHDR = "Host: felhom.demo-felhom.eu"
@@ -0,0 +1,23 @@
"""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])