feat: arr-native distributed media sync + config architecture fixes
Arr sync (new): - Media/arr_sync.sh — full mesh bidirectional sync across all HOST* nodes - Lidarr (MusicBrainz), Sonarr (TVDB), Radarr (TMDB) all handled in one script - Remote API keys read live from config.xml via SSH — never stored in conf files - Shared blocklist (DATA_DIR/arr_sync_blocklist.tsv) merged from all nodes at runtime - Graceful skip if arr not configured locally or not reachable on a remote node - --blocklist-add / --blocklist-remove / --blocklist-list management flags - daily_sync_maintenance.sh — arr sync runs as explicit phase before rsync - partnership_onboard.sh — Step 3 bootstraps merged library on both sides at onboard - master.conf — ARR_SYNC_* config block, DOCKER_APPDATA_BASE Rsync / cleanup: - DEFAULT_RSYNC_OPTS — removed --delete; arr_cleanup.sh owns orphan enforcement - lidarr_cleanup.sh — removed HOST1-only guard; runs on any node with Lidarr configured Config architecture: - HOST1/HOST2 hostnames moved from master_host*.conf → master.conf (not credentials) - Sparse checkout now works correctly: each server only needs its own host conf - detect_hosts() still resolves MY_ID + REMOTE_ID via master.conf hostname values Bug fix: - common.sh line 493 — watchdog toggle eval had broken quoting; all SYS_WATCHDOG_CHECK_* globals were silently set to empty instead of their configured values Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
009820e981
commit
b65f572367
+39
-9
@@ -47,8 +47,8 @@
|
||||
# REMOTE HEALTH CHECKS Rootfs threshold for pre-flight abort
|
||||
# RSYNC PROFILE SYSTEM Per-profile overrides for appdata syncs
|
||||
#
|
||||
# ── FAILOVER ───────────────────────────────────────────────────────────────────────────────
|
||||
# FAILOVER Mutual container failover shared settings
|
||||
# ── FALLBACK ───────────────────────────────────────────────────────────────────────────────
|
||||
# FALLBACK Mutual container failover shared settings
|
||||
# FALLBACK TEST Simulated outage settings for fallback_test.sh
|
||||
#
|
||||
# ── DOCKER ESSENTIALS ──────────────────────────────────────────────────────────────────────
|
||||
@@ -92,10 +92,20 @@
|
||||
#
|
||||
# ==============================================================================================
|
||||
|
||||
# ==============================================================================================
|
||||
# ── HOST IDENTITIES ───────────────────────────────────────────────────────────────────────────
|
||||
# ==============================================================================================
|
||||
# Hostnames for every server in the ecosystem — not credentials, safe for all machines.
|
||||
# Must match the exact unRAID hostname AND Tailscale device name (case sensitive).
|
||||
# detect_hosts() in common.sh matches the local hostname against these to set MY_ID / REMOTE_ID.
|
||||
# Tailscale IP resolution uses these names — no hardcoded IPs needed.
|
||||
# To add a new server: add HOST3="unRAID-NewServer" here + create master_host3.conf.
|
||||
HOST1="unRAID-Gmer4Lfe"
|
||||
HOST2="unRAID-Jayred365"
|
||||
|
||||
# ==============================================================================================
|
||||
# ── SHARED HOST CONFIGURATION ─────────────────────────────────────────────────────────────────
|
||||
# ==============================================================================================
|
||||
# Hostnames defined in master_host*.conf — detect_hosts() reads them at runtime.
|
||||
# DATA_DIR is the same path on all servers — persistent script state and statistics.
|
||||
# Array share — survives reboots, no flash drive wear.
|
||||
# Created automatically if it doesn't exist.
|
||||
@@ -109,6 +119,19 @@
|
||||
# "abort" — refuse to continue (strict — ensures both sides always match)
|
||||
UNRAID_VERSION_MISMATCH_ACTION="warn"
|
||||
|
||||
# ── Arr Sync ──
|
||||
# arr_sync.sh syncs Lidarr/Sonarr/Radarr libraries across all nodes bidirectionally.
|
||||
# Runs before rsync — all nodes agree on tracked library before files are transferred.
|
||||
# Remote API keys are read live from each node's config.xml via SSH — never stored here.
|
||||
ARR_SYNC_ENABLED=true
|
||||
ARR_SYNC_BLOCKLIST="${DATA_DIR}/arr_sync_blocklist.tsv"
|
||||
ARR_SYNC_CONNECT_TIMEOUT=10 # seconds — SSH connect timeout per node
|
||||
ARR_SYNC_API_TIMEOUT=60 # seconds — curl timeout for library fetches
|
||||
DOCKER_APPDATA_BASE="/mnt/user/appdata"
|
||||
ARR_SYNC_LIDARR_PORT=8686
|
||||
ARR_SYNC_SONARR_PORT=8989
|
||||
ARR_SYNC_RADARR_PORT=7878
|
||||
|
||||
# ── Remote Docker Daemon ──
|
||||
# Strike system for remote Docker daemon health checks.
|
||||
# Scripts that issue remote container commands check the remote daemon first.
|
||||
@@ -269,6 +292,8 @@
|
||||
#"Media/lidarr_cleanup.sh" # remove orphaned music files — enable when ready
|
||||
#"Media/sonarr_cleanup.sh" # remove orphaned TV files — enable when ready
|
||||
#"Media/radarr_cleanup.sh" # remove orphaned movie files — enable when ready
|
||||
"Media/radarr_tmdb_removed.sh" # remove movies dropped from TMDb
|
||||
"Media/sonarr_tvdb_removed.sh" # remove series dropped from TVDB
|
||||
"Docker_Essentials/docker_update.sh" # pull container image updates before restart
|
||||
"Docker_Essentials/docker_daily_restart.sh" # daily container restarts — runs last
|
||||
)
|
||||
@@ -373,10 +398,11 @@
|
||||
CONTAINER_DELAY=5 # seconds before starting delayed containers
|
||||
EXCLUDE_DIRS=() # directories excluded from transfer — profiles override
|
||||
|
||||
# --delete removes files on remote not on source (mirror behaviour)
|
||||
# --inplace writes directly to destination — better for large files
|
||||
# --no-whole-file forces delta transfer — sends only changed blocks
|
||||
DEFAULT_RSYNC_OPTS=(-av --info=progress2 --human-readable --bwlimit="$BW_LIMIT" --delete --inplace --no-whole-file)
|
||||
# --delete intentionally omitted — arr_cleanup.sh enforces media truth post-rsync.
|
||||
# Media shares use this default; rsync spreads files only, never removes them.
|
||||
DEFAULT_RSYNC_OPTS=(-av --info=progress2 --human-readable --bwlimit="$BW_LIMIT" --inplace --no-whole-file)
|
||||
|
||||
# ━━━ Remote Health Checks ━━━
|
||||
# Pre-flight — aborts if remote rootfs (/) usage is at or above this percentage.
|
||||
@@ -502,13 +528,13 @@
|
||||
# check_remote_disks() reads fsType per disk and handles XFS, ZFS, and cache pools automatically.
|
||||
|
||||
# ==============================================================================================
|
||||
# ── FAILOVER ──────────────────────────────────────────────────────────────────────────────────
|
||||
# ── FALLBACK ──────────────────────────────────────────────────────────────────────────────────
|
||||
# ==============================================================================================
|
||||
# Mutual container failover between two unRAID servers.
|
||||
# Each server runs Fallback/fallback.sh independently via array_start.sh.
|
||||
# All decisions based on two pings: remote reachable + internet reachable.
|
||||
#
|
||||
# States: NORMAL | FAILOVER | NO_INTERNET | DARK
|
||||
# States: NORMAL | FALLBACK | NO_INTERNET | DARK
|
||||
#
|
||||
# DDNS rules — absolute:
|
||||
# Internet loss → stop own DDNS immediately
|
||||
@@ -519,8 +545,8 @@
|
||||
# Shared settings (intervals, state file, thresholds) live here.
|
||||
|
||||
EXTERNAL_IP="8.8.8.8"
|
||||
FALLBACK_CHECK_INTERVAL=120 # seconds between fallback state checks
|
||||
FALLBACK_HANDBACK_STRIKES=2 # consecutive healthy checks before initiating handback
|
||||
FALLBACK_CHECK_INTERVAL=30 # seconds between fallback state checks
|
||||
FALLBACK_HANDBACK_STRIKES=3 # consecutive healthy checks before initiating handback (3×30s = 90s)
|
||||
FALLBACK_STATE_FILE="/boot/config/fallback_state.db"
|
||||
FALLBACK_ENABLED=false # HOST2 being rebuilt — set true when back online and tested
|
||||
# false = suppresses "not running" warnings in status scripts
|
||||
@@ -910,6 +936,10 @@
|
||||
"theme.mp3" "theme.flac" "theme.wav" "theme.m4a" "theme.mka"
|
||||
)
|
||||
|
||||
# Radarr/Sonarr TMDb/TVDB removed entry cleanup
|
||||
RADARR_DROPPED_ADD_EXCLUSION=true # add removed movies to import exclusion list
|
||||
SONARR_DROPPED_ADD_EXCLUSION=true # add removed series to import exclusion list
|
||||
|
||||
# ━━━ Arr Failed/Stalled Recovery ━━━
|
||||
# Auto blocklist + re-search failed imports and stalled downloads.
|
||||
# Runs every 6 hours — schedule: 0 */6 * * *
|
||||
|
||||
Reference in New Issue
Block a user