Commit Graph
13 Commits
Author SHA1 Message Date
Gmer4Lfe e8b114094a Bring script headers onto the template and close safeguard gaps
Headers claimed protections the code never had, and several destructive paths had no
guard against a collapsed config value.
2026-08-01 20:37:59 -04:00
Gmer4Lfe a1db8f7b2d Restore executable bit on the three arr cleanup scripts 2026-07-27 18:38:46 -04:00
Gmer4Lfe d680bd0549 Gate arr orphan deletion on ctime and stop the nightly permissions pass from restamping it — imports preserve the release's original mtime, so the age gate never actually fired for real content 2026-07-27 18:38:18 -04:00
Gmer4Lfe 2ce368abba Fix radarr_cleanup.sh missing secondary edition files as false-positive orphans
Radarr 6+ supports multiple tracked files per movie (alternate editions/extras),
but the movie list's embedded movieFile.path only ever reflects the primary one.
Relying on it alone flagged legitimately-tracked secondary edition files as
orphans. Now batch-fetches /moviefile?movieId=X across all tracked movies to
catch every file, not just the primary.
2026-07-19 10:04:47 -04:00
Gmer4Lfe d2e071dece Use find -printf instead of per-file stat fork in cleanup scripts
lidarr_cleanup.sh/sonarr_cleanup.sh/radarr_cleanup.sh each forked a
separate stat call per file during classification. find already has to
stat() every entry to know it's -type f, so -printf '%s %T@ %p' gets
size+mtime for free during the walk itself. Measured: 5.77s for all
175,954 files in the Lidarr music root (walk + stat combined) vs 85.98s
for stat alone on a 20K-file subset of the same library -- roughly 130x
faster per file, and collapses two passes into one. Verified path
parsing preserves spaces/parens/unicode exactly via read's trailing-
field capture before switching.
2026-07-17 01:52:30 -04:00
Gmer4Lfe bac1ef1c17 Update headers on today's arr-caching changes
Comment-only. Headers on the scripts touched during today's caching work
(cache-first fetches, write-through per-item cache, single-walk
consolidation, movieFile-embedded fix) still described pre-change
behavior. Also brought common.sh's top-level cache doc block current --
it was written for the single-consumer 2026-07-16 state and didn't
mention the tmpfs move, the write guard, or the 15+ consumers that now
go through it.
2026-07-17 01:08:46 -04:00
Gmer4Lfe a018245f40 Consolidate cleanup scripts' double filesystem walk into one
lidarr_cleanup.sh/sonarr_cleanup.sh/radarr_cleanup.sh each walked their
full media root twice per run: once to classify files and total the
deletion size for the safety-threshold check, then again to actually
delete. The size check needs to know the total before deleting anything,
not before knowing what to delete -- the classification pass now records
orphan/junk paths as it finds them, and the deletion pass just reads that
list instead of re-walking and re-classifying the whole tree again. Only
affects real (non-dry-run) executions, where the second walk used to
happen. Also merges two separate stat calls per file into one.
2026-07-17 00:37:31 -04:00
Gmer4Lfe a22433967a Eliminate radarr_cleanup.sh's per-movie API calls
Radarr's movie list already embeds movieFile.path on every hasFile=true
entry -- confirmed live, zero exceptions across the full library. The
separate moviefile?movieId=X call per movie (2896 of them) was fetching
data already sitting in the list this script fetches anyway. One live
list fetch replaces up to 2896 per-movie calls, every time this function
runs including rescan-aware retries.
2026-07-17 00:25:18 -04:00
Gmer4Lfe 5866097d6a Make all arr library-list fetches cache-first with live fallback
Every script that fetches the full Lidarr/Sonarr/Radarr tracked-library
list now goes through arr_get_tracked_data() instead of hitting the API
directly -- cache-first when fresh, live fetch as fallback when stale,
waits out an active rescan before either. Per-item file data (trackFile/
episodefile/moviefile) stays live-only everywhere, since that's the
actual disk-truth these scripts' decisions depend on and was never part
of what's cached.

