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.
This commit is contained in:
@@ -20,22 +20,91 @@
|
||||
# and running them concurrently would just contend for the same disk I/O for no benefit.
|
||||
#
|
||||
# ==============================================================================================
|
||||
# OPERATIONAL MODEL
|
||||
# ==============================================================================================
|
||||
#
|
||||
# Lidarr, then Sonarr, then Radarr — strictly sequential. Per arr:
|
||||
#
|
||||
# 1. Reachability
|
||||
# → check_api; unreachable skips this arr only
|
||||
#
|
||||
# 2. Already-scanning check
|
||||
# → a rescan already active (manual, or another script) means skip rather than
|
||||
# stack a second full-disk walk on top of it
|
||||
#
|
||||
# 3. Capture the before count
|
||||
# → tracked file count read from the arr's own stats
|
||||
#
|
||||
# 4. Trigger the rescan command
|
||||
# → RescanFolders (Lidarr) / RescanSeries (Sonarr) / RescanMovie (Radarr)
|
||||
#
|
||||
# 5. Poll to completion
|
||||
# → bounded by ARR_FULL_RESCAN_TIMEOUT
|
||||
#
|
||||
# 6. Report the delta
|
||||
# → before vs after tracked count, so drift that was corrected is visible
|
||||
#
|
||||
# ==============================================================================================
|
||||
# DESIGN PRINCIPLES
|
||||
# ==============================================================================================
|
||||
#
|
||||
# Proactive, Not Reactive
|
||||
# check_tracked_count_floor() catches stat drift reactively, at the moment some other
|
||||
# script is about to act on bad numbers. This job exists so that drift is corrected on a
|
||||
# schedule instead of being discovered by whichever cleanup happens to trip over it first.
|
||||
#
|
||||
# Sequential by Design
|
||||
# Each rescan is a full-disk walk. Running three concurrently contends for the same
|
||||
# spindles and finishes no sooner, so the arrs are never parallelised — the slowness is
|
||||
# accepted deliberately rather than optimised into I/O thrash.
|
||||
#
|
||||
# Never Stack a Scan
|
||||
# An already-running rescan is left alone rather than duplicated. A second concurrent
|
||||
# walk of the same library doubles the I/O cost and returns nothing the first will not.
|
||||
#
|
||||
# Per-Arr Isolation
|
||||
# One arr being down, slow, or already scanning must never prevent the other two from
|
||||
# being reconciled. Partial coverage beats a skipped run.
|
||||
#
|
||||
# ==============================================================================================
|
||||
# OPERATIONAL SAFEGUARDS
|
||||
# ==============================================================================================
|
||||
#
|
||||
# Root required — required for consistency across Arrs_Stack/, no direct fs writes here
|
||||
# acquire_lock "wait" — waits for a prior run to finish rather than skipping or colliding;
|
||||
# a full-library rescan across three arrs can run long, worth queuing
|
||||
# behind rather than silently no-op'ing
|
||||
# Reachability check — check_api before touching an arr; unreachable → skip that arr only
|
||||
# Active-rescan check — skips triggering a NEW rescan if one's already active on that arr
|
||||
# (manual trigger, another script) — never stacks a duplicate scan,
|
||||
# see Tools/arr_rescan_monitor.sh for catching up that arr's cache
|
||||
# once the pre-existing scan finishes instead of waiting for next week
|
||||
# Sequential only — never runs two arrs' rescans in parallel; each is a heavy full-disk
|
||||
# walk and concurrent walks would just contend for the same disk I/O
|
||||
# Per-arr isolation — one arr failing, timing out, or being skipped never blocks the others
|
||||
# --dry-run mode — reports which arrs would be rescanned, triggers nothing
|
||||
# Root Enforcement
|
||||
# Kept for consistency across Arrs_Stack/ — this script makes no direct filesystem writes.
|
||||
#
|
||||
# Lock Acquisition
|
||||
# acquire_lock "wait" — waits for a prior run rather than skipping or colliding. A full
|
||||
# rescan across three arrs runs long and is worth queuing behind, not silently dropping.
|
||||
#
|
||||
# Host Detection
|
||||
# detect_hosts() aliases each arr's URL and API key.
|
||||
#
|
||||
# jq Dependency Check
|
||||
# Fails fast if jq is missing. Both the before/after tracked counts and the command
|
||||
# payload are built with jq — without it the counts read empty and every delta would be
|
||||
# reported as if nothing changed.
|
||||
#
|
||||
# Reachability Check
|
||||
# check_api before touching an arr; unreachable skips that arr only.
|
||||
#
|
||||
# Active-Rescan Check
|
||||
# Skips triggering a new rescan if one is already active on that arr, so a duplicate
|
||||
# full-disk walk is never stacked. See Tools/arr_rescan_monitor.sh for catching that
|
||||
# arr's cache up once the pre-existing scan finishes, rather than waiting a week.
|
||||
#
|
||||
# Sequential Only
|
||||
# Two arrs' rescans never run in parallel.
|
||||
#
|
||||
# Per-Arr Isolation
|
||||
# One arr failing, timing out, or being skipped never blocks the others.
|
||||
#
|
||||
# Timeout Bound
|
||||
# ARR_FULL_RESCAN_TIMEOUT caps the wait per arr, so a rescan that never completes cannot
|
||||
# hold the weekly window open indefinitely.
|
||||
#
|
||||
# Dry Run Support
|
||||
# --dry-run reports which arrs would be rescanned and triggers nothing.
|
||||
#
|
||||
# ==============================================================================================
|
||||
# CONFIGURATION
|
||||
@@ -72,6 +141,14 @@ if [[ "$EUID" -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Both the tracked-count reads and the command payload are built with jq — without it the
|
||||
# counts read empty and every arr would report a zero delta as if nothing had drifted.
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
error "jq not found — required for JSON parsing"
|
||||
notify "Arr full rescan failed on $(hostname) — jq not installed" "Arr Full Rescan" "warning"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
acquire_lock "wait"
|
||||
|
||||
detect_hosts
|
||||
|
||||
Reference in New Issue
Block a user