Media drive events, night: K1 (nothing lost while a drive is gone), K2 (Media C made ready by script, idempotent), K3 (safe removal is not safe while media apps run), K5 part (restart after added/returned)
gates / gates (push) Successful in 6m48s
gates / gates (push) Successful in 6m48s
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/mnt/felhom-drives/media_a/userdata/media/tv/Avatar - Seven Havens/Season 1/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE.mkv 909464483 4194364 2 1791997622
|
||||
/mnt/felhom-drives/media_a/userdata/media/tv/Avatar - Seven Havens/Season 1/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE.mkv 720261766 4194368 2 1791997651
|
||||
/mnt/felhom-drives/media_a/userdata/media/tv/Avatar - Seven Havens/Season 1/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE.mkv 829645981 4194375 2 1791997623
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE.mkv 909464483 4194364 2 1791997622
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE/avatar.seven.havens.s01e01.1080p.web.h264-grace.nfo 497 4194376 1 1791997577
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE/Sample/avatar.seven.havens.s01e01.1080p.web.h264-grace.sample.mkv 35166429 4194366 1 1791997623
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb.mkv 3789544605 4194398 1 1791997839
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb.nfo 62 4194400 1 1791997834
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E03.1080p.WEB.H264-CAKES/slow.horses.s06e03.1080p.web.h264-cakes.mkv 3931160378 4194385 1 1791997887
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E03.1080p.WEB.H264-CAKES/slow.horses.s06e03.1080p.web.h264-cakes.nfo 2728 4194367 1 1791997882
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E03.1080p.WEB.H264-CAKES/Sample/slow.horses.s06e03.1080p.web.h264-cakes-sample.mkv 85809338 4194392 1 1791997778
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL/slow.horses.s06e02.proper.1080p.web.h264-ethel.nfo 1023 4194397 1 1791997846
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL.mkv 3758255491 4194369 1 1791997854
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL/Sample/slow.horses.s06e02.proper.1080p.web.h264-ethel.sample.mkv 77743753 4194383 1 1791997852
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE.mkv 720261766 4194368 2 1791997651
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE/avatar.seven.havens.s01e03.1080p.web.h264-grace.nfo 492 4194377 1 1791997591
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE/Sample/avatar.seven.havens.s01e03.1080p.web.h264-grace.sample.mkv 21739818 4194370 1 1791997622
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/movies/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L.nfo 602 4194405 1 1791997982
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/movies/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L.mkv 4697542077 4194391 2 1791997988
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E04.1080p.WEB.H264-CAKES/slow.horses.s06e04.1080p.web.h264-cakes.mkv 4039934637 4194396 1 1791997987
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E04.1080p.WEB.H264-CAKES/slow.horses.s06e04.1080p.web.h264-cakes.nfo 2730 4194399 1 1791997757
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E04.1080p.WEB.H264-CAKES/Sample/slow.horses.s06e04.1080p.web.h264-cakes-sample.mkv 94200139 4194395 1 1791997773
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E01.1080p.WEB.H264-CAKES/slow.horses.s06e01.1080p.web.h264-cakes.mkv 3859110437 4194387 1 1791997961
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E01.1080p.WEB.H264-CAKES/slow.horses.s06e01.1080p.web.h264-cakes.nfo 2693 4194388 1 1791997744
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E01.1080p.WEB.H264-CAKES/Sample/slow.horses.s06e01.1080p.web.h264-cakes-sample.mkv 104128605 4194390 1 1791997759
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE/avatar.seven.havens.s01e02.1080p.web.h264-grace.nfo 497 4194374 1 1791997576
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE.mkv 829645981 4194375 2 1791997623
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE/Sample/avatar.seven.havens.s01e02.1080p.web.h264-grace.sample.mkv 31210978 4194373 1 1791997609
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/movies/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY.mkv 2819947717 4194408 1 1791998428
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/movies/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY.nfo 8091 4194409 1 1791998340
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/movies/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY/Sample/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY-Sample.mkv 22742740 4194411 1 1791998422
|
||||
/mnt/felhom-drives/media_a/userdata/media/movies/Hope (2026)/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L.mkv 4697542077 4194391 2 1791997988
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/movies/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX.mkv 3393846457 1048578 2 1791998022
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/movies/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX.nfo 619 1048579 1 1791998019
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 68 131101 1 1791997602
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E01.13.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1314062473 131100 2 1791997680
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E03.Rauhnacht.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 813589489 131110 2 1791997659
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 68 131113 1 1791997627
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E07.The.Baddest.Witch.of.Them.All.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 956532263 393221 2 1791997699
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 67 393223 1 1791997690
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E05.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E05.Date.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 969653267 393218 2 1791997719
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E05.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E05.Date.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.nfo 77 393220 1 1791997712
|
||||
/mnt/felhom-drives/media_b/userdata/media/movies/Matchbox the Movie (2026)/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX.mkv 3393846457 1048578 2 1791998022
|
||||
/mnt/felhom-drives/media_b/userdata/media/movies/WHO (2026)/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY.mkv 2819947717 2097156 1 1791998428
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E04.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1164079593 131107 2 1791997676
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1314062473 131100 2 1791997680
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E06.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 913481011 131112 2 1791997757
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 956532263 393221 2 1791997699
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 813589489 131110 2 1791997659
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1274167804 131103 2 1791997733
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E05.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 969653267 393218 2 1791997719
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1149433990 262146 2 1791997741
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb.mkv 3789544605 524295 1 1791997839
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E01.1080p.WEB.H264-CAKES.mkv 3859110437 524298 1 1791997961
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E04.1080p.WEB.H264-CAKES.mkv 4039934637 524299 1 1791997987
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL.mkv 3758255491 524296 1 1791997854
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E03.1080p.WEB.H264-CAKES.mkv 3931160378 524297 1 1791997887
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E02.1.13.AM.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1274167804 131103 2 1791997733
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 68 131104 1 1791997605
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E04.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E04.Is.That.All.There.Is.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1164079593 131107 2 1791997676
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E04.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E04.Is.That.All.There.Is.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.nfo 67 131108 1 1791997615
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E08.Hell.No.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1149433990 262146 2 1791997741
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 67 262147 1 1791997643
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E06.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E06.The.Return.of.Devils.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 913481011 131112 2 1791997757
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E06.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E06.The.Return.of.Devils.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.nfo 93 131114 1 1791997633
|
||||
|
||||
|
@@ -0,0 +1,13 @@
|
||||
# K1 predictions — written before the detach (2026-10-14 ~23:00 CEST)
|
||||
|
||||
With Media B detached (the guest keeps a dead mount; reads give I/O errors — S5):
|
||||
- a. Plex scan with autoEmptyTrash OFF: B's items stay, their parts unavailable. With it ON (the default): the scan
|
||||
REMOVES the B shows/films (American Horror Story, Matchbox, Who) and the B half of Slow Horses — or, because the
|
||||
folder answers I/O errors rather than „empty", Plex may refuse to treat it as gone and keep everything. Jellyfin
|
||||
scan: removes B's items. After re-attach + restart + rescan: items come back as NEW entries; Plex's watch count on
|
||||
the probe episode is lost unless Plex matches it again by GUID (Plex keeps view state per GUID — it may survive).
|
||||
- b. Sonarr/Radarr refresh+rescan: the B root folder is inaccessible; Sonarr's own failsafe („root folder is empty —
|
||||
rescan will not update") keeps the files' records; nothing is unmonitored (the option is off). With the option ON:
|
||||
still nothing, if the failsafe holds.
|
||||
- c. After re-attach + stop/start: qBittorrent and Transmission recheck or show „missing files" for B's torrents for a
|
||||
moment, then continue without re-downloading.
|
||||
@@ -0,0 +1,5 @@
|
||||
plex probe before: viewCount=3
|
||||
plex scrobble -> 200
|
||||
jellyfin probe before: Played=False
|
||||
jellyfin played -> 200
|
||||
after: plex viewCount=4 | jellyfin Played=True
|
||||
@@ -0,0 +1,35 @@
|
||||
Oct 14, 2026 22:55:55.191 [137446263175992] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.195 [137446267394872] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.321 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2097 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.325 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2098 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.333 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2099 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.405 [137446265285432] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.413 [137446267394872] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.443 [137446263175992] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.539 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2107 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.556 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2106 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.583 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2112 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.606 [137446267394872] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.614 [137446265285432] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.639 [137446263175992] DEBUG - [JobRunner] Job running: FFMPEG_EXTERNAL_LIBS='/config/Library/Application\ Support/Plex\ Media\ Server/Codecs/e613bce-97f23d579c1001d8e9cc0d2e-linux-x86_64/' X_PLEX_TOKEN=xxxxxx
|
||||
Oct 14, 2026 22:55:55.783 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2115 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.790 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2121 is 0 (success)
|
||||
Oct 14, 2026 22:55:55.810 [137446322166584] DEBUG - Jobs: '/usr/lib/plexmediaserver/Plex Media Scanner' exit code for process 2116 is 0 (success)
|
||||
Oct 14, 2026 22:56:01.730 [137446282160952] DEBUG - Request: [172.18.0.1:44862 (Subnet)] GET /library/sections/1/all?includeMissing=1 (2 live) #5df Signed-in Token (<plex user>) (Tester1 - server)
|
||||
Oct 14, 2026 22:56:01.730 [137446282160952] WARN - [Req#5df] Missing X-Plex-Container-Size header. This will fail with status code 400 in the future.
|
||||
Oct 14, 2026 22:56:01.735 [137446311959352] DEBUG - Completed: [172.18.0.1:44862] 200 GET /library/sections/1/all?includeMissing=1 (2 live) #5df 5ms 6611 bytes
|
||||
Oct 14, 2026 22:56:01.770 [137446282160952] DEBUG - Request: [172.18.0.1:44884 (Subnet)] GET /library/sections/2/all?includeMissing=1 (2 live) #5e7 Signed-in Token (<plex user>) (Tester1 - server)
|
||||
Oct 14, 2026 22:56:01.770 [137446282160952] WARN - [Req#5e7] Missing X-Plex-Container-Size header. This will fail with status code 400 in the future.
|
||||
Oct 14, 2026 22:56:01.776 [137446311959352] DEBUG - Completed: [172.18.0.1:44884] 200 GET /library/sections/2/all?includeMissing=1 (2 live) #5e7 5ms 4955 bytes
|
||||
Oct 14, 2026 22:56:01.820 [137446282160952] WARN - [Req#5f3] Missing X-Plex-Container-Size header. This will fail with status code 400 in the future.
|
||||
Oct 14, 2026 22:56:01.829 [137446282160952] WARN - [Req#5f7] Missing X-Plex-Container-Size header. This will fail with status code 400 in the future.
|
||||
PMS Plugin Logs
|
||||
Plex Crash Uploader.1.log
|
||||
Plex Crash Uploader.2.log
|
||||
Plex Crash Uploader.log
|
||||
Plex Media Scanner Analysis.1.log
|
||||
Plex Media Scanner Analysis.2.log
|
||||
Plex Media Scanner Analysis.3.log
|
||||
Plex Media Scanner Analysis.4.log
|
||||
Plex Media Scanner Analysis.5.log
|
||||
Plex Media Scanner Analysis.log
|
||||
@@ -0,0 +1,47 @@
|
||||
### a1. Plex, autoEmptyTrash OFF
|
||||
plex autoEmptyTrash -> 200
|
||||
plex refresh section 1 -> 200
|
||||
plex refresh section 2 -> 200
|
||||
plex scan done 20:55:50
|
||||
--- 20:55:51 state
|
||||
plex movie Hope items=1 parts=1 unavailable=0
|
||||
plex movie Matchbox the Movie items=1 parts=1 unavailable=0
|
||||
plex movie Who items=1 parts=1 unavailable=0
|
||||
plex show American Horror Story items=8 parts=8 unavailable=0
|
||||
plex show Avatar: Seven Havens items=3 parts=3 unavailable=0
|
||||
plex show Slow Horses items=5 parts=5 unavailable=0
|
||||
plex probe: viewCount=4
|
||||
### a2. Plex, autoEmptyTrash ON (the default)
|
||||
plex autoEmptyTrash -> 200
|
||||
plex refresh section 1 -> 200
|
||||
plex refresh section 2 -> 200
|
||||
plex scan done 20:56:00
|
||||
--- 20:56:01 state
|
||||
plex movie Hope items=1 parts=1 unavailable=0
|
||||
plex movie Matchbox the Movie items=1 parts=1 unavailable=0
|
||||
plex movie Who items=1 parts=1 unavailable=0
|
||||
plex show American Horror Story items=8 parts=8 unavailable=0
|
||||
plex show Avatar: Seven Havens items=3 parts=3 unavailable=0
|
||||
plex show Slow Horses items=5 parts=5 unavailable=0
|
||||
plex probe: viewCount=4
|
||||
checkFiles=1 Hope parts=1 accessible=[True] exists=['True']
|
||||
checkFiles=1 Matchbox the Movie parts=1 accessible=[False] exists=['False']
|
||||
checkFiles=1 Who parts=1 accessible=[False] exists=['False']
|
||||
checkFiles=1 American Horror Story parts=8 accessible=[None, None, None, None, None, None, None, None] exists=['None']
|
||||
checkFiles=1 Avatar: Seven Havens parts=3 accessible=[None, None, None] exists=['None']
|
||||
checkFiles=1 Slow Horses parts=5 accessible=[None, None, None, None, None] exists=['None']
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.583 [131834519904000] DEBUG - [MI] * fc9137b652c38e8de1b20c288b8f4926fbd4377b [mkv h264/eac3] Duration: 1472736ms, 1920x1080 (1.777778) 23.976fps, bitrate=4962kbps, audio channe
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.583 [131834519904000] DEBUG - [MI] Closing input file: "/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E06.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.586 [131834519904000] DEBUG - Updating part with ID=34 [/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E06.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.602 [131834519904000] DEBUG - [ID 35] Media part analysis: /mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WE
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.602 [131834519904000] DEBUG - [MI] Opening input file: "/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.602 [131834519904000] DEBUG - [FFMPEG] - Opening '/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.644 [131834519904000] DEBUG - [MI] * c53e1ba1643469bcce4cfb4fc900238d99edb69d [mkv h264/eac3] Duration: 1385728ms, 1920x1080 (1.777778) 23.976fps, bitrate=5522kbps, audio channe
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.645 [131834519904000] DEBUG - [MI] Closing input file: "/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.657 [131834519904000] DEBUG - Updating part with ID=35 [/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.690 [131834519904000] DEBUG - [ID 36] Media part analysis: /mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WE
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.690 [131834519904000] DEBUG - [MI] Opening input file: "/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.690 [131834519904000] DEBUG - [FFMPEG] - Opening '/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.733 [131834519904000] DEBUG - [MI] * 03ec86569979824516a2e8ae2033abdaf107fd94 [mkv h264/eac3] Duration: 1828608ms, 1920x1080 (1.777778) 23.976fps, bitrate=5028kbps, audio channe
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.733 [131834519904000] DEBUG - [MI] Closing input file: "/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WEB-D
|
||||
scanner: Plex Media Scanner Analysis.1.log Oct 14, 2026 19:15:45.736 [131834519904000] DEBUG - Updating part with ID=36 [/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WEB-D
|
||||
@@ -0,0 +1,40 @@
|
||||
### a3. Jellyfin scan
|
||||
jellyfin /Library/Refresh -> 204
|
||||
jellyfin scan done 20:56:43
|
||||
--- 20:56:44 state
|
||||
jellyfin: {'Series': 3, 'Movie': 3, 'Episode': 16} ['Amerikai Horror Story', 'Avatar: Seven Havens', 'Hope - Remény', 'Matchbox', 'Roger nyúl a pácban', 'Utolsó befutók']
|
||||
jellyfin probe: Played=True
|
||||
### b1. Sonarr/Radarr refresh + rescan, unmonitor OFF (default)
|
||||
sonarr RefreshSeries -> 201 completed
|
||||
sonarr RescanSeries -> 201 completed
|
||||
radarr RefreshMovie -> 201 completed
|
||||
radarr RescanMovie -> 201 completed
|
||||
--- 20:57:00 state
|
||||
sonarr Avatar: Seven Havens monitored=True files=3 path=media_a
|
||||
sonarr American Horror Story monitored=True files=8 path=media_b
|
||||
sonarr Slow Horses monitored=True files=5 path=media_b
|
||||
Avatar: Seven Havens episodes monitored=13/13 hasFile=3
|
||||
American Horror Story episodes monitored=13/166 hasFile=8
|
||||
Slow Horses episodes monitored=6/39 hasFile=5
|
||||
radarr Hope monitored=True files=True path=media_a
|
||||
radarr Matchbox the Movie monitored=True files=True path=media_b
|
||||
radarr WHO monitored=True files=True path=media_b
|
||||
### b2. the same with unmonitor ON
|
||||
sonarr autoUnmonitorPreviouslyDownloadedEpisodes=True -> 202
|
||||
radarr autoUnmonitorPreviouslyDownloadedMovies=True -> 202
|
||||
sonarr RefreshSeries -> 201 completed
|
||||
sonarr RescanSeries -> 201 completed
|
||||
radarr RefreshMovie -> 201 completed
|
||||
radarr RescanMovie -> 201 completed
|
||||
--- 20:57:17 state
|
||||
sonarr Avatar: Seven Havens monitored=True files=3 path=media_a
|
||||
sonarr American Horror Story monitored=True files=8 path=media_b
|
||||
sonarr Slow Horses monitored=True files=5 path=media_b
|
||||
Avatar: Seven Havens episodes monitored=13/13 hasFile=3
|
||||
American Horror Story episodes monitored=13/166 hasFile=8
|
||||
Slow Horses episodes monitored=6/39 hasFile=5
|
||||
radarr Hope monitored=True files=True path=media_a
|
||||
radarr Matchbox the Movie monitored=True files=True path=media_b
|
||||
radarr WHO monitored=True files=True path=media_b
|
||||
sonarr autoUnmonitorPreviouslyDownloadedEpisodes=False -> 202
|
||||
radarr autoUnmonitorPreviouslyDownloadedMovies=False -> 202
|
||||
@@ -0,0 +1,20 @@
|
||||
2026-10-14T22:59:00+02:00
|
||||
scsi3: nvme-scratch:341/vm-341-disk-4.raw,backup=0,size=100G
|
||||
2026/10/14 20:59:32 [INFO] [gate] drive RETURNED /mnt/felhom-drives/media_b — re-attached + restarted gate-stopped apps
|
||||
2026/10/14 20:59:32 [INFO] Event pushed: storage_reconnected (info) [hu-only] — Meghajtó újra csatlakoztatva: Media B
|
||||
`-/mnt/felhom-drives/media_b /dev/sdf[/felhom-data]
|
||||
|-/mnt/felhom-drives/media_b /dev/sdf[/felhom-data]
|
||||
|
||||
qbittorrent stop -> 200
|
||||
transmission stop -> 200
|
||||
sonarr stop -> 200
|
||||
radarr stop -> 200
|
||||
plex stop -> 200
|
||||
jellyfin stop -> 200
|
||||
qbittorrent start -> 200
|
||||
transmission start -> 200
|
||||
sonarr start -> 200
|
||||
radarr start -> 200
|
||||
plex start -> 200
|
||||
jellyfin start -> 200
|
||||
stop+start of six apps took 40s (incl. 10s pause)
|
||||
@@ -0,0 +1,16 @@
|
||||
21:00:49 qbit: {'tv-drive-b:queuedUP': 2, 'tv-drive-a:stalledUP': 1, 'movies-drive-a:queuedUP': 1, 'tv-drive-a:queuedUP': 4, 'tv-drive-b:stalledUP': 2, 'movies-drive-b:queuedUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:01:03 qbit: {'tv-drive-b:queuedUP': 2, 'tv-drive-a:stalledUP': 1, 'movies-drive-a:queuedUP': 1, 'tv-drive-a:queuedUP': 4, 'tv-drive-b:stalledUP': 2, 'movies-drive-b:queuedUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:01:17 qbit: {'tv-drive-b:queuedUP': 3, 'tv-drive-a:queuedUP': 3, 'movies-drive-a:queuedUP': 1, 'tv-drive-a:stalledUP': 2, 'movies-drive-b:queuedUP': 1, 'tv-drive-b:stalledUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:01:30 qbit: {'tv-drive-b:queuedUP': 3, 'tv-drive-a:queuedUP': 3, 'movies-drive-a:queuedUP': 1, 'tv-drive-a:stalledUP': 2, 'movies-drive-b:queuedUP': 1, 'tv-drive-b:stalledUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:01:44 qbit: {'tv-drive-b:stalledUP': 1, 'tv-drive-a:queuedUP': 4, 'movies-drive-a:queuedUP': 1, 'tv-drive-a:stalledUP': 1, 'tv-drive-b:queuedUP': 3, 'movies-drive-b:stalledUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:01:58 qbit: {'tv-drive-b:stalledUP': 1, 'tv-drive-a:queuedUP': 4, 'movies-drive-a:queuedUP': 1, 'tv-drive-a:stalledUP': 1, 'tv-drive-b:queuedUP': 3, 'movies-drive-b:stalledUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:02:12 qbit: {'tv-drive-b:queuedUP': 4, 'tv-drive-a:queuedUP': 3, 'movies-drive-a:stalledUP': 1, 'tv-drive-a:stalledUP': 2, 'movies-drive-b:queuedUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
21:02:25 qbit: {'tv-drive-b:queuedUP': 4, 'tv-drive-a:queuedUP': 3, 'movies-drive-a:stalledUP': 1, 'tv-drive-a:stalledUP': 2, 'movies-drive-b:queuedUP': 1}
|
||||
transmission: {'media_a:status6': 4, 'media_b:status6': 4}
|
||||
@@ -0,0 +1,7 @@
|
||||
2026-10-14T22:54:48+02:00
|
||||
update VM 341: -delete scsi3
|
||||
unused0: nvme-scratch:341/vm-341-disk-4.raw
|
||||
2026/10/14 20:55:01 [INFO] [settings] Storage path /mnt/felhom-drives/media_b disconnected=true
|
||||
2026/10/14 20:55:01 [WARN] [gate] drive ABSENT /mnt/felhom-drives/media_b — stopped+blocked 0 app(s): []
|
||||
2026/10/14 20:55:01 [INFO] Event pushed: storage_disconnected (error) [hu-only] — Meghajtó váratlanul leválasztva: Media B
|
||||
20:55:33 up 5:27, 0 users, load average: 0.60, 0.56, 0.55
|
||||
@@ -0,0 +1,66 @@
|
||||
/mnt/felhom-drives/media_a/userdata/media/tv/Avatar - Seven Havens/Season 1/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE.mkv 909464483 4194364 2 1791997622
|
||||
/mnt/felhom-drives/media_a/userdata/media/tv/Avatar - Seven Havens/Season 1/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE.mkv 720261766 4194368 2 1791997651
|
||||
/mnt/felhom-drives/media_a/userdata/media/tv/Avatar - Seven Havens/Season 1/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE.mkv 829645981 4194375 2 1791997623
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE.mkv 909464483 4194364 2 1791997622
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE/avatar.seven.havens.s01e01.1080p.web.h264-grace.nfo 497 4194376 1 1791997577
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E01.1080p.WEB.h264-GRACE/Sample/avatar.seven.havens.s01e01.1080p.web.h264-grace.sample.mkv 35166429 4194366 1 1791997623
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb.mkv 3789544605 4194398 1 1791997839
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb.nfo 62 4194400 1 1791997834
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E03.1080p.WEB.H264-CAKES/slow.horses.s06e03.1080p.web.h264-cakes.mkv 3931160378 4194385 1 1791997887
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E03.1080p.WEB.H264-CAKES/slow.horses.s06e03.1080p.web.h264-cakes.nfo 2728 4194367 1 1791997882
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E03.1080p.WEB.H264-CAKES/Sample/slow.horses.s06e03.1080p.web.h264-cakes-sample.mkv 85809338 4194392 1 1791997778
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL/slow.horses.s06e02.proper.1080p.web.h264-ethel.nfo 1023 4194397 1 1791997846
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL.mkv 3758255491 4194369 1 1791997854
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL/Sample/slow.horses.s06e02.proper.1080p.web.h264-ethel.sample.mkv 77743753 4194383 1 1791997852
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE.mkv 720261766 4194368 2 1791997651
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE/avatar.seven.havens.s01e03.1080p.web.h264-grace.nfo 492 4194377 1 1791997591
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/tv/Avatar.Seven.Havens.S01E03.1080p.WEB.h264-GRACE/Sample/avatar.seven.havens.s01e03.1080p.web.h264-grace.sample.mkv 21739818 4194370 1 1791997622
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/movies/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L.nfo 602 4194405 1 1791997982
|
||||
/mnt/felhom-drives/media_a/userdata/media/torrents/movies/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L.mkv 4697542077 4194391 2 1791997988
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E04.1080p.WEB.H264-CAKES/slow.horses.s06e04.1080p.web.h264-cakes.mkv 4039934637 4194396 1 1791997987
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E04.1080p.WEB.H264-CAKES/slow.horses.s06e04.1080p.web.h264-cakes.nfo 2730 4194399 1 1791997757
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E04.1080p.WEB.H264-CAKES/Sample/slow.horses.s06e04.1080p.web.h264-cakes-sample.mkv 94200139 4194395 1 1791997773
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E01.1080p.WEB.H264-CAKES/slow.horses.s06e01.1080p.web.h264-cakes.mkv 3859110437 4194387 1 1791997961
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E01.1080p.WEB.H264-CAKES/slow.horses.s06e01.1080p.web.h264-cakes.nfo 2693 4194388 1 1791997744
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Slow.Horses.S06E01.1080p.WEB.H264-CAKES/Sample/slow.horses.s06e01.1080p.web.h264-cakes-sample.mkv 104128605 4194390 1 1791997759
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE/avatar.seven.havens.s01e02.1080p.web.h264-grace.nfo 497 4194374 1 1791997576
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE.mkv 829645981 4194375 2 1791997623
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/tv/Avatar.Seven.Havens.S01E02.1080p.WEB.h264-GRACE/Sample/avatar.seven.havens.s01e02.1080p.web.h264-grace.sample.mkv 31210978 4194373 1 1791997609
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/movies/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY.mkv 2819947717 4194408 1 1791998428
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/movies/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY.nfo 8091 4194409 1 1791998340
|
||||
/mnt/felhom-drives/media_a/userdata/media/transmission/movies/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY/Sample/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY-Sample.mkv 22742740 4194411 1 1791998422
|
||||
/mnt/felhom-drives/media_a/userdata/media/movies/Hope (2026)/Hope.2026.720p.AMZN.WEB-DL.DDP5.1.Atmos.H.264-N1H4L.mkv 4697542077 4194391 2 1791997988
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/movies/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX.mkv 3393846457 1048578 2 1791998022
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/movies/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX.nfo 619 1048579 1 1791998019
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 68 131101 1 1791997602
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E01.13.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1314062473 131100 2 1791997680
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E03.Rauhnacht.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 813589489 131110 2 1791997659
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 68 131113 1 1791997627
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E07.The.Baddest.Witch.of.Them.All.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 956532263 393221 2 1791997699
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 67 393223 1 1791997690
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E05.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E05.Date.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 969653267 393218 2 1791997719
|
||||
/mnt/felhom-drives/media_b/userdata/media/torrents/tv/American.Horror.Story.S13E05.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E05.Date.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.nfo 77 393220 1 1791997712
|
||||
/mnt/felhom-drives/media_b/userdata/media/movies/Matchbox the Movie (2026)/Matchbox.The.Movie.2026.720p.ATVP.WEB-DL.DDP5.1.Atmos.H.264-FLUX.mkv 3393846457 1048578 2 1791998022
|
||||
/mnt/felhom-drives/media_b/userdata/media/movies/WHO (2026)/Who.2026.720p.DSNP.WEB-DL.DDP5.1.H.264.HuNSUB-TRiNiTY.mkv 2819947717 2097156 1 1791998428
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E04.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1164079593 131107 2 1791997676
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E01.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1314062473 131100 2 1791997680
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E06.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 913481011 131112 2 1791997757
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E07.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 956532263 393221 2 1791997699
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E03.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 813589489 131110 2 1791997659
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1274167804 131103 2 1791997733
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E05.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 969653267 393218 2 1791997719
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/American Horror Story/Season 13/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.mkv 1149433990 262146 2 1791997741
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E05.Sayonara.1080p.ATVP.WEB-DL.DDP5.1.H.264-NTb.mkv 3789544605 524295 1 1791997839
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E01.1080p.WEB.H264-CAKES.mkv 3859110437 524298 1 1791997961
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E04.1080p.WEB.H264-CAKES.mkv 4039934637 524299 1 1791997987
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E02.PROPER.1080p.WEB.h264-ETHEL.mkv 3758255491 524296 1 1791997854
|
||||
/mnt/felhom-drives/media_b/userdata/media/tv/Slow Horses/Season 6/Slow.Horses.S06E03.1080p.WEB.H264-CAKES.mkv 3931160378 524297 1 1791997887
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E02.1.13.AM.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1274167804 131103 2 1791997733
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E02.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 68 131104 1 1791997605
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E04.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E04.Is.That.All.There.Is.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1164079593 131107 2 1791997676
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E04.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E04.Is.That.All.There.Is.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.nfo 67 131108 1 1791997615
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E08.Hell.No.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 1149433990 262146 2 1791997741
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E08.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB.nfo 67 262147 1 1791997643
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E06.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E06.The.Return.of.Devils.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.mkv 913481011 131112 2 1791997757
|
||||
/mnt/felhom-drives/media_b/userdata/media/transmission/tv/American.Horror.Story.S13E06.1080p.DSNP.WEB-DL.DDP5.1.H.264-PlayWEB/American.Horror.Story.S13E06.The.Return.of.Devils.Night.1080p.DSNP.WEB-DL.DD5.1.H.264-playWEB.nfo 93 131114 1 1791997633
|
||||
|
||||
|
@@ -0,0 +1,16 @@
|
||||
jellyfin stop -> 200
|
||||
jellyfin start -> 200 {'ok': True, 'data': {'state': 'starting'}, 'message': 'Stack jellyfin start requested — state now: starting'}
|
||||
running healthy started=2026-10-14T20:57:47.941764769Z err=
|
||||
ls: cannot access '/mnt/felhom-drives/media_b/userdata/media/tv': Input/output error
|
||||
ls: reading directory '/mnt/felhom-drives/media_b': Input/output error
|
||||
total 0
|
||||
2026/10/14 20:57:47 [INFO] [stacks] Starting stack: jellyfin
|
||||
2026/10/14 20:57:48 [INFO] [stacks] Stack jellyfin started successfully (took 0.3s)
|
||||
2026/10/14 20:57:51 [INFO] [stacks] Stack jellyfin post-start status:
|
||||
2026/10/14 20:57:51 [INFO] [stacks] jellyfin jellyfin/jellyfin:10.11.11 running Up 3 seconds (health: starting)
|
||||
|
||||
jellyfin /Library/Refresh -> 204
|
||||
jellyfin scan done 20:58:40
|
||||
--- 20:58:41 state
|
||||
jellyfin: {'Series': 3, 'Movie': 3, 'Episode': 16} ['Amerikai Horror Story', 'Avatar: Seven Havens', 'Hope - Remény', 'Matchbox', 'Roger nyúl a pácban', 'Utolsó befutók']
|
||||
jellyfin probe: Played=True
|
||||
@@ -0,0 +1,16 @@
|
||||
plex prefs: (absent = default)
|
||||
plex FSEventLibraryUpdatesEnabled value= False default= False
|
||||
plex FSEventLibraryPartialScanEnabled value= False default= False
|
||||
plex ScheduledLibraryUpdatesEnabled value= False default= False
|
||||
plex ScheduledLibraryUpdateInterval value= 3600 default= 3600
|
||||
plex autoEmptyTrash value= True default= True
|
||||
sonarr {'autoUnmonitorPreviouslyDownloadedEpisodes': False, 'recycleBin': '', 'deleteEmptyFolders': False}
|
||||
radarr {'autoUnmonitorPreviouslyDownloadedMovies': False, 'recycleBin': '', 'deleteEmptyFolders': False}
|
||||
2 <EnableRealtimeMonitor>false
|
||||
config
|
||||
data
|
||||
log
|
||||
metadata
|
||||
plugins
|
||||
root
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
--- 20:53:46 state
|
||||
plex movie Hope items=1 parts=1 unavailable=0
|
||||
plex movie Matchbox the Movie items=1 parts=1 unavailable=0
|
||||
plex movie Who items=1 parts=1 unavailable=0
|
||||
plex show American Horror Story items=8 parts=8 unavailable=0
|
||||
plex show Avatar: Seven Havens items=3 parts=3 unavailable=0
|
||||
plex show Slow Horses items=5 parts=5 unavailable=0
|
||||
plex probe: viewCount=1
|
||||
jellyfin: {'Series': 3, 'Movie': 3, 'Episode': 16} ['Amerikai Horror Story', 'Avatar: Seven Havens', 'Hope - Remény', 'Matchbox', 'Roger nyúl a pácban', 'Utolsó befutók']
|
||||
jellyfin probe: episode gone
|
||||
sonarr Avatar: Seven Havens monitored=True files=3 path=media_a
|
||||
sonarr American Horror Story monitored=True files=8 path=media_b
|
||||
sonarr Slow Horses monitored=True files=5 path=media_b
|
||||
Avatar: Seven Havens episodes monitored=13/13 hasFile=3
|
||||
American Horror Story episodes monitored=13/166 hasFile=8
|
||||
Slow Horses episodes monitored=6/39 hasFile=5
|
||||
radarr Hope monitored=True files=True path=media_a
|
||||
radarr Matchbox the Movie monitored=True files=True path=media_b
|
||||
radarr WHO monitored=True files=True path=media_b
|
||||
@@ -0,0 +1,19 @@
|
||||
--- 21:02:50 state
|
||||
plex movie Hope items=1 parts=1 unavailable=0
|
||||
plex movie Matchbox the Movie items=1 parts=1 unavailable=0
|
||||
plex movie Who items=1 parts=1 unavailable=0
|
||||
plex show American Horror Story items=8 parts=8 unavailable=0
|
||||
plex show Avatar: Seven Havens items=3 parts=3 unavailable=0
|
||||
plex show Slow Horses items=5 parts=5 unavailable=0
|
||||
plex probe: viewCount=4
|
||||
jellyfin: {'Series': 3, 'Movie': 3, 'Episode': 16} ['Amerikai Horror Story', 'Avatar: Seven Havens', 'Hope - Remény', 'Matchbox', 'Roger nyúl a pácban', 'Utolsó befutók']
|
||||
jellyfin probe: Played=True
|
||||
sonarr Avatar: Seven Havens monitored=True files=3 path=media_a
|
||||
sonarr American Horror Story monitored=True files=8 path=media_b
|
||||
sonarr Slow Horses monitored=True files=5 path=media_b
|
||||
Avatar: Seven Havens episodes monitored=13/13 hasFile=3
|
||||
American Horror Story episodes monitored=13/166 hasFile=8
|
||||
Slow Horses episodes monitored=6/39 hasFile=5
|
||||
radarr Hope monitored=True files=True path=media_a
|
||||
radarr Matchbox the Movie monitored=True files=True path=media_b
|
||||
radarr WHO monitored=True files=True path=media_b
|
||||
@@ -0,0 +1,4 @@
|
||||
/dev/nvme0n1 938 192 699 22% /mnt/hdd_1
|
||||
scsi4: successfully created disk 'nvme-scratch:341/vm-341-disk-5.raw,backup=0,size=50G'
|
||||
scsi4: nvme-scratch:341/vm-341-disk-5.raw,backup=0,size=50G
|
||||
/dev/nvme0n1 938 192 699 22% /mnt/hdd_1
|
||||
@@ -0,0 +1,12 @@
|
||||
23:03:23 candidates -> 200 ['/dev/sde']
|
||||
23:03:23 POST /api/storage/init {"device": "/dev/sde", "fstype": "ext4", "mount_name": "media_c", "label": "Media C", "set_default": false, "confirmed": false, "durable_id": ""} -> 200 {"data": {"phase": "formatting", "started": true}, "ok": true}
|
||||
23:03:25 status -> 200 {"device": "/dev/sde", "durable_id": "", "error": "", "opsign": "", "phase": "mounting", "reason": "", "started_at": "2026-10-14T21:03:23.232663968Z", "updated_at": "2026-10-14T21:03:23.597372998Z", "where": "/mnt/media_c"}
|
||||
23:03:27 status -> 200 {"device": "/dev/sde", "durable_id": "", "error": "", "opsign": "", "phase": "done", "reason": "", "started_at": "2026-10-14T21:03:23.232663968Z", "updated_at": "2026-10-14T21:03:25.736060363Z", "where": "/mnt/felhom-drives/media_c"}
|
||||
RESULT done
|
||||
`-/mnt/felhom-drives/media_c /dev/sde[/felhom-data]
|
||||
`-/mnt/felhom-drives/media_c /dev/sde[/felhom-data]
|
||||
audiobooks books comics grimmory metube movies music nzbget photos podcasts tv usenet 2026/10/14 21:03:23 [INFO] [web] storage init "/mnt/media_c" started (device /dev/sde, fs ext4)
|
||||
2026/10/14 21:03:25 [INFO] [settings] Added storage path: /mnt/felhom-drives/media_c
|
||||
2026/10/14 21:03:25 [INFO] [web] storage init done: /mnt/felhom-drives/media_c registered (2503ms)
|
||||
2026/10/14 21:03:26 [INFO] [web] FileBrowser mounts synced (recreated) — 4 storage path(s), config updated
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/opt/docker/stacks/sonarr/docker-compose.yml:1
|
||||
/opt/docker/stacks/plex/docker-compose.yml:1
|
||||
2026/10/14 21:03:59 [INFO] [sync] Updated transmission/docker-compose.yml
|
||||
2026/10/14 21:03:59 [INFO] [sync] catalog moved b0fd3a033b4a -> 925f3fd9766b (0 new, 6 stack dir(s) changed)
|
||||
2026/10/14 21:03:59 [INFO] [sync] Catalog sync complete
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-rw-r--r-- 1 root root 145093 Oct 14 23:06 /tmp/probe.mkv
|
||||
/mnt/felhom-drives/media_c/userdata/media/tv/Felhom Probe Show (2026)/Season 01/Felhom Probe Show (2026) - S01E01.mkv 145093
|
||||
/mnt/felhom-drives/media_c/userdata/media/movies/Felhom Probe Film (2026)/Felhom Probe Film (2026).mkv 145093
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
no token, from another container: GET /library/sections -> 401
|
||||
no token, from another container: GET /:/prefs -> 401
|
||||
no token, from another container: GET /identity -> 200
|
||||
no token, from inside the Plex container (127.0.0.1): GET /library/sections -> 401
|
||||
Preferences.xml keys of interest: PlexOnlineToken=" customConnections=" PlexOnlineUsername="
|
||||
@@ -0,0 +1,155 @@
|
||||
== folders on media_a: all present
|
||||
== folders on media_b: all present
|
||||
== folders on media_c: made ['torrents', 'torrents/tv', 'torrents/movies', 'transmission', 'transmission/tv', 'transmission/movies']
|
||||
== qBittorrent http://172.18.0.2:8080 (password: the deploy secret, read from the container's environment)
|
||||
POST http://172.18.0.2:8080/api/v2/auth/login -> 204 ''
|
||||
session cookie name: QBT_SID_8080
|
||||
GET http://172.18.0.2:8080/api/v2/app/preferences -> 200 {add_stopped_enabled, add_to_top_of_queue, add_trackers, add_trackers_enabled, add_trackers_from_url_enabled, add_trackers_url, add_trackers_url_list, alt_dl_limit, alt_up_limit, alternative_webui_enabled, alternative_webui_path, announce_ip, announce_port, announce_to_all_tiers, announce_to_all_trac}
|
||||
before: auto_tmm_enabled=True save_path=/mnt/felhom-drives/media_a/userdata/media/torrents temp_path_enabled=True temp_path=/mnt/felhom-drives/media_a/userdata/media/torrents/.temp
|
||||
POST http://172.18.0.2:8080/api/v2/app/setPreferences -> 200 ''
|
||||
GET http://172.18.0.2:8080/api/v2/app/preferences -> 200 {add_stopped_enabled, add_to_top_of_queue, add_trackers, add_trackers_enabled, add_trackers_from_url_enabled, add_trackers_url, add_trackers_url_list, alt_dl_limit, alt_up_limit, alternative_webui_enabled, alternative_webui_path, announce_ip, announce_port, announce_to_all_tiers, announce_to_all_trac}
|
||||
after : auto_tmm_enabled=True (a category's save path applies only in automatic mode)
|
||||
GET http://172.18.0.2:8080/api/v2/torrents/categories -> 200 {movies-drive-a, movies-drive-b, tv-drive-a, tv-drive-b}
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/createCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/createCategory -> 200 ''
|
||||
GET http://172.18.0.2:8080/api/v2/torrents/categories -> 200 {movies-drive-a, movies-drive-b, movies-drive-c, tv-drive-a, tv-drive-b, tv-drive-c}
|
||||
category movies-drive-a: savePath=/mnt/felhom-drives/media_a/userdata/media/torrents/movies downloadPath=/mnt/felhom-drives/media_a/userdata/media/torrents/.temp
|
||||
category movies-drive-b: savePath=/mnt/felhom-drives/media_b/userdata/media/torrents/movies downloadPath=/mnt/felhom-drives/media_b/userdata/media/torrents/.temp
|
||||
category movies-drive-c: savePath=/mnt/felhom-drives/media_c/userdata/media/torrents/movies downloadPath=/mnt/felhom-drives/media_c/userdata/media/torrents/.temp
|
||||
category tv-drive-a: savePath=/mnt/felhom-drives/media_a/userdata/media/torrents/tv downloadPath=/mnt/felhom-drives/media_a/userdata/media/torrents/.temp
|
||||
category tv-drive-b: savePath=/mnt/felhom-drives/media_b/userdata/media/torrents/tv downloadPath=/mnt/felhom-drives/media_b/userdata/media/torrents/.temp
|
||||
category tv-drive-c: savePath=/mnt/felhom-drives/media_c/userdata/media/torrents/tv downloadPath=/mnt/felhom-drives/media_c/userdata/media/torrents/.temp
|
||||
== Transmission http://172.18.0.3:9091/transmission/rpc (password: the deploy secret, read from the container's environment)
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
before: {"download-dir": "/mnt/felhom-drives/media_a/userdata/media/transmission/complete", "incomplete-dir": "/mnt/felhom-drives/media_a/userdata/media/transmission/incomplete", "incomplete-dir-enabled": false, "rename-partial-files": true}
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
after : {"download-dir": "/mnt/felhom-drives/media_a/userdata/media/transmission/complete", "incomplete-dir-enabled": false, "rename-partial-files": true} (one incomplete folder for all torrents would be on drive A)
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
probe Host: transmission:9091 -> HTTP 200 {'arguments': {'version': '4.1.3 (838877323f)'}, 'result': 'success'}
|
||||
== sonarr http://172.18.0.5:8989/api/v3 (key: <ApiKey> in /config/config.xml, read from the config volume)
|
||||
GET http://172.18.0.5:8989/api/v3/tag -> 200 [list of 3]
|
||||
POST http://172.18.0.5:8989/api/v3/tag -> 201 {id, label}
|
||||
tags: {'driva-a': 3, 'drive-a': 1, 'drive-b': 2, 'drive-c': 4}
|
||||
GET http://172.18.0.5:8989/api/v3/rootfolder -> 200 [list of 2]
|
||||
POST http://172.18.0.5:8989/api/v3/rootfolder -> 201 {accessible, freeSpace, id, path, unmappedFolders}
|
||||
GET http://172.18.0.5:8989/api/v3/rootfolder -> 200 [list of 3]
|
||||
root folder: /mnt/felhom-drives/media_a/userdata/media/tv accessible=True freeSpace=69873070080
|
||||
root folder: /mnt/felhom-drives/media_b/userdata/media/tv accessible=True freeSpace=65554092032
|
||||
root folder: /mnt/felhom-drives/media_c/userdata/media/tv accessible=True freeSpace=49817907200
|
||||
GET http://172.18.0.5:8989/api/v3/downloadclient/schema -> 200 [list of 18]
|
||||
GET http://172.18.0.5:8989/api/v3/downloadclient -> 200 [list of 4]
|
||||
client qBittorrent drive-a: exists — left as it is
|
||||
client Transmission drive-a: exists — left as it is
|
||||
client qBittorrent drive-b: exists — left as it is
|
||||
client Transmission drive-b: exists — left as it is
|
||||
POST http://172.18.0.5:8989/api/v3/downloadclient -> 201 {configContract, enable, fields, id, implementation, implementationName, infoLink, name, priority, protocol, removeCompletedDownloads, removeFailedDownloads, tags}
|
||||
POST http://172.18.0.5:8989/api/v3/downloadclient -> 201 {configContract, enable, fields, id, implementation, implementationName, infoLink, name, priority, protocol, removeCompletedDownloads, removeFailedDownloads, tags}
|
||||
GET http://172.18.0.5:8989/api/v3/downloadclient -> 200 [list of 6]
|
||||
client qBittorrent drive-a: impl=QBittorrent enable=True tags=[1] host=qbittorrent category=tv-drive-a directory=None
|
||||
client qBittorrent drive-b: impl=QBittorrent enable=True tags=[2] host=qbittorrent category=tv-drive-b directory=None
|
||||
client qBittorrent drive-c: impl=QBittorrent enable=True tags=[4] host=qbittorrent category=tv-drive-c directory=None
|
||||
client Transmission drive-a: impl=Transmission enable=True tags=[1] host=transmission category= directory=/mnt/felhom-drives/media_a/userdata/media/transmission/tv
|
||||
client Transmission drive-b: impl=Transmission enable=True tags=[2] host=transmission category= directory=/mnt/felhom-drives/media_b/userdata/media/transmission/tv
|
||||
client Transmission drive-c: impl=Transmission enable=True tags=[4] host=transmission category= directory=/mnt/felhom-drives/media_c/userdata/media/transmission/tv
|
||||
GET http://172.18.0.5:8989/api/v3/config/mediamanagement -> 200 {autoUnmonitorPreviouslyDownloadedEpisodes, chmodFolder, chownGroup, copyUsingHardlinks, createEmptySeriesFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, episodeTitleRequired, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, recycleBin, recy}
|
||||
before: minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True
|
||||
PUT http://172.18.0.5:8989/api/v3/config/mediamanagement/1 -> 202 {autoUnmonitorPreviouslyDownloadedEpisodes, chmodFolder, chownGroup, copyUsingHardlinks, createEmptySeriesFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, episodeTitleRequired, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, recycleBin, recy}
|
||||
GET http://172.18.0.5:8989/api/v3/config/mediamanagement -> 200 {autoUnmonitorPreviouslyDownloadedEpisodes, chmodFolder, chownGroup, copyUsingHardlinks, createEmptySeriesFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, episodeTitleRequired, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, recycleBin, recy}
|
||||
after : minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True (default kept)
|
||||
== radarr http://172.18.0.7:7878/api/v3 (key: <ApiKey> in /config/config.xml, read from the config volume)
|
||||
GET http://172.18.0.7:7878/api/v3/tag -> 200 [list of 2]
|
||||
POST http://172.18.0.7:7878/api/v3/tag -> 201 {id, label}
|
||||
tags: {'drive-a': 1, 'drive-b': 2, 'drive-c': 3}
|
||||
GET http://172.18.0.7:7878/api/v3/rootfolder -> 200 [list of 2]
|
||||
POST http://172.18.0.7:7878/api/v3/rootfolder -> 201 {accessible, freeSpace, id, path, unmappedFolders}
|
||||
GET http://172.18.0.7:7878/api/v3/rootfolder -> 200 [list of 3]
|
||||
root folder: /mnt/felhom-drives/media_a/userdata/media/movies accessible=True freeSpace=69873070080
|
||||
root folder: /mnt/felhom-drives/media_b/userdata/media/movies accessible=True freeSpace=65554092032
|
||||
root folder: /mnt/felhom-drives/media_c/userdata/media/movies accessible=True freeSpace=49817907200
|
||||
GET http://172.18.0.7:7878/api/v3/downloadclient/schema -> 200 [list of 19]
|
||||
GET http://172.18.0.7:7878/api/v3/downloadclient -> 200 [list of 4]
|
||||
client qBittorrent drive-a: exists — left as it is
|
||||
client Transmission drive-a: exists — left as it is
|
||||
client qBittorrent drive-b: exists — left as it is
|
||||
client Transmission drive-b: exists — left as it is
|
||||
POST http://172.18.0.7:7878/api/v3/downloadclient -> 201 {configContract, enable, fields, id, implementation, implementationName, infoLink, name, priority, protocol, removeCompletedDownloads, removeFailedDownloads, tags}
|
||||
POST http://172.18.0.7:7878/api/v3/downloadclient -> 201 {configContract, enable, fields, id, implementation, implementationName, infoLink, name, priority, protocol, removeCompletedDownloads, removeFailedDownloads, tags}
|
||||
GET http://172.18.0.7:7878/api/v3/downloadclient -> 200 [list of 6]
|
||||
client qBittorrent drive-a: impl=QBittorrent enable=True tags=[1] host=qbittorrent category=movies-drive-a directory=None
|
||||
client qBittorrent drive-b: impl=QBittorrent enable=True tags=[2] host=qbittorrent category=movies-drive-b directory=None
|
||||
client qBittorrent drive-c: impl=QBittorrent enable=True tags=[3] host=qbittorrent category=movies-drive-c directory=None
|
||||
client Transmission drive-a: impl=Transmission enable=True tags=[1] host=transmission category= directory=/mnt/felhom-drives/media_a/userdata/media/transmission/movies
|
||||
client Transmission drive-b: impl=Transmission enable=True tags=[2] host=transmission category= directory=/mnt/felhom-drives/media_b/userdata/media/transmission/movies
|
||||
client Transmission drive-c: impl=Transmission enable=True tags=[3] host=transmission category= directory=/mnt/felhom-drives/media_c/userdata/media/transmission/movies
|
||||
GET http://172.18.0.7:7878/api/v3/config/mediamanagement -> 200 {autoRenameFolders, autoUnmonitorPreviouslyDownloadedMovies, chmodFolder, chownGroup, copyUsingHardlinks, createEmptyMovieFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, pathsDefaultStatic, re}
|
||||
before: minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True
|
||||
PUT http://172.18.0.7:7878/api/v3/config/mediamanagement/1 -> 202 {autoRenameFolders, autoUnmonitorPreviouslyDownloadedMovies, chmodFolder, chownGroup, copyUsingHardlinks, createEmptyMovieFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, pathsDefaultStatic, re}
|
||||
GET http://172.18.0.7:7878/api/v3/config/mediamanagement -> 200 {autoRenameFolders, autoUnmonitorPreviouslyDownloadedMovies, chmodFolder, chownGroup, copyUsingHardlinks, createEmptyMovieFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, pathsDefaultStatic, re}
|
||||
after : minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True (default kept)
|
||||
== done; Transmission reachable by its container name: True
|
||||
== prowlarr http://172.18.0.13:9696/api/v1 (key: <ApiKey> in /config/config.xml, read from the config volume)
|
||||
GET http://172.18.0.13:9696/api/v1/applications/schema -> 200 [list of 7]
|
||||
GET http://172.18.0.13:9696/api/v1/applications -> 200 [list of 2]
|
||||
application Sonarr: exists — left as it is
|
||||
application Radarr: exists — left as it is
|
||||
GET http://172.18.0.13:9696/api/v1/applications -> 200 [list of 2]
|
||||
application Radarr: syncLevel=fullSync prowlarrUrl=http://prowlarr:9696 baseUrl=http://radarr:7878 syncCategories=[2000, 2010, 2020, 2030, 2040, 2045, 2050, 2060, 2070, 2080, 2090]
|
||||
application Sonarr: syncLevel=fullSync prowlarrUrl=http://prowlarr:9696 baseUrl=http://sonarr:8989 syncCategories=[5000, 5010, 5020, 5030, 5040, 5045, 5050, 5090]
|
||||
GET http://172.18.0.13:9696/api/v1/indexer -> 200 [list of 1]
|
||||
indexers in Prowlarr: ['nCore']
|
||||
POST http://172.18.0.13:9696/api/v1/command -> 201 {body, clientUserAgent, commandName, id, name, priority, queued, sendUpdatesToClient, started, stateChangeTime, status, trigger, updateScheduledTask}
|
||||
GET http://172.18.0.13:9696/api/v1/command/53 -> 200 {body, clientUserAgent, commandName, duration, ended, id, message, name, priority, queued, sendUpdatesToClient, started, stateChangeTime, status, trigger, updateScheduledTask}
|
||||
ApplicationIndexerSync -> status=completed result=None message=Completed
|
||||
GET http://172.18.0.5:8989/api/v3/indexer -> 200 [list of 1]
|
||||
sonarr now holds 1 indexer(s): [('nCore (Prowlarr)', 'Torznab')]
|
||||
GET http://172.18.0.7:7878/api/v3/indexer -> 200 [list of 1]
|
||||
radarr now holds 1 indexer(s): [('nCore (Prowlarr)', 'Torznab')]
|
||||
== prowlarr part done
|
||||
== plex http://172.18.0.12:32400 (token: the server's own PlexOnlineToken in Preferences.xml)
|
||||
GET http://172.18.0.12:32400/library/sections -> 200 {MediaContainer}
|
||||
PUT http://172.18.0.12:32400/library/sections/1?name=Movies&type=movie&agent=tv.plex.agents.movie&scanner=Plex+Movie&language=en-US&location=%2Fmnt%2Ffelhom-drives%2Fmedia_a%2Fuserdata%2Fmedia%2Fmovies&location=%2Fmnt%2Ffelhom-drives%2Fmedia_b%2Fuserdata%2Fmedia%2Fmovies&location=%2Fmnt%2Ffelhom-drives%2Fmedia_c%2Fuserdata%2Fmedia%2Fmovies -> 200 ''
|
||||
library Movies: added ['/mnt/felhom-drives/media_c/userdata/media/movies'] -> 200
|
||||
GET http://172.18.0.12:32400/library/sections/1/refresh -> 200 ''
|
||||
library Movies: scan started -> 200
|
||||
PUT http://172.18.0.12:32400/library/sections/2?name=TV+Shows&type=show&agent=tv.plex.agents.series&scanner=Plex+TV+Series&language=en-US&location=%2Fmnt%2Ffelhom-drives%2Fmedia_a%2Fuserdata%2Fmedia%2Ftv&location=%2Fmnt%2Ffelhom-drives%2Fmedia_b%2Fuserdata%2Fmedia%2Ftv&location=%2Fmnt%2Ffelhom-drives%2Fmedia_c%2Fuserdata%2Fmedia%2Ftv -> 200 ''
|
||||
library TV Shows: added ['/mnt/felhom-drives/media_c/userdata/media/tv'] -> 200
|
||||
GET http://172.18.0.12:32400/library/sections/2/refresh -> 200 ''
|
||||
library TV Shows: scan started -> 200
|
||||
GET http://172.18.0.12:32400/:/prefs -> 200 {MediaContainer}
|
||||
PUT http://172.18.0.12:32400/:/prefs?FSEventLibraryUpdatesEnabled=1 -> 200 ''
|
||||
pref FSEventLibraryUpdatesEnabled (R-1037: scan when a change is detected) -> 200
|
||||
GET http://172.18.0.12:32400/:/prefs -> 200 {MediaContainer}
|
||||
PUT http://172.18.0.12:32400/:/prefs?FSEventLibraryPartialScanEnabled=1 -> 200 ''
|
||||
pref FSEventLibraryPartialScanEnabled (R-1037: scan when a change is detected) -> 200
|
||||
GET http://172.18.0.12:32400/library/sections -> 200 {MediaContainer}
|
||||
GET http://172.18.0.12:32400/library/sections/1/all -> 200 {MediaContainer}
|
||||
library Movies: folders=['media_a', 'media_b', 'media_c'] items=['Felhom Probe Film', 'Hope', 'Matchbox the Movie', 'Who']
|
||||
GET http://172.18.0.12:32400/library/sections/2/all -> 200 {MediaContainer}
|
||||
library TV Shows: folders=['media_a', 'media_b', 'media_c'] items=['American Horror Story', 'Avatar: Seven Havens', 'Felhom Probe Show', 'Slow Horses']
|
||||
POST http://172.18.0.14:8096/Users/AuthenticateByName -> 200 {AccessToken, ServerId, SessionInfo, User}
|
||||
== jellyfin http://172.18.0.14:8096 (an admin session: the box made the first admin itself, so it holds the password)
|
||||
GET http://172.18.0.14:8096/Auth/Keys -> 200 {Items, StartIndex, TotalRecordCount}
|
||||
POST http://172.18.0.14:8096/Auth/Keys?app=felhom -> 204 ''
|
||||
API key for the box (POST /Auth/Keys?app=felhom) -> 204 (needs an admin session; without one, one household step)
|
||||
GET http://172.18.0.14:8096/Library/VirtualFolders -> 200 [list of 2]
|
||||
POST http://172.18.0.14:8096/Library/VirtualFolders/Paths?refreshLibrary=false -> 204 ''
|
||||
library Movies: added /mnt/felhom-drives/media_c/userdata/media/movies -> 204
|
||||
POST http://172.18.0.14:8096/Library/VirtualFolders/Paths?refreshLibrary=false -> 204 ''
|
||||
library TV Shows: added /mnt/felhom-drives/media_c/userdata/media/tv -> 204
|
||||
POST http://172.18.0.14:8096/Library/Refresh -> 204 ''
|
||||
scan -> 204
|
||||
GET http://172.18.0.14:8096/Library/VirtualFolders -> 200 [list of 2]
|
||||
library Movies: folders=['media_a', 'media_b', 'media_c']
|
||||
library TV Shows: folders=['media_a', 'media_b', 'media_c']
|
||||
GET http://172.18.0.14:8096/Items?Recursive=true&IncludeItemTypes=Series,Movie -> 200 {Items, StartIndex, TotalRecordCount}
|
||||
items: ['Amerikai Horror Story', 'Avatar: Seven Havens', 'Felhom Probe Film (2026)', 'Felhom Probe Show (2026)', 'Hope - Remény', 'Matchbox', 'Roger nyúl a pácban', 'Utolsó befutók']
|
||||
== all parts done
|
||||
@@ -0,0 +1,140 @@
|
||||
== folders on media_a: all present
|
||||
== folders on media_b: all present
|
||||
== folders on media_c: all present
|
||||
== qBittorrent http://172.18.0.2:8080 (password: the deploy secret, read from the container's environment)
|
||||
POST http://172.18.0.2:8080/api/v2/auth/login -> 204 ''
|
||||
session cookie name: QBT_SID_8080
|
||||
GET http://172.18.0.2:8080/api/v2/app/preferences -> 200 {add_stopped_enabled, add_to_top_of_queue, add_trackers, add_trackers_enabled, add_trackers_from_url_enabled, add_trackers_url, add_trackers_url_list, alt_dl_limit, alt_up_limit, alternative_webui_enabled, alternative_webui_path, announce_ip, announce_port, announce_to_all_tiers, announce_to_all_trac}
|
||||
before: auto_tmm_enabled=True save_path=/mnt/felhom-drives/media_a/userdata/media/torrents temp_path_enabled=True temp_path=/mnt/felhom-drives/media_a/userdata/media/torrents/.temp
|
||||
POST http://172.18.0.2:8080/api/v2/app/setPreferences -> 200 ''
|
||||
GET http://172.18.0.2:8080/api/v2/app/preferences -> 200 {add_stopped_enabled, add_to_top_of_queue, add_trackers, add_trackers_enabled, add_trackers_from_url_enabled, add_trackers_url, add_trackers_url_list, alt_dl_limit, alt_up_limit, alternative_webui_enabled, alternative_webui_path, announce_ip, announce_port, announce_to_all_tiers, announce_to_all_trac}
|
||||
after : auto_tmm_enabled=True (a category's save path applies only in automatic mode)
|
||||
GET http://172.18.0.2:8080/api/v2/torrents/categories -> 200 {movies-drive-a, movies-drive-b, movies-drive-c, tv-drive-a, tv-drive-b, tv-drive-c}
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
POST http://172.18.0.2:8080/api/v2/torrents/editCategory -> 200 ''
|
||||
GET http://172.18.0.2:8080/api/v2/torrents/categories -> 200 {movies-drive-a, movies-drive-b, movies-drive-c, tv-drive-a, tv-drive-b, tv-drive-c}
|
||||
category movies-drive-a: savePath=/mnt/felhom-drives/media_a/userdata/media/torrents/movies downloadPath=/mnt/felhom-drives/media_a/userdata/media/torrents/.temp
|
||||
category movies-drive-b: savePath=/mnt/felhom-drives/media_b/userdata/media/torrents/movies downloadPath=/mnt/felhom-drives/media_b/userdata/media/torrents/.temp
|
||||
category movies-drive-c: savePath=/mnt/felhom-drives/media_c/userdata/media/torrents/movies downloadPath=/mnt/felhom-drives/media_c/userdata/media/torrents/.temp
|
||||
category tv-drive-a: savePath=/mnt/felhom-drives/media_a/userdata/media/torrents/tv downloadPath=/mnt/felhom-drives/media_a/userdata/media/torrents/.temp
|
||||
category tv-drive-b: savePath=/mnt/felhom-drives/media_b/userdata/media/torrents/tv downloadPath=/mnt/felhom-drives/media_b/userdata/media/torrents/.temp
|
||||
category tv-drive-c: savePath=/mnt/felhom-drives/media_c/userdata/media/torrents/tv downloadPath=/mnt/felhom-drives/media_c/userdata/media/torrents/.temp
|
||||
== Transmission http://172.18.0.3:9091/transmission/rpc (password: the deploy secret, read from the container's environment)
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
before: {"download-dir": "/mnt/felhom-drives/media_a/userdata/media/transmission/complete", "incomplete-dir": "/mnt/felhom-drives/media_a/userdata/media/transmission/incomplete", "incomplete-dir-enabled": false, "rename-partial-files": true}
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
after : {"download-dir": "/mnt/felhom-drives/media_a/userdata/media/transmission/complete", "incomplete-dir-enabled": false, "rename-partial-files": true} (one incomplete folder for all torrents would be on drive A)
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 409 '<h1>409: Conflict</h1><p>Your request had an invalid session_id header.</p><p>To fix this, follow these steps:<ol><li>
|
||||
POST http://172.18.0.3:9091/transmission/rpc -> 200 {arguments, result}
|
||||
probe Host: transmission:9091 -> HTTP 200 {'arguments': {'version': '4.1.3 (838877323f)'}, 'result': 'success'}
|
||||
== sonarr http://172.18.0.5:8989/api/v3 (key: <ApiKey> in /config/config.xml, read from the config volume)
|
||||
GET http://172.18.0.5:8989/api/v3/tag -> 200 [list of 4]
|
||||
tags: {'driva-a': 3, 'drive-a': 1, 'drive-b': 2, 'drive-c': 4}
|
||||
GET http://172.18.0.5:8989/api/v3/rootfolder -> 200 [list of 3]
|
||||
GET http://172.18.0.5:8989/api/v3/rootfolder -> 200 [list of 3]
|
||||
root folder: /mnt/felhom-drives/media_a/userdata/media/tv accessible=True freeSpace=69873070080
|
||||
root folder: /mnt/felhom-drives/media_b/userdata/media/tv accessible=True freeSpace=65554092032
|
||||
root folder: /mnt/felhom-drives/media_c/userdata/media/tv accessible=True freeSpace=49817907200
|
||||
GET http://172.18.0.5:8989/api/v3/downloadclient/schema -> 200 [list of 18]
|
||||
GET http://172.18.0.5:8989/api/v3/downloadclient -> 200 [list of 6]
|
||||
client qBittorrent drive-a: exists — left as it is
|
||||
client Transmission drive-a: exists — left as it is
|
||||
client qBittorrent drive-b: exists — left as it is
|
||||
client Transmission drive-b: exists — left as it is
|
||||
client qBittorrent drive-c: exists — left as it is
|
||||
client Transmission drive-c: exists — left as it is
|
||||
GET http://172.18.0.5:8989/api/v3/downloadclient -> 200 [list of 6]
|
||||
client qBittorrent drive-a: impl=QBittorrent enable=True tags=[1] host=qbittorrent category=tv-drive-a directory=None
|
||||
client qBittorrent drive-b: impl=QBittorrent enable=True tags=[2] host=qbittorrent category=tv-drive-b directory=None
|
||||
client qBittorrent drive-c: impl=QBittorrent enable=True tags=[4] host=qbittorrent category=tv-drive-c directory=None
|
||||
client Transmission drive-a: impl=Transmission enable=True tags=[1] host=transmission category= directory=/mnt/felhom-drives/media_a/userdata/media/transmission/tv
|
||||
client Transmission drive-b: impl=Transmission enable=True tags=[2] host=transmission category= directory=/mnt/felhom-drives/media_b/userdata/media/transmission/tv
|
||||
client Transmission drive-c: impl=Transmission enable=True tags=[4] host=transmission category= directory=/mnt/felhom-drives/media_c/userdata/media/transmission/tv
|
||||
GET http://172.18.0.5:8989/api/v3/config/mediamanagement -> 200 {autoUnmonitorPreviouslyDownloadedEpisodes, chmodFolder, chownGroup, copyUsingHardlinks, createEmptySeriesFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, episodeTitleRequired, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, recycleBin, recy}
|
||||
before: minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True
|
||||
PUT http://172.18.0.5:8989/api/v3/config/mediamanagement/1 -> 202 {autoUnmonitorPreviouslyDownloadedEpisodes, chmodFolder, chownGroup, copyUsingHardlinks, createEmptySeriesFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, episodeTitleRequired, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, recycleBin, recy}
|
||||
GET http://172.18.0.5:8989/api/v3/config/mediamanagement -> 200 {autoUnmonitorPreviouslyDownloadedEpisodes, chmodFolder, chownGroup, copyUsingHardlinks, createEmptySeriesFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, episodeTitleRequired, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, recycleBin, recy}
|
||||
after : minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True (default kept)
|
||||
== radarr http://172.18.0.7:7878/api/v3 (key: <ApiKey> in /config/config.xml, read from the config volume)
|
||||
GET http://172.18.0.7:7878/api/v3/tag -> 200 [list of 3]
|
||||
tags: {'drive-a': 1, 'drive-b': 2, 'drive-c': 3}
|
||||
GET http://172.18.0.7:7878/api/v3/rootfolder -> 200 [list of 3]
|
||||
GET http://172.18.0.7:7878/api/v3/rootfolder -> 200 [list of 3]
|
||||
root folder: /mnt/felhom-drives/media_a/userdata/media/movies accessible=True freeSpace=69873070080
|
||||
root folder: /mnt/felhom-drives/media_b/userdata/media/movies accessible=True freeSpace=65554092032
|
||||
root folder: /mnt/felhom-drives/media_c/userdata/media/movies accessible=True freeSpace=49817907200
|
||||
GET http://172.18.0.7:7878/api/v3/downloadclient/schema -> 200 [list of 19]
|
||||
GET http://172.18.0.7:7878/api/v3/downloadclient -> 200 [list of 6]
|
||||
client qBittorrent drive-a: exists — left as it is
|
||||
client Transmission drive-a: exists — left as it is
|
||||
client qBittorrent drive-b: exists — left as it is
|
||||
client Transmission drive-b: exists — left as it is
|
||||
client qBittorrent drive-c: exists — left as it is
|
||||
client Transmission drive-c: exists — left as it is
|
||||
GET http://172.18.0.7:7878/api/v3/downloadclient -> 200 [list of 6]
|
||||
client qBittorrent drive-a: impl=QBittorrent enable=True tags=[1] host=qbittorrent category=movies-drive-a directory=None
|
||||
client qBittorrent drive-b: impl=QBittorrent enable=True tags=[2] host=qbittorrent category=movies-drive-b directory=None
|
||||
client qBittorrent drive-c: impl=QBittorrent enable=True tags=[3] host=qbittorrent category=movies-drive-c directory=None
|
||||
client Transmission drive-a: impl=Transmission enable=True tags=[1] host=transmission category= directory=/mnt/felhom-drives/media_a/userdata/media/transmission/movies
|
||||
client Transmission drive-b: impl=Transmission enable=True tags=[2] host=transmission category= directory=/mnt/felhom-drives/media_b/userdata/media/transmission/movies
|
||||
client Transmission drive-c: impl=Transmission enable=True tags=[3] host=transmission category= directory=/mnt/felhom-drives/media_c/userdata/media/transmission/movies
|
||||
GET http://172.18.0.7:7878/api/v3/config/mediamanagement -> 200 {autoRenameFolders, autoUnmonitorPreviouslyDownloadedMovies, chmodFolder, chownGroup, copyUsingHardlinks, createEmptyMovieFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, pathsDefaultStatic, re}
|
||||
before: minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True
|
||||
PUT http://172.18.0.7:7878/api/v3/config/mediamanagement/1 -> 202 {autoRenameFolders, autoUnmonitorPreviouslyDownloadedMovies, chmodFolder, chownGroup, copyUsingHardlinks, createEmptyMovieFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, pathsDefaultStatic, re}
|
||||
GET http://172.18.0.7:7878/api/v3/config/mediamanagement -> 200 {autoRenameFolders, autoUnmonitorPreviouslyDownloadedMovies, chmodFolder, chownGroup, copyUsingHardlinks, createEmptyMovieFolders, deleteEmptyFolders, downloadPropersAndRepacks, enableMediaInfo, extraFileExtensions, fileDate, id, importExtraFiles, minimumFreeSpaceWhenImporting, pathsDefaultStatic, re}
|
||||
after : minimumFreeSpaceWhenImporting=10240 MB, copyUsingHardlinks=True (default kept)
|
||||
== done; Transmission reachable by its container name: True
|
||||
== prowlarr http://172.18.0.13:9696/api/v1 (key: <ApiKey> in /config/config.xml, read from the config volume)
|
||||
GET http://172.18.0.13:9696/api/v1/applications/schema -> 200 [list of 7]
|
||||
GET http://172.18.0.13:9696/api/v1/applications -> 200 [list of 2]
|
||||
application Sonarr: exists — left as it is
|
||||
application Radarr: exists — left as it is
|
||||
GET http://172.18.0.13:9696/api/v1/applications -> 200 [list of 2]
|
||||
application Radarr: syncLevel=fullSync prowlarrUrl=http://prowlarr:9696 baseUrl=http://radarr:7878 syncCategories=[2000, 2010, 2020, 2030, 2040, 2045, 2050, 2060, 2070, 2080, 2090]
|
||||
application Sonarr: syncLevel=fullSync prowlarrUrl=http://prowlarr:9696 baseUrl=http://sonarr:8989 syncCategories=[5000, 5010, 5020, 5030, 5040, 5045, 5050, 5090]
|
||||
GET http://172.18.0.13:9696/api/v1/indexer -> 200 [list of 1]
|
||||
indexers in Prowlarr: ['nCore']
|
||||
POST http://172.18.0.13:9696/api/v1/command -> 201 {body, clientUserAgent, commandName, id, name, priority, queued, sendUpdatesToClient, status, trigger, updateScheduledTask}
|
||||
GET http://172.18.0.13:9696/api/v1/command/54 -> 200 {body, clientUserAgent, commandName, duration, ended, id, message, name, priority, queued, sendUpdatesToClient, started, stateChangeTime, status, trigger, updateScheduledTask}
|
||||
ApplicationIndexerSync -> status=completed result=None message=Completed
|
||||
GET http://172.18.0.5:8989/api/v3/indexer -> 200 [list of 1]
|
||||
sonarr now holds 1 indexer(s): [('nCore (Prowlarr)', 'Torznab')]
|
||||
GET http://172.18.0.7:7878/api/v3/indexer -> 200 [list of 1]
|
||||
radarr now holds 1 indexer(s): [('nCore (Prowlarr)', 'Torznab')]
|
||||
== prowlarr part done
|
||||
== plex http://172.18.0.12:32400 (token: the server's own PlexOnlineToken in Preferences.xml)
|
||||
GET http://172.18.0.12:32400/library/sections -> 200 {MediaContainer}
|
||||
library Movies: every drive's folder already in it — left as it is
|
||||
library TV Shows: every drive's folder already in it — left as it is
|
||||
GET http://172.18.0.12:32400/:/prefs -> 200 {MediaContainer}
|
||||
pref FSEventLibraryUpdatesEnabled=True already
|
||||
GET http://172.18.0.12:32400/:/prefs -> 200 {MediaContainer}
|
||||
pref FSEventLibraryPartialScanEnabled=True already
|
||||
GET http://172.18.0.12:32400/library/sections -> 200 {MediaContainer}
|
||||
GET http://172.18.0.12:32400/library/sections/1/all -> 200 {MediaContainer}
|
||||
library Movies: folders=['media_a', 'media_b', 'media_c'] items=['Felhom Probe Film', 'Hope', 'Matchbox the Movie', 'Who']
|
||||
GET http://172.18.0.12:32400/library/sections/2/all -> 200 {MediaContainer}
|
||||
library TV Shows: folders=['media_a', 'media_b', 'media_c'] items=['American Horror Story', 'Avatar: Seven Havens', 'Felhom Probe Show', 'Slow Horses']
|
||||
POST http://172.18.0.14:8096/Users/AuthenticateByName -> 200 {AccessToken, ServerId, SessionInfo, User}
|
||||
== jellyfin http://172.18.0.14:8096 (an admin session: the box made the first admin itself, so it holds the password)
|
||||
GET http://172.18.0.14:8096/Auth/Keys -> 200 {Items, StartIndex, TotalRecordCount}
|
||||
API key for the box: exists
|
||||
GET http://172.18.0.14:8096/Library/VirtualFolders -> 200 [list of 2]
|
||||
library Movies: every drive's folder already in it — left as it is
|
||||
library TV Shows: every drive's folder already in it — left as it is
|
||||
POST http://172.18.0.14:8096/Library/Refresh -> 204 ''
|
||||
scan -> 204
|
||||
GET http://172.18.0.14:8096/Library/VirtualFolders -> 200 [list of 2]
|
||||
library Movies: folders=['media_a', 'media_b', 'media_c']
|
||||
library TV Shows: folders=['media_a', 'media_b', 'media_c']
|
||||
GET http://172.18.0.14:8096/Items?Recursive=true&IncludeItemTypes=Series,Movie -> 200 {Items, StartIndex, TotalRecordCount}
|
||||
items: ['Amerikai Horror Story', 'Avatar: Seven Havens', 'Felhom Probe Film (2026)', 'Felhom Probe Show (2026)', 'Hope - Remény', 'Matchbox', 'Roger nyúl a pácban', 'Utolsó befutók']
|
||||
== all parts done
|
||||
@@ -0,0 +1,23 @@
|
||||
qbit add -> {'added_torrent_ids': ['522b2e41bd4a656a1b97b26491091a72828ca867'], 'failure_count': 0, 'pending_count': 0, 'success_count': 1}
|
||||
trans add -> {"arguments": {"torrent-added": {"hashString": "241e4478e835637208d9c8f19b210ee24fb3dc78", "id": 9, "name": "k3-own-bytes-trans"}}, "result": "success"}
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E01.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E03.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Hope.2026.720p.AMZN.WEB-DL.DDP', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E02.PROPER.1080', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E03.1080p.WEB.H', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E05.Sayonara.10', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E01.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E03.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E05.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E07.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'Matchbox.The.Movie.2026.720p.A', 'queuedUP', 1)
|
||||
('qbit', 'media_c', 'k3-own-bytes-qbit', 'stalledUP', 1)
|
||||
('trans', 'media_a', 'Avatar.Seven.Havens.S01E02.108', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E01.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E04.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Who.2026.720p.DSNP.WEB-DL.DDP5', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E02.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E04.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E06.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E08.1', 'seeding', 1.0)
|
||||
('trans', 'media_c', 'k3-own-bytes-trans', 'seeding', 1.0)
|
||||
@@ -0,0 +1,23 @@
|
||||
qbit pause 1 torrent(s) on media_c ->
|
||||
trans pause 1 torrent(s) on media_c -> success
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E01.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E03.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Hope.2026.720p.AMZN.WEB-DL.DDP', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E02.PROPER.1080', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E03.1080p.WEB.H', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E05.Sayonara.10', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E01.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E03.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E05.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E07.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'Matchbox.The.Movie.2026.720p.A', 'queuedUP', 1)
|
||||
('qbit', 'media_c', 'k3-own-bytes-qbit', 'stoppedUP', 1)
|
||||
('trans', 'media_a', 'Avatar.Seven.Havens.S01E02.108', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E01.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E04.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Who.2026.720p.DSNP.WEB-DL.DDP5', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E02.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E04.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E06.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E08.1', 'seeding', 1.0)
|
||||
('trans', 'media_c', 'k3-own-bytes-trans', 'stopped', 1.0)
|
||||
@@ -0,0 +1,22 @@
|
||||
POST /api/storage/eject -> 200 in 2.0s {"data": {"vmid": 9201, "ejected": "/mnt/media_c", "dependent_guests": null}, "ok": true}
|
||||
TARGET SOURCE
|
||||
guest ls C:
|
||||
sonarr sees C: Felhom Probe Show (2026)
|
||||
qbittorrent sees C: Felhom Probe Show (2026)
|
||||
plex sees C: Felhom Probe Show (2026)
|
||||
filebrowser sees C: ls: /mnt/felhom-drives/media_c/userdata/media/tv: No such file or directory
|
||||
adatlemez beolvasas media_a media_b
|
||||
2026/10/14 21:10:25 [INFO] [settings] Removed storage path: /mnt/felhom-drives/media_c
|
||||
2026/10/14 21:10:26 [INFO] [web] FileBrowser mounts synced (recreated) — 3 storage path(s), config updated
|
||||
|
||||
Oct 14 23:10:24 felhom sudo[674618]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/chown 100000:100000 /mnt/media_c/felhom-data
|
||||
Oct 14 23:10:24 felhom sudo[674621]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/mkdir -p /mnt/felhom-drives/media_c
|
||||
Oct 14 23:10:24 felhom felhom-agent[1201]: time=2026-10-14T23:10:24.680+02:00 level=INFO msg="reconcile: enrolled drive bound under shared parent (live, no reboot)" vmid=9201 where=/mnt/media_c guest_path=/mnt/felhom-dri
|
||||
Oct 14 23:10:25 felhom felhom-agent[1201]: time=2026-10-14T23:10:25.922+02:00 level=INFO msg="local-api: drive intent recorded" where=/mnt/media_c action=ejected durable_id=uuid:86f33f9c-1022-43d8-95eb-f9a6ec9eb923
|
||||
Oct 14 23:10:25 felhom sudo[674712]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/umount /mnt/felhom-drives/media_c
|
||||
Oct 14 23:10:25 felhom systemd[1]: mnt-felhom\x2ddrives-media_c.mount: Deactivated successfully.
|
||||
Oct 14 23:10:25 felhom felhom-agent[1201]: time=2026-10-14T23:10:25.943+02:00 level=INFO msg="guest-detach: drive fully unmounted from shared parent (live, fail-closed)" where=/mnt/media_c stable=/mnt/felhom-drives/media
|
||||
Oct 14 23:10:25 felhom felhom-agent[1201]: time=2026-10-14T23:10:25.943+02:00 level=INFO msg="local-api: drive ejected (bind detached, raw mount kept)" vmid=9201 where=/mnt/media_c dependent_guests=0
|
||||
Oct 14 23:10:30 felhom sudo[675114]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/sbin/smartctl -a -j /dev/sde
|
||||
Oct 14 23:10:31 felhom sudo[675177]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/sbin/smartctl -a -j /dev/sde
|
||||
1
|
||||
@@ -0,0 +1,26 @@
|
||||
BEFORE: guest C path: drwxr-xr-x 2 nobody nogroup 4096 Oct 14 21:03 . drwxr-xr-x 6 nobody nogroup 4096 Oct 14 21:03 .. /dev/mapper/pve-root
|
||||
|
||||
plex stop -> 200
|
||||
plex start -> 500
|
||||
jellyfin stop -> 200
|
||||
jellyfin start -> 500
|
||||
plex: sees C:
|
||||
jellyfin: sees C:
|
||||
AFTER: guest C path tree (did docker create folders on the guest's own disk?):
|
||||
/mnt/felhom-drives/media_c
|
||||
on device: /dev/mapper/pve-root
|
||||
|
||||
2026/10/14 21:11:28 [INFO] Event pushed: app_start_failed (warning) [hu-only] — Telepített alkalmazás nem fut: Plex
|
||||
2026/10/14 21:11:28 [INFO] Event pushed: app_start_failed (warning) [hu-only] — Telepített alkalmazás nem fut: Jellyfin
|
||||
2026/10/14 21:11:28 [INFO] [stacks] ParseComposeHDDMounts: found 1 HDD mounts for /opt/docker/stacks/jellyfin/docker-compose.yml
|
||||
2026/10/14 21:11:28 [INFO] [stacks] ParseComposeHDDMounts: found 1 HDD mounts for /opt/docker/stacks/plex/docker-compose.yml
|
||||
jellyfin Created
|
||||
plex Created
|
||||
2026/10/14 21:11:19 [ERROR] [api] start failed for plex: starting stack plex: exit code 1
|
||||
2026/10/14 21:11:25 [INFO] [api] start requested for stack: jellyfin
|
||||
2026/10/14 21:11:26 [INFO] [stacks] Starting stack: jellyfin
|
||||
2026/10/14 21:11:26 [ERROR] [api] start failed for jellyfin: starting stack jellyfin: exit code 1
|
||||
2026/10/14 21:11:28 [INFO] Event pushed: app_start_failed (warning) [hu-only] — Telepített alkalmazás nem fut: Plex
|
||||
2026/10/14 21:11:28 [INFO] Event pushed: app_start_failed (warning) [hu-only] — Telepített alkalmazás nem fut: Jellyfin
|
||||
Error response from daemon: error while creating mount source path '/mnt/felhom-drives/media_c/userdata/media': mkdir /mnt/felhom-drives/media_c/userdata: permission denied
|
||||
failed to start containers: plex
|
||||
@@ -0,0 +1,27 @@
|
||||
2026-10-14T23:12:42+02:00
|
||||
unused0: nvme-scratch:341/vm-341-disk-5.raw
|
||||
Oct 14 23:12:43 felhom systemd[1]: mnt-media_c.mount: Deactivated successfully.
|
||||
Oct 14 23:12:43 felhom systemd[1]: Unmounted mnt-media_c.mount - Felhom storage mount 86f33f9c-1022-43d8-95eb-f9a6ec9eb923.
|
||||
Oct 14 23:12:43 felhom felhom-agent[1201]: time=2026-10-14T23:12:43.987+02:00 level=INFO msg="storage: enrolled drive absent by UUID — not re-asserting (will retry when it enumerates)" name=86f33f9c
|
||||
Oct 14 23:12:48 felhom felhom-agent[1201]: time=2026-10-14T23:12:48.266+02:00 level=INFO msg="storage: watchdog — known drive went absent; clearing any eject intent (replug will auto-mount)" target=
|
||||
Oct 14 23:13:03 felhom felhom-agent[1201]: time=2026-10-14T23:13:03.987+02:00 level=INFO msg="storage: enrolled drive absent by UUID — not re-asserting (will retry when it enumerates)" name=86f33f9c
|
||||
Oct 14 23:13:04 felhom felhom-agent[1201]: time=2026-10-14T23:13:04.608+02:00 level=WARN msg="reconcile: enrolled drive not present (durable-id absent) — skipping" vmid=9201 durable_id=uuid:86f33f9c
|
||||
2026-10-14T23:13:11+02:00
|
||||
scsi4: nvme-scratch:341/vm-341-disk-5.raw,backup=0,size=50G
|
||||
sdd drive-scsi4 /mnt/media_c
|
||||
/dev/sdd on /mnt/media_c type ext4 (rw,relatime)
|
||||
/dev/sdd on /mnt/felhom-drives/media_c type ext4 (rw,relatime)
|
||||
Oct 14 23:13:44 felhom sudo[682301]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/mkdir -p /mnt/felhom-drives/media_c
|
||||
Oct 14 23:13:44 felhom felhom-agent[1201]: time=2026-10-14T23:13:44.678+02:00 level=INFO msg="reconcile: enrolled drive bound under shared parent (live, no reboot)" vmid=9201 where=/mnt/media_c guest_
|
||||
Oct 14 23:14:04 felhom sudo[682848]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/mkdir -p /mnt/media_c/felhom-data
|
||||
Oct 14 23:14:04 felhom sudo[682851]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/chown 100000:100000 /mnt/media_c/felhom-data
|
||||
Oct 14 23:14:04 felhom sudo[682854]: felhom-agent : PWD=/ ; USER=root ; COMMAND=/usr/bin/mkdir -p /mnt/felhom-drives/media_c
|
||||
Oct 14 23:14:04 felhom felhom-agent[1201]: time=2026-10-14T23:14:04.666+02:00 level=INFO msg="reconcile: enrolled drive bound under shared parent (live, no reboot)" vmid=9201 where=/mnt/media_c guest_
|
||||
dashboard drives: [('4ebfd36d', 'attached', '/mnt/felhom-drives/media_a'), ('863c67fd', 'attached', '/mnt/felhom-drives/adatlemez'), ('86f33f9c', 'attached', '/mnt/felhom-drives/media_c'), ('e15652d5', 'attached', '/mnt/felhom-drives/media_b')]
|
||||
candidates: {"vmid": 9201, "initialize": [{"device": "/dev/sdd", "size_bytes": 53687091200, "model": "QEMU HARDDISK", "fstype": "ext4", "data_bearing": true, "mountable": true, "mount_source": "/dev/sdd", "durable_id": "uuid:86f33f9c-1022-43d8-95eb-f9a6ec9eb923"}], "attach": [{"device": "/dev/sdd", "size_bytes"
|
||||
register-mounted /mnt/felhom-drives/media_c -> 200 {"data": {"registered": true, "where": "/mnt/felhom-drives/media_c"}, "ok": true}
|
||||
2026/10/14 21:14:35 [INFO] [settings] Added storage path: /mnt/felhom-drives/media_c
|
||||
2026/10/14 21:14:35 [INFO] [web] storage path registered (already-mounted store): /mnt/felhom-drives/media_c
|
||||
2026/10/14 21:14:35 [INFO] [web] FileBrowser mounts synced (recreated) — 4 storage path(s), config updated
|
||||
Felhom Probe Show (2026)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
qbit resume 1 torrent(s) on media_c ->
|
||||
trans resume 1 torrent(s) on media_c -> success
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E01.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E03.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Hope.2026.720p.AMZN.WEB-DL.DDP', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E02.PROPER.1080', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E03.1080p.WEB.H', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E05.Sayonara.10', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E01.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E03.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E05.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E07.1', 'stalledUP', 1)
|
||||
('qbit', 'media_b', 'Matchbox.The.Movie.2026.720p.A', 'queuedUP', 1)
|
||||
('qbit', 'media_c', 'k3-own-bytes-qbit', 'stalledUP', 1)
|
||||
('trans', 'media_a', 'Avatar.Seven.Havens.S01E02.108', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E01.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E04.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Who.2026.720p.DSNP.WEB-DL.DDP5', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E02.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E04.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E06.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E08.1', 'seeding', 1.0)
|
||||
('trans', 'media_c', 'k3-own-bytes-trans', 'seeding', 1.0)
|
||||
--- 21:17:53
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E01.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Avatar.Seven.Havens.S01E03.108', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Hope.2026.720p.AMZN.WEB-DL.DDP', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E02.PROPER.1080', 'queuedUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E03.1080p.WEB.H', 'stalledUP', 1)
|
||||
('qbit', 'media_a', 'Slow.Horses.S06E05.Sayonara.10', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E01.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E03.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E05.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'American.Horror.Story.S13E07.1', 'queuedUP', 1)
|
||||
('qbit', 'media_b', 'Matchbox.The.Movie.2026.720p.A', 'queuedUP', 1)
|
||||
('qbit', 'media_c', 'k3-own-bytes-qbit', 'stalledUP', 1)
|
||||
('trans', 'media_a', 'Avatar.Seven.Havens.S01E02.108', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E01.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Slow.Horses.S06E04.1080p.WEB.H', 'seeding', 1.0)
|
||||
('trans', 'media_a', 'Who.2026.720p.DSNP.WEB-DL.DDP5', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E02.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E04.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E06.1', 'seeding', 1.0)
|
||||
('trans', 'media_b', 'American.Horror.Story.S13E08.1', 'seeding', 1.0)
|
||||
('trans', 'media_c', 'k3-own-bytes-trans', 'seeding', 1.0)
|
||||
@@ -0,0 +1,8 @@
|
||||
# K3 predictions — written before the safe removal of Media C (2026-10-14 ~23:15 CEST)
|
||||
- Pausing by save folder stops ONLY C's two torrents; A's and B's keep their state (seeding/queued).
|
||||
- „Biztonságos leválasztás" (POST /api/storage/eject): the agent unmounts; the controller DEREGISTERS the drive
|
||||
(RemoveStoragePath) and re-syncs FileBrowser. With six running containers holding a bind of C, the unmount may be
|
||||
refused as busy — or succeed lazily, leaving the containers a view of the old filesystem.
|
||||
- After the VM disk is detached and re-attached, the agent mounts it again (replug), but the controller no longer has
|
||||
it registered: it needs „Meglévő meghajtó csatolása" (attach) — the household's step today.
|
||||
- After restart + resume, C's torrents seed again without a re-check; A's never stopped.
|
||||
@@ -0,0 +1,6 @@
|
||||
qbittorrent dashboard restart (compose up -d, compose CHANGED) -> 200 in 2.0s; started before=21:00:32 after=2026-10-14T21:04:23.405827829Z | audiobooks
|
||||
transmission dashboard restart (compose up -d, compose CHANGED) -> 200 in 5.9s; started before=21:00:32 after=2026-10-14T21:04:38.76445242Z | audiobooks
|
||||
sonarr dashboard restart (compose up -d, compose CHANGED) -> 200 in 3.9s; started before=21:00:33 after=2026-10-14T21:04:52.134164368Z | audiobooks
|
||||
radarr dashboard restart (compose up -d, compose CHANGED) -> 200 in 4.0s; started before=21:00:34 after=2026-10-14T21:05:06.56466461Z | audiobooks
|
||||
plex dashboard restart (compose up -d, compose CHANGED) -> 200 in 9.3s; started before=21:00:34 after=2026-10-14T21:05:25.260983982Z | audiobooks
|
||||
jellyfin dashboard restart (compose up -d, compose CHANGED) -> 200 in 0.9s; started before=21:00:35 after=2026-10-14T21:05:36.397174757Z | audiobooks
|
||||
@@ -0,0 +1,18 @@
|
||||
BEFORE: {'sonarr': "ls: cannot access '/mnt/felhom-drives/media_c/userdata/media/tv': I/O error", 'radarr': "ls: cannot access '/mnt/felhom-drives/media_c/userdata/media/tv': I/O error", 'qbittorrent': 'ls: /mnt/felhom-drives/media_c/userdata/media/tv: I/O error', 'transmission': "ls: cannot access '/mnt/felhom-drives/media_c/userdata/media/tv': I/O error"}
|
||||
sonarr compose up -d --force-recreate: 6.9s; sees C: Felhom Probe Show (2026) | Container sonarr Starting
|
||||
Container sonarr Started
|
||||
qbittorrent compose up -d --force-recreate: 5.9s; sees C: Felhom Probe Show (2026) | Container qbittorrent Starting
|
||||
Container qbittorrent Started
|
||||
radarr dashboard stop+start (200,200): 4.1s; sees C: Felhom Probe Show (2026)
|
||||
transmission dashboard stop+start (200,200): 5.3s; sees C: Felhom Probe Show (2026)
|
||||
plex dashboard start (200): 0.6s; sees C: Felhom Probe Show (2026)
|
||||
jellyfin dashboard start (200): 0.7s; sees C: Felhom Probe Show (2026)
|
||||
filebrowser sees C: Felhom Probe Show (2026)
|
||||
sonarr dashboard restart -> 200
|
||||
qbittorrent dashboard restart -> 200
|
||||
sonarr rule: Host(`sonarr.enkicsifelhom.hu`) sees C: Felhom Probe Show (2026)
|
||||
qbittorrent rule: Host(`torrent.enkicsifelhom.hu`) sees C: Felhom Probe Show (2026)
|
||||
qbit password env set: yes
|
||||
|
||||
sonarr public: 302
|
||||
torrent public: 200
|
||||
@@ -0,0 +1,9 @@
|
||||
# Night log — media drive events (Part 2), times CEST
|
||||
22:52 K0 safety baseline: every file on every drive's userdata/media (K0-filesig-start.tsv)
|
||||
22:54:48 K1 DETACH Media B (VM 341 scsi3, nvme-scratch:341/vm-341-disk-4.raw) — expect a hub mail
|
||||
22:59:00 K1 RE-ATTACH Media B (same volume, scsi3)
|
||||
23:02 K1 done: nothing lost in any app; files identical
|
||||
23:03:10 K2 Media C added (VM 341 scsi4, 50 GB, backup=0)
|
||||
23:10:23 K3 safe removal of Media C (POST /api/storage/eject) — expect a hub mail?
|
||||
23:12:41 K3 DETACH Media C disk (scsi4) after the safe removal
|
||||
23:13:11 K3 RE-ATTACH Media C disk (scsi4)
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
"""filesig.py <out-label> — the safety baseline: every regular file under each drive's userdata/media with size, inode,
|
||||
link count and mtime, one line each, sorted. Run INSIDE the guest. Two runs compared = 'did any FILE change or vanish'
|
||||
(the Part 2 STOP condition), as opposed to a library entry."""
|
||||
import glob, os
|
||||
for root in sorted(glob.glob("/mnt/felhom-drives/*/userdata/media")):
|
||||
for dp, dn, fn in os.walk(root):
|
||||
for f in fn:
|
||||
p = os.path.join(dp, f)
|
||||
try:
|
||||
s = os.lstat(p)
|
||||
except OSError as e:
|
||||
print(f"ERR {p} {e}"); continue
|
||||
print(f"{p}\t{s.st_size}\t{s.st_ino}\t{s.st_nlink}\t{int(s.st_mtime)}")
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
# grun.sh <tool.py> [args...] — run a tool of this folder INSIDE the Tester 1 guest via stdin, with Jellyfin's admin
|
||||
# password substituted for __JF_PW__ in the piped copy only (it lives in ~/.felhom-tester1/secrets.json). The guest copy is deleted.
|
||||
cd "$(dirname "$0")"
|
||||
python3 - "$@" <<'PY' | sed -E 's/X-Plex-Token=[A-Za-z0-9_-]+/X-Plex-Token=<redacted>/g'
|
||||
import json,os,sys,shlex
|
||||
sys.path.insert(0,"/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
|
||||
os.environ.setdefault("SC",os.path.expanduser("~/.felhom-tester1")); os.environ.setdefault("TARGET","tester-1")
|
||||
import box_walk as w
|
||||
pw=json.load(open(os.path.expanduser("~/.felhom-tester1/secrets.json")))["jellyfin"]["admin"]
|
||||
src=open(sys.argv[1]).read().replace("__JF_PW__",pw)
|
||||
args=" ".join(shlex.quote(a) for a in sys.argv[2:])
|
||||
r=w.sh(w.ssh_args()+[f'pct exec 9201 -- sh -c "cat > /root/.g.py; timeout 900 python3 /root/.g.py {args} 2>&1; rm -f /root/.g.py"'],timeout=960,inp=src)
|
||||
print(r.stdout, end=""); print(r.stderr[-600:]) if r.returncode else None
|
||||
PY
|
||||
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env python3
|
||||
"""k1.py <step> — K1 (what the media apps do while a drive is gone), run INSIDE the Tester 1 guest.
|
||||
|
||||
steps:
|
||||
mark mark one Media B episode watched in Plex and Jellyfin (the watch-state probe)
|
||||
state what every app shows now (per item: present / unavailable / gone; watch state of the probe)
|
||||
plexscan force Plex to scan both libraries (and wait)
|
||||
plexset <0|1> set Plex's „empty trash automatically after every scan" (autoEmptyTrash)
|
||||
jfscan force Jellyfin to scan (and wait)
|
||||
arrscan run Sonarr's RefreshSeries + RescanSeries and Radarr's RefreshMovie + RescanMovie (and wait)
|
||||
arrset <0|1> set Sonarr/Radarr „unmonitor deleted episodes/movies"
|
||||
Plex's token: its own Preferences.xml. Jellyfin's admin password: substituted into this copy by the runner. Nothing printed.
|
||||
"""
|
||||
import json, re, subprocess, sys, time, urllib.error, urllib.parse, urllib.request
|
||||
|
||||
JFPW = "__JF_PW__"
|
||||
PROBE_SHOW, PROBE_EP = "American Horror Story", (13, 1) # on Media B
|
||||
|
||||
|
||||
def sh(c):
|
||||
return subprocess.run(c, shell=True, capture_output=True, text=True).stdout.strip()
|
||||
|
||||
|
||||
def ip(c):
|
||||
return sh(f"docker inspect {c} -f '{{{{range .NetworkSettings.Networks}}}}{{{{.IPAddress}}}}{{{{end}}}}'")
|
||||
|
||||
|
||||
def call(m, url, h=None, body=None, raw=False, t=60):
|
||||
hh = dict(h or {})
|
||||
data = None
|
||||
if body is not None:
|
||||
data = json.dumps(body).encode(); hh["Content-Type"] = "application/json"
|
||||
try:
|
||||
with urllib.request.urlopen(urllib.request.Request(url, data=data, headers=hh, method=m), timeout=t) as r:
|
||||
b = r.read(); return r.status, (b.decode() if raw else (json.loads(b) if b else None))
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code, None
|
||||
|
||||
|
||||
P = "/var/lib/docker/volumes/plex_plex_config/_data/Library/Application Support/Plex Media Server"
|
||||
PT = re.search(r'PlexOnlineToken="([^"]+)', open(f"{P}/Preferences.xml").read()).group(1)
|
||||
PB = f"http://{ip('plex')}:32400"
|
||||
PH = {"Accept": "application/json", "X-Plex-Token": PT}
|
||||
|
||||
|
||||
def plex(m, path, **q):
|
||||
return call(m, PB + path + ("?" + urllib.parse.urlencode(q) if q else ""), PH)
|
||||
|
||||
|
||||
def arr(app):
|
||||
port = 8989 if app == "sonarr" else 7878
|
||||
k = re.search(r"<ApiKey>([^<]+)", open(f"/var/lib/docker/volumes/{app}_{app}_config/_data/config.xml").read()).group(1)
|
||||
return f"http://{ip(app)}:{port}/api/v3", {"X-Api-Key": k, "Host": app}
|
||||
|
||||
|
||||
def jf():
|
||||
b = f"http://{ip('jellyfin')}:8096"
|
||||
A = 'MediaBrowser Client="felhom-test", Device="k1", DeviceId="felhom-k1", Version="1"'
|
||||
c, r = call("POST", b + "/Users/AuthenticateByName", {"Authorization": A}, {"Username": "admin", "Pw": JFPW})
|
||||
return b, {"X-Emby-Token": r["AccessToken"]}, r["User"]["Id"]
|
||||
|
||||
|
||||
def plex_items():
|
||||
out = {}
|
||||
for sec in (1, 2):
|
||||
c, d = plex("GET", f"/library/sections/{sec}/all")
|
||||
for m in (d or {}).get("MediaContainer", {}).get("Metadata", []):
|
||||
out[m["title"]] = m["ratingKey"]
|
||||
return out
|
||||
|
||||
|
||||
def plex_probe():
|
||||
rk = plex_items().get(PROBE_SHOW)
|
||||
if not rk:
|
||||
return None, "show gone from Plex"
|
||||
c, d = plex("GET", f"/library/metadata/{rk}/allLeaves")
|
||||
for e in (d or {}).get("MediaContainer", {}).get("Metadata", []):
|
||||
if (e.get("parentIndex"), e.get("index")) == PROBE_EP:
|
||||
return e["ratingKey"], f"viewCount={e.get('viewCount', 0)}"
|
||||
return None, "episode gone"
|
||||
|
||||
|
||||
def jf_probe(b, H, uid):
|
||||
# the plain recursive episode list (the per-show and search routes answered empty on this 10.11)
|
||||
c, d = call("GET", b + f"/Users/{uid}/Items?Recursive=true&IncludeItemTypes=Episode", H)
|
||||
for e in (d or {}).get("Items", []):
|
||||
if "Horror" in (e.get("SeriesName") or "") and (e.get("ParentIndexNumber"), e.get("IndexNumber")) == PROBE_EP:
|
||||
return e["Id"], f"Played={e.get('UserData', {}).get('Played')}"
|
||||
return None, "episode gone"
|
||||
|
||||
|
||||
def state():
|
||||
print(f"--- {time.strftime('%H:%M:%S')} state")
|
||||
for sec in (1, 2):
|
||||
c, d = plex("GET", f"/library/sections/{sec}/all", includeMissing=1)
|
||||
for m in (d or {}).get("MediaContainer", {}).get("Metadata", []):
|
||||
c2, d2 = plex("GET", f"/library/metadata/{m['ratingKey']}/allLeaves" if m["type"] == "show" else f"/library/metadata/{m['ratingKey']}")
|
||||
leaves = (d2 or {}).get("MediaContainer", {}).get("Metadata", [])
|
||||
parts = [p for l in leaves for md in l.get("Media", []) for p in md.get("Part", [])]
|
||||
gone = sum(1 for p in parts if p.get("accessible") is False or p.get("exists") is False)
|
||||
print(f" plex {m['type']:5} {m['title'][:24]:24} items={len(leaves)} parts={len(parts)} unavailable={gone}")
|
||||
print(" plex probe:", plex_probe()[1])
|
||||
b, H, uid = jf()
|
||||
c, d = call("GET", b + f"/Users/{uid}/Items?Recursive=true&IncludeItemTypes=Series,Movie,Episode", H)
|
||||
items = (d or {}).get("Items", [])
|
||||
print(" jellyfin:", {t: len([i for i in items if i["Type"] == t]) for t in ("Series", "Movie", "Episode")},
|
||||
sorted(i["Name"] for i in items if i["Type"] in ("Series", "Movie")))
|
||||
print(" jellyfin probe:", jf_probe(b, H, uid)[1])
|
||||
for app, kind in (("sonarr", "series"), ("radarr", "movie")):
|
||||
base, H2 = arr(app)
|
||||
c, s = call("GET", base + f"/{kind}", H2)
|
||||
for x in s or []:
|
||||
st = x.get("statistics") or {}
|
||||
print(f" {app} {x['title'][:24]:24} monitored={x['monitored']} files={st.get('episodeFileCount', x.get('hasFile'))} path={x['path'].split('/')[3]}")
|
||||
if app == "sonarr":
|
||||
for x in s or []:
|
||||
c, eps = call("GET", base + f"/episode?seriesId={x['id']}", H2)
|
||||
eps = eps or []
|
||||
print(f" {x['title'][:24]:24} episodes monitored={sum(1 for e in eps if e['monitored'])}/{len(eps)} hasFile={sum(1 for e in eps if e['hasFile'])}")
|
||||
|
||||
|
||||
def wait_cmd(base, H, cid):
|
||||
for _ in range(60):
|
||||
time.sleep(3)
|
||||
c, d = call("GET", base + f"/command/{cid}", H)
|
||||
if (d or {}).get("status") in ("completed", "failed", "aborted"):
|
||||
return d["status"]
|
||||
return "timeout"
|
||||
|
||||
|
||||
step = sys.argv[1]
|
||||
if step == "mark":
|
||||
rk, s = plex_probe(); print("plex probe before:", s)
|
||||
c, _ = plex("GET", "/:/scrobble", key=rk, identifier="com.plexapp.plugins.library"); print("plex scrobble ->", c)
|
||||
b, H, uid = jf(); iid, s = jf_probe(b, H, uid); print("jellyfin probe before:", s)
|
||||
c, _ = call("POST", b + f"/Users/{uid}/PlayedItems/{iid}", H); print("jellyfin played ->", c)
|
||||
print("after: plex", plex_probe()[1], "| jellyfin", jf_probe(b, H, uid)[1])
|
||||
elif step == "state":
|
||||
state()
|
||||
elif step == "plexscan":
|
||||
for sec in (1, 2):
|
||||
print(f"plex refresh section {sec} ->", plex("GET", f"/library/sections/{sec}/refresh", force=1)[0])
|
||||
for _ in range(60):
|
||||
time.sleep(5)
|
||||
c, d = plex("GET", "/library/sections")
|
||||
if not any(x.get("refreshing") for x in (d or {}).get("MediaContainer", {}).get("Directory", [])):
|
||||
break
|
||||
print("plex scan done", time.strftime("%H:%M:%S"))
|
||||
elif step == "plexset":
|
||||
print("plex autoEmptyTrash ->", plex("PUT", "/:/prefs", autoEmptyTrash=sys.argv[2])[0])
|
||||
elif step == "jfscan":
|
||||
b, H, uid = jf()
|
||||
print("jellyfin /Library/Refresh ->", call("POST", b + "/Library/Refresh", H)[0])
|
||||
for _ in range(60):
|
||||
time.sleep(5)
|
||||
c, tasks = call("GET", b + "/ScheduledTasks", H)
|
||||
t = [x for x in tasks or [] if x.get("Key") == "RefreshLibrary"]
|
||||
if t and t[0].get("State") == "Idle":
|
||||
break
|
||||
print("jellyfin scan done", time.strftime("%H:%M:%S"))
|
||||
elif step == "arrscan":
|
||||
for app, cmds in (("sonarr", ("RefreshSeries", "RescanSeries")), ("radarr", ("RefreshMovie", "RescanMovie"))):
|
||||
base, H = arr(app)
|
||||
for cmd in cmds:
|
||||
c, d = call("POST", base + "/command", H, {"name": cmd})
|
||||
print(f"{app} {cmd} -> {c} {wait_cmd(base, H, (d or {}).get('id'))}")
|
||||
elif step == "arrset":
|
||||
v = sys.argv[2] == "1"
|
||||
for app, key in (("sonarr", "autoUnmonitorPreviouslyDownloadedEpisodes"), ("radarr", "autoUnmonitorPreviouslyDownloadedMovies")):
|
||||
base, H = arr(app)
|
||||
c, mm = call("GET", base + "/config/mediamanagement", H)
|
||||
mm[key] = v
|
||||
print(f"{app} {key}={v} ->", call("PUT", base + f"/config/mediamanagement/{mm['id']}", H, mm)[0])
|
||||
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
"""k3.py create|state|pause|resume [drive] — K3 (a safe removal), run INSIDE the Tester 1 guest.
|
||||
|
||||
create makes ONE torrent of our own random bytes (3 MB, private, no tracker) per client on Media C and adds it so it
|
||||
seeds: qBittorrent (category tv-drive-c → media_c/userdata/media/torrents/tv), Transmission
|
||||
(media_c/userdata/media/transmission/tv).
|
||||
state every torrent: client, drive, state, progress — the „did anything else stop / re-check" record.
|
||||
pause pause ONLY the torrents whose save folder is on <drive> (qBittorrent by save_path, Transmission by downloadDir).
|
||||
resume start them again.
|
||||
Passwords: the deploy secrets read from the containers' environment; never printed.
|
||||
"""
|
||||
import base64, hashlib, json, os, re, subprocess, sys, time, urllib.error, urllib.parse, urllib.request
|
||||
|
||||
DRV = sys.argv[2] if len(sys.argv) > 2 else "media_c"
|
||||
M = f"/mnt/felhom-drives/{DRV}/userdata/media"
|
||||
|
||||
|
||||
def sh(c):
|
||||
return subprocess.run(c, shell=True, capture_output=True, text=True).stdout.strip()
|
||||
|
||||
|
||||
def ip(c):
|
||||
return sh(f"docker inspect {c} -f '{{{{range .NetworkSettings.Networks}}}}{{{{.IPAddress}}}}{{{{end}}}}'")
|
||||
|
||||
|
||||
def be(x):
|
||||
if isinstance(x, int): return b"i%de" % x
|
||||
if isinstance(x, bytes): return b"%d:%s" % (len(x), x)
|
||||
if isinstance(x, str): return be(x.encode())
|
||||
if isinstance(x, list): return b"l" + b"".join(be(i) for i in x) + b"e"
|
||||
return b"d" + b"".join(be(k) + be(x[k]) for k in sorted(x)) + b"e"
|
||||
|
||||
|
||||
def mktorrent(d):
|
||||
L = 262144
|
||||
files = sorted(os.listdir(d)); data = b"".join(open(os.path.join(d, f), "rb").read() for f in files)
|
||||
info = {"name": os.path.basename(d), "piece length": L, "private": 1,
|
||||
"pieces": b"".join(hashlib.sha1(data[i:i+L]).digest() for i in range(0, len(data), L)),
|
||||
"files": [{"length": os.path.getsize(os.path.join(d, f)), "path": [f]} for f in files]}
|
||||
return be({"info": info, "created by": "felhom K3 (own random bytes)"})
|
||||
|
||||
|
||||
QB = f"http://{ip('qbittorrent')}:8080"
|
||||
qpw = sh("docker exec qbittorrent printenv QBT_ADMIN_PASSWORD")
|
||||
req = urllib.request.Request(QB + "/api/v2/auth/login", data=urllib.parse.urlencode({"username": "admin", "password": qpw}).encode(), headers={"Referer": QB})
|
||||
with urllib.request.urlopen(req) as r:
|
||||
m = re.search(r"((?:QBT_)?SID[A-Za-z0-9_]*)=([^;]+)", r.headers.get("Set-Cookie", ""))
|
||||
QH = {"Referer": QB, "Cookie": f"{m.group(1)}={m.group(2)}"}
|
||||
|
||||
|
||||
def qb(path, form=None, files=None):
|
||||
if files:
|
||||
bnd = "felhomk3"
|
||||
body = b""
|
||||
for k, v in (form or {}).items():
|
||||
body += f"--{bnd}\r\nContent-Disposition: form-data; name=\"{k}\"\r\n\r\n{v}\r\n".encode()
|
||||
for k, (fn, data) in files.items():
|
||||
body += f"--{bnd}\r\nContent-Disposition: form-data; name=\"{k}\"; filename=\"{fn}\"\r\nContent-Type: application/x-bittorrent\r\n\r\n".encode() + data + b"\r\n"
|
||||
body += f"--{bnd}--\r\n".encode()
|
||||
r = urllib.request.Request(QB + path, data=body, headers=dict(QH, **{"Content-Type": f"multipart/form-data; boundary={bnd}"}))
|
||||
elif form is not None:
|
||||
r = urllib.request.Request(QB + path, data=urllib.parse.urlencode(form).encode(), headers=QH)
|
||||
else:
|
||||
r = urllib.request.Request(QB + path, headers=QH)
|
||||
with urllib.request.urlopen(r, timeout=60) as x:
|
||||
t = x.read().decode()
|
||||
try: return json.loads(t)
|
||||
except ValueError: return t
|
||||
|
||||
|
||||
TR = f"http://{ip('transmission')}:9091/transmission/rpc"
|
||||
tpw = sh("docker exec transmission printenv PASS")
|
||||
TA = {"Authorization": "Basic " + base64.b64encode(f"admin:{tpw}".encode()).decode()}
|
||||
|
||||
|
||||
def tr(method, args=None):
|
||||
h = dict(TA)
|
||||
for _ in range(2):
|
||||
r = urllib.request.Request(TR, data=json.dumps({"method": method, "arguments": args or {}}).encode(), headers=h)
|
||||
try:
|
||||
with urllib.request.urlopen(r, timeout=60) as x: return json.load(x)
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 409: h["X-Transmission-Session-Id"] = e.headers.get("X-Transmission-Session-Id"); continue
|
||||
raise
|
||||
|
||||
|
||||
def state():
|
||||
out = []
|
||||
for t in qb("/api/v2/torrents/info"):
|
||||
out.append(("qbit", t["save_path"].split("/")[3], t["name"][:30], t["state"], round(t["progress"], 4)))
|
||||
for t in tr("torrent-get", {"fields": ["name", "downloadDir", "status", "percentDone", "error", "errorString"]})["arguments"]["torrents"]:
|
||||
st = {0: "stopped", 1: "check-wait", 2: "checking", 3: "dl-wait", 4: "downloading", 5: "seed-wait", 6: "seeding"}.get(t["status"], t["status"])
|
||||
out.append(("trans", t["downloadDir"].split("/")[3], t["name"][:30], st + (" ERR " + t["errorString"][:30] if t["error"] else ""), round(t["percentDone"], 4)))
|
||||
return sorted(out)
|
||||
|
||||
|
||||
step = sys.argv[1]
|
||||
if step == "create":
|
||||
for client, sub in (("qbit", "torrents/tv"), ("trans", "transmission/tv")):
|
||||
d = f"{M}/{sub}/k3-own-bytes-{client}"
|
||||
os.makedirs(d, exist_ok=True)
|
||||
with open(f"{d}/data.bin", "wb") as f: f.write(os.urandom(3_000_000))
|
||||
sh(f"chown -R 1000:1000 '{d}'")
|
||||
tor = mktorrent(d)
|
||||
if client == "qbit":
|
||||
print("qbit add ->", qb("/api/v2/torrents/add", {"category": "tv-drive-c"}, {"torrents": ("k3.torrent", tor)}))
|
||||
else:
|
||||
print("trans add ->", json.dumps(tr("torrent-add", {"metainfo": base64.b64encode(tor).decode(), "download-dir": f"{M}/transmission/tv"}))[:160])
|
||||
time.sleep(20)
|
||||
for s in state(): print(" ", s)
|
||||
elif step == "state":
|
||||
print(f"--- {time.strftime('%H:%M:%S')}")
|
||||
for s in state(): print(" ", s)
|
||||
elif step in ("pause", "resume"):
|
||||
hs = [t["hash"] for t in qb("/api/v2/torrents/info") if t["save_path"].startswith(M)]
|
||||
print(f"qbit {step} {len(hs)} torrent(s) on {DRV} ->", qb(f"/api/v2/torrents/{'stop' if step == 'pause' else 'start'}", {"hashes": "|".join(hs)}) if hs else "none")
|
||||
ids = [t["id"] for t in tr("torrent-get", {"fields": ["id", "downloadDir"]})["arguments"]["torrents"] if t["downloadDir"].startswith(M)]
|
||||
print(f"trans {step} {len(ids)} torrent(s) on {DRV} ->", tr("torrent-stop" if step == "pause" else "torrent-start", {"ids": ids})["result"] if ids else "none")
|
||||
time.sleep(5)
|
||||
for s in state(): print(" ", s)
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
"""run_in_guest.py <script.py> [args] — run one of this folder's stdlib scripts INSIDE the Tester 1 guest
|
||||
(SC=~/.felhom-tester1 TARGET=tester-1) and remove it afterwards. Output only; nothing is left on the box."""
|
||||
import os, sys
|
||||
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
|
||||
import box_walk as w
|
||||
src = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), sys.argv[1])).read()
|
||||
args = " ".join(sys.argv[2:])
|
||||
print(w.guest(f"cat > /root/.media-tool.py <<'PYEOF'\n{src}\nPYEOF\npython3 /root/.media-tool.py {args} 2>&1; rm -f /root/.media-tool.py", timeout=1800))
|
||||
@@ -0,0 +1,374 @@
|
||||
#!/usr/bin/env python3
|
||||
"""wire.py [-v] — (extended 2026-10-14 night, K2: drives from WIRE_DRIVES; download folders; Plex; Jellyfin) — Part C: connect Sonarr and Radarr to qBittorrent and Transmission, ONE ENTRY PER DRIVE, on the box.
|
||||
|
||||
Runs INSIDE the guest (it talks to the containers on the docker network and reads their keys from their own config
|
||||
volumes / environment). Stdlib only. Every key and password is read at runtime and NEVER written to a file or a log:
|
||||
every printed line passes through redact(). `-v` prints every call and the SHAPE of every answer (status, top-level
|
||||
keys / list length) — this is the reference the later link code copies.
|
||||
|
||||
For each drive d in DRIVES, M = /mnt/felhom-drives/<d>/userdata/media (the same path in every container):
|
||||
qBittorrent : categories tv-<d>, movies-<d> -> save path M/torrents/{tv,movies}, incomplete path M/torrents/.temp
|
||||
Sonarr : root folder M/tv; tag <d>; „qBittorrent <d>" (category tv-<d>, tag <d>) and
|
||||
„Transmission <d>" (directory M/transmission/tv, tag <d>)
|
||||
Radarr : the same with movies
|
||||
Sonarr/Radarr: minimum free space when importing = MIN_FREE_MB; „use hardlinks instead of copy" quoted
|
||||
Prowlarr : (when installed) one Application entry each for Sonarr and Radarr, sync level „Full Sync", reached by
|
||||
container name; then an ApplicationIndexerSync command, and the indexers each app holds read back
|
||||
Box-wide, recorded with the reason in the output:
|
||||
qBittorrent : auto_tmm_enabled = true (a category's save path applies ONLY in automatic torrent management;
|
||||
qBittorrent's default is manual, which saves every torrent to the default
|
||||
path = drive A, whatever the category says)
|
||||
Transmission: incomplete-dir-enabled = false (Transmission has ONE incomplete folder for all torrents; on drive A it
|
||||
would make every drive-B download a cross-drive copy at completion)
|
||||
|
||||
Idempotent: an existing tag / root folder / client / category of the same name is left as it is and reported.
|
||||
"""
|
||||
import base64, json, os, re, subprocess, sys, time, urllib.error, urllib.parse, urllib.request
|
||||
|
||||
V = "-v" in sys.argv
|
||||
_d = next((a[7:] for a in sys.argv if a.startswith("drives=")), os.environ.get("WIRE_DRIVES", "drive-a:media_a,drive-b:media_b"))
|
||||
DRIVES = [tuple(x.split(":")) for x in _d.split(",")] # e.g. drives=drive-a:media_a,drive-b:media_b,drive-c:media_c
|
||||
JFPW = "__JF_PW__" # Jellyfin's admin password: substituted into the box's copy by the runner (grun.sh), never stored here
|
||||
MIN_FREE_MB = 10240
|
||||
SECRETS = []
|
||||
|
||||
|
||||
def redact(s):
|
||||
s = str(s)
|
||||
for x in SECRETS:
|
||||
if x:
|
||||
s = s.replace(x, "<redacted>")
|
||||
return s
|
||||
|
||||
|
||||
def say(*a):
|
||||
print(redact(" ".join(str(x) for x in a)), flush=True)
|
||||
|
||||
|
||||
def sh(cmd):
|
||||
return subprocess.run(cmd, shell=True, capture_output=True, text=True).stdout.strip()
|
||||
|
||||
|
||||
def shape(body):
|
||||
if isinstance(body, dict):
|
||||
return "{" + ", ".join(sorted(body.keys()))[:300] + "}"
|
||||
if isinstance(body, list):
|
||||
return f"[list of {len(body)}]"
|
||||
return repr(body)[:120]
|
||||
|
||||
|
||||
def call(method, url, headers=None, data=None, form=False, raw=False, expect=(200, 201, 202, 204)):
|
||||
h = dict(headers or {})
|
||||
if data is not None and not isinstance(data, (bytes, str)):
|
||||
data = urllib.parse.urlencode(data) if form else json.dumps(data)
|
||||
h.setdefault("Content-Type", "application/x-www-form-urlencoded" if form else "application/json")
|
||||
if isinstance(data, str):
|
||||
data = data.encode()
|
||||
req = urllib.request.Request(url, data=data, headers=h, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=60) as r:
|
||||
code, txt, hdrs = r.status, r.read().decode("utf-8", "replace"), {k.lower(): v for k, v in r.headers.items()}
|
||||
except urllib.error.HTTPError as e:
|
||||
code, txt, hdrs = e.code, e.read().decode("utf-8", "replace"), {k.lower(): v for k, v in e.headers.items()}
|
||||
try:
|
||||
body = json.loads(txt) if txt and not raw else txt
|
||||
except ValueError:
|
||||
body = txt
|
||||
if V:
|
||||
say(f" {method} {url} -> {code} {shape(body)}")
|
||||
if code not in expect:
|
||||
say(f" !! {method} {url} -> {code}: {redact(txt)[:600]}")
|
||||
return code, body, hdrs
|
||||
|
||||
|
||||
def ip(c):
|
||||
return sh(f"docker inspect {c} -f '{{{{range .NetworkSettings.Networks}}}}{{{{.IPAddress}}}} {{{{end}}}}'").split()[0]
|
||||
|
||||
|
||||
def apikey(app):
|
||||
x = open(f"/var/lib/docker/volumes/{app}_{app}_config/_data/config.xml").read() # sonarr, radarr, prowlarr
|
||||
k = re.search(r"<ApiKey>([^<]+)</ApiKey>", x).group(1)
|
||||
SECRETS.append(k)
|
||||
return k
|
||||
|
||||
|
||||
def env(c, var):
|
||||
v = sh(f"docker exec {c} printenv {var}")
|
||||
SECRETS.append(v)
|
||||
return v
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- the download folders (the skeleton may not have them)
|
||||
for tag, d in DRIVES:
|
||||
M = f"/mnt/felhom-drives/{d}/userdata/media"
|
||||
made = []
|
||||
for sub in ("torrents", "torrents/tv", "torrents/movies", "transmission", "transmission/tv", "transmission/movies"):
|
||||
if not os.path.isdir(f"{M}/{sub}"):
|
||||
os.makedirs(f"{M}/{sub}"); os.chown(f"{M}/{sub}", 1000, 1000); os.chmod(f"{M}/{sub}", 0o2775); made.append(sub)
|
||||
say(f"== folders on {d}: {'made ' + str(made) if made else 'all present'}")
|
||||
|
||||
# ---------------------------------------------------------------- qBittorrent
|
||||
QB = f"http://{ip('qbittorrent')}:8080"
|
||||
qpw = env("qbittorrent", "QBT_ADMIN_PASSWORD")
|
||||
say("== qBittorrent", QB, "(password: the deploy secret, read from the container's environment)")
|
||||
c, _, hd = call("POST", QB + "/api/v2/auth/login", {"Referer": QB}, {"username": "admin", "password": qpw}, form=True, raw=True)
|
||||
# qBittorrent 5.x names the session cookie QBT_SID_<port> (older versions: SID) — take whichever it set
|
||||
m = re.search(r"((?:QBT_)?SID[A-Za-z0-9_]*)=([^;]+)", hd.get("set-cookie", ""))
|
||||
if not m:
|
||||
sys.exit(say(f" !! no session cookie; answer headers: {sorted(hd)}") or 1)
|
||||
say(f" session cookie name: {m.group(1)}")
|
||||
SECRETS.append(m.group(2))
|
||||
QH = {"Referer": QB, "Cookie": f"{m.group(1)}={m.group(2)}"}
|
||||
c, prefs, _ = call("GET", QB + "/api/v2/app/preferences", QH)
|
||||
say(f" before: auto_tmm_enabled={prefs.get('auto_tmm_enabled')} save_path={prefs.get('save_path')} "
|
||||
f"temp_path_enabled={prefs.get('temp_path_enabled')} temp_path={prefs.get('temp_path')}")
|
||||
call("POST", QB + "/api/v2/app/setPreferences", QH, {"json": json.dumps({"auto_tmm_enabled": True})}, form=True, raw=True)
|
||||
c, prefs, _ = call("GET", QB + "/api/v2/app/preferences", QH)
|
||||
say(f" after : auto_tmm_enabled={prefs.get('auto_tmm_enabled')} (a category's save path applies only in automatic mode)")
|
||||
c, cats, _ = call("GET", QB + "/api/v2/torrents/categories", QH)
|
||||
for tag, d in DRIVES:
|
||||
M = f"/mnt/felhom-drives/{d}/userdata/media"
|
||||
for kind in ("tv", "movies"):
|
||||
name = f"{kind}-{tag}"
|
||||
form = {"category": name, "savePath": f"{M}/torrents/{kind}", "downloadPathEnabled": "true",
|
||||
"downloadPath": f"{M}/torrents/.temp"}
|
||||
ep = "editCategory" if name in (cats or {}) else "createCategory"
|
||||
call("POST", QB + f"/api/v2/torrents/{ep}", QH, form, form=True, raw=True)
|
||||
c, cats, _ = call("GET", QB + "/api/v2/torrents/categories", QH)
|
||||
for n, v in sorted((cats or {}).items()):
|
||||
say(f" category {n}: savePath={v.get('savePath')} downloadPath={v.get('download_path', v.get('downloadPath'))}")
|
||||
|
||||
# ---------------------------------------------------------------- Transmission
|
||||
TR = f"http://{ip('transmission')}:9091/transmission/rpc"
|
||||
tpw = env("transmission", "PASS")
|
||||
TA = "Basic " + base64.b64encode(f"admin:{tpw}".encode()).decode()
|
||||
SECRETS.append(TA.split()[1])
|
||||
say("== Transmission", TR, "(password: the deploy secret, read from the container's environment)")
|
||||
|
||||
|
||||
def trpc(method, args=None, host=None):
|
||||
h = {"Authorization": TA}
|
||||
if host:
|
||||
h["Host"] = host
|
||||
c, b, hd = call("POST", TR, h, {"method": method, "arguments": args or {}}, expect=(200, 409))
|
||||
if c == 409:
|
||||
h["X-Transmission-Session-Id"] = hd.get("x-transmission-session-id", "")
|
||||
c, b, hd = call("POST", TR, h, {"method": method, "arguments": args or {}}, expect=(200, 421))
|
||||
return c, b
|
||||
|
||||
|
||||
c, b = trpc("session-get", {"fields": ["download-dir", "incomplete-dir", "incomplete-dir-enabled", "rename-partial-files"]})
|
||||
say(f" before: {json.dumps((b or {}).get('arguments'))}")
|
||||
trpc("session-set", {"incomplete-dir-enabled": False})
|
||||
c, b = trpc("session-get", {"fields": ["download-dir", "incomplete-dir-enabled", "rename-partial-files"]})
|
||||
say(f" after : {json.dumps((b or {}).get('arguments'))} (one incomplete folder for all torrents would be on drive A)")
|
||||
# The probe the link code needs: can another container reach Transmission BY NAME? (Host-header allow-list)
|
||||
c, b = trpc("session-get", {"fields": ["version"]}, host="transmission:9091")
|
||||
say(f" probe Host: transmission:9091 -> HTTP {c} {redact(str(b))[:160]}")
|
||||
TR_BY_NAME = c == 200
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- Sonarr / Radarr
|
||||
def arr(app, port, kind, root_kind):
|
||||
base = f"http://{ip(app)}:{port}/api/v3"
|
||||
# Host = the container name: Sonarr/Radarr refuse a bare IP once the household sets „Allowed hosts"
|
||||
# (measured 2026-10-14 18:30: 400 „Invalid Hostname" for Host=<ip>, 200 for Host=sonarr)
|
||||
H = {"X-Api-Key": apikey(app), "Host": app}
|
||||
say(f"== {app} {base} (key: <ApiKey> in /config/config.xml, read from the config volume)")
|
||||
c, tags, _ = call("GET", base + "/tag", H)
|
||||
have = {t["label"]: t["id"] for t in tags or []}
|
||||
for tag, _d in DRIVES:
|
||||
if tag not in have:
|
||||
c, t, _ = call("POST", base + "/tag", H, {"label": tag})
|
||||
have[tag] = t["id"]
|
||||
say(f" tags: {have}")
|
||||
c, roots, _ = call("GET", base + "/rootfolder", H)
|
||||
rp = {r["path"].rstrip("/") for r in roots or []}
|
||||
for tag, d in DRIVES:
|
||||
p = f"/mnt/felhom-drives/{d}/userdata/media/{root_kind}"
|
||||
if p not in rp:
|
||||
call("POST", base + "/rootfolder", H, {"path": p})
|
||||
c, roots, _ = call("GET", base + "/rootfolder", H)
|
||||
for r in roots or []:
|
||||
say(f" root folder: {r['path']} accessible={r.get('accessible')} freeSpace={r.get('freeSpace')}")
|
||||
c, schema, _ = call("GET", base + "/downloadclient/schema", H)
|
||||
sch = {s["implementation"]: s for s in schema}
|
||||
c, clients, _ = call("GET", base + "/downloadclient", H)
|
||||
names = {x["name"] for x in clients or []}
|
||||
for tag, d in DRIVES:
|
||||
M = f"/mnt/felhom-drives/{d}/userdata/media"
|
||||
for impl, nm, vals in (
|
||||
("QBittorrent", f"qBittorrent {tag}", {"host": "qbittorrent", "port": 8080, "username": "admin",
|
||||
"password": qpw, f"{kind}Category": f"{'tv' if kind == 'tv' else 'movies'}-{tag}"}),
|
||||
("Transmission", f"Transmission {tag}", {"host": "transmission", "port": 9091, "username": "admin",
|
||||
"password": tpw, "urlBase": "/transmission/",
|
||||
# the schema's default category must be CLEARED: Sonarr/Radarr
|
||||
# refuse „Cannot use Category and Directory" (measured, run 1)
|
||||
f"{kind}Category": "",
|
||||
f"{kind}Directory": f"{M}/transmission/{root_kind}"})):
|
||||
if nm in names:
|
||||
say(f" client {nm}: exists — left as it is")
|
||||
continue
|
||||
body = json.loads(json.dumps(sch[impl]))
|
||||
body.update({"name": nm, "enable": True, "tags": [have[tag]], "priority": 1})
|
||||
for f in body["fields"]:
|
||||
if f["name"] in vals:
|
||||
f["value"] = vals[f["name"]]
|
||||
c, r, _ = call("POST", base + "/downloadclient", H, body, expect=(200, 201, 400))
|
||||
if c == 400:
|
||||
say(f" client {nm}: REFUSED by {app}'s own connection test: {redact(json.dumps(r))[:400]}")
|
||||
c, clients, _ = call("GET", base + "/downloadclient", H)
|
||||
for x in clients or []:
|
||||
f = {k["name"]: k.get("value") for k in x["fields"]}
|
||||
say(f" client {x['name']}: impl={x['implementation']} enable={x['enable']} tags={x['tags']} host={f.get('host')}"
|
||||
f" category={f.get(kind + 'Category')} directory={f.get(kind + 'Directory')}")
|
||||
c, mm, _ = call("GET", base + "/config/mediamanagement", H)
|
||||
say(f" before: minimumFreeSpaceWhenImporting={mm.get('minimumFreeSpaceWhenImporting')} MB, "
|
||||
f"copyUsingHardlinks={mm.get('copyUsingHardlinks')}")
|
||||
mm["minimumFreeSpaceWhenImporting"] = MIN_FREE_MB
|
||||
call("PUT", base + f"/config/mediamanagement/{mm['id']}", H, mm)
|
||||
c, mm, _ = call("GET", base + "/config/mediamanagement", H)
|
||||
say(f" after : minimumFreeSpaceWhenImporting={mm.get('minimumFreeSpaceWhenImporting')} MB, "
|
||||
f"copyUsingHardlinks={mm.get('copyUsingHardlinks')} (default kept)")
|
||||
|
||||
|
||||
arr("sonarr", 8989, "tv", "tv")
|
||||
arr("radarr", 7878, "movie", "movies")
|
||||
say("== done; Transmission reachable by its container name:", TR_BY_NAME)
|
||||
|
||||
# ---------------------------------------------------------------- Prowlarr -> Sonarr / Radarr (Settings -> Apps)
|
||||
def prowlarr():
|
||||
if not sh("docker ps -q -f name=^prowlarr$"):
|
||||
say("== prowlarr: not installed — skipped")
|
||||
return
|
||||
base = f"http://{ip('prowlarr')}:9696/api/v1"
|
||||
H = {"X-Api-Key": apikey("prowlarr"), "Host": "prowlarr"}
|
||||
say(f"== prowlarr {base} (key: <ApiKey> in /config/config.xml, read from the config volume)")
|
||||
c, schema, _ = call("GET", base + "/applications/schema", H)
|
||||
sch = {x["implementation"]: x for x in schema}
|
||||
c, apps, _ = call("GET", base + "/applications", H)
|
||||
have = {a["name"] for a in apps or []}
|
||||
for impl, port in (("Sonarr", 8989), ("Radarr", 7878)):
|
||||
if impl in have:
|
||||
say(f" application {impl}: exists — left as it is")
|
||||
continue
|
||||
body = json.loads(json.dumps(sch[impl]))
|
||||
vals = {"prowlarrUrl": "http://prowlarr:9696", "baseUrl": f"http://{impl.lower()}:{port}",
|
||||
"apiKey": apikey(impl.lower())}
|
||||
for f in body["fields"]:
|
||||
if f["name"] in vals:
|
||||
f["value"] = vals[f["name"]]
|
||||
body.update({"name": impl, "syncLevel": "fullSync", "tags": []})
|
||||
c, r, _ = call("POST", base + "/applications", H, body, expect=(200, 201, 400))
|
||||
if c == 400:
|
||||
say(f" application {impl}: REFUSED by Prowlarr's own test: {redact(json.dumps(r))[:400]}")
|
||||
c, apps, _ = call("GET", base + "/applications", H)
|
||||
for a in apps or []:
|
||||
f = {k["name"]: k.get("value") for k in a["fields"]}
|
||||
say(f" application {a['name']}: syncLevel={a.get('syncLevel')} prowlarrUrl={f.get('prowlarrUrl')} baseUrl={f.get('baseUrl')}"
|
||||
f" syncCategories={f.get('syncCategories')}")
|
||||
c, ix, _ = call("GET", base + "/indexer", H)
|
||||
say(f" indexers in Prowlarr: {[i['name'] for i in ix or []]}")
|
||||
c, cmd, _ = call("POST", base + "/command", H, {"name": "ApplicationIndexerSync"})
|
||||
cid = (cmd or {}).get("id")
|
||||
import time
|
||||
for _ in range(20):
|
||||
time.sleep(3)
|
||||
c, st, _ = call("GET", base + f"/command/{cid}", H)
|
||||
if (st or {}).get("status") in ("completed", "failed", "aborted"):
|
||||
break
|
||||
say(f" ApplicationIndexerSync -> status={(st or {}).get('status')} result={(st or {}).get('result')} message={(st or {}).get('message')}")
|
||||
for app, port in (("sonarr", 8989), ("radarr", 7878)):
|
||||
c, ai, _ = call("GET", f"http://{ip(app)}:{port}/api/v3/indexer", {"X-Api-Key": apikey(app), "Host": app})
|
||||
say(f" {app} now holds {len(ai or [])} indexer(s): {[(i['name'], i.get('implementation')) for i in ai or []]}")
|
||||
|
||||
|
||||
prowlarr()
|
||||
say("== prowlarr part done")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- Plex: add every drive's folder to the EXISTING libraries
|
||||
def plex():
|
||||
if not sh("docker ps -q -f name=^plex$"):
|
||||
say("== plex: not installed — skipped"); return
|
||||
P = "/var/lib/docker/volumes/plex_plex_config/_data/Library/Application Support/Plex Media Server/Preferences.xml"
|
||||
tok = re.search(r'PlexOnlineToken="([^"]+)', open(P).read()).group(1) # the server's own token (K2-5: 401 without)
|
||||
SECRETS.append(tok)
|
||||
B = f"http://{ip('plex')}:32400"
|
||||
H = {"Accept": "application/json", "X-Plex-Token": tok}
|
||||
say(f"== plex {B} (token: the server's own PlexOnlineToken in Preferences.xml)")
|
||||
c, d, _ = call("GET", B + "/library/sections", H)
|
||||
want = {"show": "tv", "movie": "movies"}
|
||||
for sec in (d or {}).get("MediaContainer", {}).get("Directory", []):
|
||||
sub = want.get(sec["type"])
|
||||
if not sub:
|
||||
continue
|
||||
have = [l["path"] for l in sec.get("Location", [])]
|
||||
need = [f"/mnt/felhom-drives/{dd}/userdata/media/{sub}" for _t, dd in DRIVES]
|
||||
missing = [x for x in need if x not in have]
|
||||
if not missing:
|
||||
say(f" library {sec['title']}: every drive's folder already in it — left as it is"); continue
|
||||
q = [("name", sec["title"]), ("type", sec["type"]), ("agent", sec["agent"]), ("scanner", sec["scanner"]),
|
||||
("language", sec["language"])] + [("location", x) for x in have + missing]
|
||||
c, _, _ = call("PUT", B + f"/library/sections/{sec['key']}?" + urllib.parse.urlencode(q), H, expect=(200, 201, 204))
|
||||
say(f" library {sec['title']}: added {missing} -> {c}")
|
||||
c, _, _ = call("GET", B + f"/library/sections/{sec['key']}/refresh", H)
|
||||
say(f" library {sec['title']}: scan started -> {c}")
|
||||
for k in ("FSEventLibraryUpdatesEnabled", "FSEventLibraryPartialScanEnabled"):
|
||||
c, pr, _ = call("GET", B + "/:/prefs", H)
|
||||
cur = next((x["value"] for x in pr["MediaContainer"]["Setting"] if x["id"] == k), None)
|
||||
if cur is True:
|
||||
say(f" pref {k}=True already"); continue
|
||||
c, _, _ = call("PUT", B + f"/:/prefs?{k}=1", H, expect=(200, 204))
|
||||
say(f" pref {k} (R-1037: scan when a change is detected) -> {c}")
|
||||
time.sleep(20)
|
||||
c, d, _ = call("GET", B + "/library/sections", H)
|
||||
for sec in (d or {}).get("MediaContainer", {}).get("Directory", []):
|
||||
c2, a, _ = call("GET", B + f"/library/sections/{sec['key']}/all", H)
|
||||
say(f" library {sec['title']}: folders={[l['path'].split('/')[3] for l in sec.get('Location', [])]} items={[m['title'] for m in (a or {}).get('MediaContainer', {}).get('Metadata', [])]}")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- Jellyfin: add every drive's folder to the EXISTING libraries
|
||||
def jellyfin():
|
||||
if not sh("docker ps -q -f name=^jellyfin$"):
|
||||
say("== jellyfin: not installed — skipped"); return
|
||||
B = f"http://{ip('jellyfin')}:8096"
|
||||
A = 'MediaBrowser Client="felhom", Device="wire", DeviceId="felhom-wire", Version="1"'
|
||||
SECRETS.append(JFPW)
|
||||
c, r, _ = call("POST", B + "/Users/AuthenticateByName", {"Authorization": A}, {"Username": "admin", "Pw": JFPW})
|
||||
tok = r["AccessToken"]; SECRETS.append(tok)
|
||||
H = {"X-Emby-Token": tok}
|
||||
say(f"== jellyfin {B} (an admin session: the box made the first admin itself, so it holds the password)")
|
||||
c, keys, _ = call("GET", B + "/Auth/Keys", H)
|
||||
if not any(k.get("AppName") == "felhom" for k in (keys or {}).get("Items", [])):
|
||||
c, _, _ = call("POST", B + "/Auth/Keys?app=felhom", H, expect=(200, 204))
|
||||
say(f" API key for the box (POST /Auth/Keys?app=felhom) -> {c} (needs an admin session; without one, one household step)")
|
||||
else:
|
||||
say(" API key for the box: exists")
|
||||
c, vf, _ = call("GET", B + "/Library/VirtualFolders", H)
|
||||
want = {"tvshows": "tv", "movies": "movies"}
|
||||
for v in vf or []:
|
||||
sub = want.get(v.get("CollectionType"))
|
||||
if not sub:
|
||||
continue
|
||||
need = [f"/mnt/felhom-drives/{dd}/userdata/media/{sub}" for _t, dd in DRIVES]
|
||||
missing = [x for x in need if x not in v.get("Locations", [])]
|
||||
if not missing:
|
||||
say(f" library {v['Name']}: every drive's folder already in it — left as it is"); continue
|
||||
for x in missing:
|
||||
c, _, _ = call("POST", B + "/Library/VirtualFolders/Paths?refreshLibrary=false", H,
|
||||
{"Name": v["Name"], "PathInfo": {"Path": x}}, expect=(200, 204))
|
||||
say(f" library {v['Name']}: added {x} -> {c}")
|
||||
c, _, _ = call("POST", B + "/Library/Refresh", H, expect=(200, 204))
|
||||
say(f" scan -> {c}")
|
||||
time.sleep(25)
|
||||
c, vf, _ = call("GET", B + "/Library/VirtualFolders", H)
|
||||
for v in vf or []:
|
||||
say(f" library {v['Name']}: folders={[l.split('/')[3] for l in v.get('Locations', [])]}")
|
||||
c, it, _ = call("GET", B + "/Items?Recursive=true&IncludeItemTypes=Series,Movie", H)
|
||||
say(f" items: {sorted(i['Name'] for i in (it or {}).get('Items', []))}")
|
||||
|
||||
|
||||
plex()
|
||||
jellyfin()
|
||||
say("== all parts done")
|
||||
Reference in New Issue
Block a user