Also adds arr_cache_prefill.sh to CRITICAL_MAINTENANCE_SCRIPTS (30min
tier) with a short 1min wait ceiling, so the cache stays consistently
fresh instead of only refreshing whenever some other script happens to
write through. A full cache refresh for all three arrs measured at ~12s
total live -- nothing like the multi-hour cost of an actual rescan.
2026-07-16 23:27:23 -04:00
Gmer4Lfe c7ecf99c3f Generalize tracked-data cache from Lidarr-only to all three arrs
Shared cache/rescan-duration logic in common.sh now takes an arr_type
param instead of being Lidarr-specific, so Sonarr and Radarr cleanup
scripts get the same cache-first fetch + rescan-aware retry Lidarr had.
Avoids redundant full-library API calls across scripts run back to back,
and stops false failures when a fetch lands mid-rescan.
2026-07-16 15:34:56 -04:00
Gmer4Lfe 6623d1e776 Fix dead/incorrect vars and consolidate duplicated logic into common.sh
Codebase-wide audit pass: fixed real bugs (SSH hangs missing BatchMode,
local-outside-function no-ops, variable name collisions, a truncated
ratio calc, wrong state-dir path, DARK vs NO_INTERNET drift, and more),
then pulled logic that was duplicated across multiple scripts — arr
cleanup safety gates, docker restart ordering, container maintenance
stop/restart, watchdog state-file helpers, partnership role resolution,
cert expiry checks, remote node discovery, and TMDB discovery scoring —
into common.sh so each now has a single implementation.
2026-07-03 23:52:33 -04:00
Gmer4Lfe 69189bbf18 Fix dead-variable and exit-code bugs found in codebase-wide audit
Same audit as the orchestrator standardization pass (2a062e5), extended to
every remaining script. Found the same class of bug independently recurring:
ramdisk_stop.sh checked $LOG (nothing assigns it, should be $ENABLE_LOGGING),
partnership_onboard.sh checked $LOG_MODE (same issue), emby_session_report.sh
checked $TRANSCODE_PCT which was never computed so the high-transcode alert
could never fire, and storage_migrate.sh never called detect_hosts() so
$MY_ID was empty, silently breaking the post-migration host*.conf update.
partnership_manager.sh used `local` at top-level script scope (invalid outside
a function) and had two master.conf path references missing "Configurations/".

Along the way: several scripts (share_setup.sh, conf_sync.sh,
downloaders_reset.sh, transcode_cleanup.sh, transcode_manager.sh,
remote_arr_cache_writer.sh, upgrade_webhook_handler.sh) had no explicit
trailing exit code, so they always reported success regardless of real
failures. play_state_sync.sh was missing the partnership gate its own header
documented, so remote play-state sync ran even with PARTNERSHIP_ENABLED=false;
it also always exited 0 on sync errors. arr_profile_enforcer.sh and
webhook_setup.sh hand-rolled their own flag parsing instead of common.sh's
parse_args, so --log silently did nothing on either.

system_watchdog.sh was itself an un-standardized mini-orchestrator — converted
to the shared run_orch_child()/JOB_PASS/JOB_FAIL pattern, added the missing
failure notification, and fixed dry-run to pass --dry-run down to children
instead of skipping them outright. Also fixed a stale webgui_watchdog.sh path
in master.conf.template that would break system_watchdog.sh on any fresh
install.

Closed a sibling-drift gap: radarr_cleanup.sh and sonarr_cleanup.sh were
missing lidarr_cleanup.sh's tracked-count percentage-drop safety gate and its
"not configured on this host, skip cleanly" guard — both now match Lidarr's
7-gate model.
2026-07-03 17:35:30 -04:00
Gmer4Lfe b4bc9267e9 Move arr stack scripts from Media/ to Arrs_Stack/
Media/ now holds only media-level scripts (cleaner, permissions, play_state_sync).
All arr management scripts (cleanup, discovery, sync, webhooks, release fixer) live in Arrs_Stack/.
2026-06-27 18:39:33 -04:00