incorp, host profiles into scripts that needed it

This commit is contained in:
2026-04-19 17:39:11 -04:00
parent af14a5ca2c
commit cbfdc488c3
6 changed files with 172 additions and 35 deletions
+18
View File
@@ -53,6 +53,24 @@ fi
success "Running as root"
# Select correct per-host watchdog lists
detect_hosts
if [[ "$LOCAL_SERVER_NAME" == "$HOST1" ]]; then
WATCHDOG_REQUIRED_CONTAINERS=("${HOST1_WATCHDOG_REQUIRED_CONTAINERS[@]}")
declare -A WATCHDOG_CONTAINER_URLS
for key in "${!HOST1_WATCHDOG_CONTAINER_URLS[@]}"; do
WATCHDOG_CONTAINER_URLS["$key"]="${HOST1_WATCHDOG_CONTAINER_URLS[$key]}"
done
else
WATCHDOG_REQUIRED_CONTAINERS=("${HOST2_WATCHDOG_REQUIRED_CONTAINERS[@]}")
declare -A WATCHDOG_CONTAINER_URLS
for key in "${!HOST2_WATCHDOG_CONTAINER_URLS[@]}"; do
WATCHDOG_CONTAINER_URLS["$key"]="${HOST2_WATCHDOG_CONTAINER_URLS[$key]}"
done
fi
info "Watchdog running as: $LOCAL_SERVER_NAME"
if ! command -v docker >/dev/null 2>&1; then
error "Docker not found"
exit 1
+74 -31
View File
@@ -679,14 +679,19 @@ declare -A WATCHDOG_CONTAINERS=(
["Code-Server"]=1024
)
declare -A WATCHDOG_CONTAINER_URLS=(
# Per-host HTTP health check URLs — docker_watchdog.sh picks correct list via detect_hosts()
declare -A HOST1_WATCHDOG_CONTAINER_URLS=(
["Emby"]="http://localhost:8096"
)
# Containers that must always be running — strike system, persistent skip list on /boot/
# Skip list auto-clears when container recovers — no manual intervention for normal recovery
# These are your core auth and proxy stack — everything depends on them being up
WATCHDOG_REQUIRED_CONTAINERS=(
declare -A HOST2_WATCHDOG_CONTAINER_URLS=(
["Emby"]="http://localhost:8096" # his Emby — same port, different server
)
# Per-host required containers — core stack that must always be running
# docker_watchdog.sh picks correct list via detect_hosts()
# Strike system — persistent skip list on /boot/, auto-clears on recovery
HOST1_WATCHDOG_REQUIRED_CONTAINERS=(
"NginxProxyManager"
"Lldap-Gmer4Lfe"
"Authelia"
@@ -696,6 +701,11 @@ WATCHDOG_REQUIRED_CONTAINERS=(
"Redis-Authelia-Secondary"
)
HOST2_WATCHDOG_REQUIRED_CONTAINERS=(
"NginxProxyManager"
# add HOST2's required containers here
)
# Strike state file — /tmp resets on reboot which is correct for strike tracking
WATCHDOG_STATE_FILE="/tmp/container_watchdog_state.db"
@@ -909,6 +919,13 @@ MEDIA_MAINTENANCE_JOBS=(
# Each arr script queries its API to get all tracked file paths, then compares against
# what exists on disk. Files not tracked by the arr and older than ORPHAN_AGE days are deleted.
#
# Each server runs different arrs managing different shares:
# HOST1: Sonarr (Tv_Shows), Radarr (Movies), Lidarr (Music)
# HOST2: Sonarr (Anime_Shows), Radarr (Anime_Movies)
#
# detect_hosts() selects the correct URL, API key, and root path at runtime.
# Scripts run identically on both servers — configuration drives behavior.
#
# Why the age threshold matters:
# The arr downloads a file then processes it — there is a window where the file exists
# on disk but the arr hasn't imported it yet. ORPHAN_AGE prevents deleting files that
@@ -917,33 +934,52 @@ MEDIA_MAINTENANCE_JOBS=(
# Protected patterns are NEVER deleted regardless of tracking status or age.
# These protect arr-generated metadata (cover art, .nfo files, subtitles) that the arr
# depends on but does not include in its tracked file API response.
# Add new patterns here if arr metadata formats change in future versions.
# Lidarr — music library
LIDARR_URL="http://192.168.50.2:8686"
LIDARR_API_KEY="b2977e71ef074bc0a0529d9fcce3b2dc"
LIDARR_MUSIC_ROOT="/mnt/user/Music-New" # must match the root path set in Lidarr
LIDARR_ORPHAN_AGE=7 # days before untracked file is eligible for deletion
LIDARR_EXTENSIONS=("flac" "mp3" "m4a" "wav" "aac" "ogg" "opus" "wma")
LIDARR_PROTECTED_PATTERNS=("*.jpg" "*.jpeg" "*.png" "*.nfo" "*.lrc")
# never deleted — cover art, metadata, lyrics
# ── Lidarr ────────────────────────────────────────────────────────────────────────────────────
# Lidarr runs on HOST1 only — music library management
# HOST2 does not run Lidarr — no HOST2 Lidarr config needed
# Sonarr — TV library
SONARR_URL="http://192.168.50.2:8989"
SONARR_API_KEY="130decd3db5b4c25afad64864cd03f9f"
SONARR_TV_ROOT="/mnt/user/Tv_Shows" # must match the root path set in Sonarr
SONARR_ORPHAN_AGE=7
SONARR_EXTENSIONS=("mkv" "mp4" "avi" "m4v" "ts" "wmv" "mov")
SONARR_PROTECTED_PATTERNS=("*.jpg" "*.jpeg" "*.png" "*.nfo" "*.srt" "*.sub" "*.ass" "*.ssa")
# never deleted — artwork, metadata, subtitles
HOST1_LIDARR_URL="http://192.168.50.2:8686"
HOST1_LIDARR_API_KEY="b2977e71ef074bc0a0529d9fcce3b2dc"
HOST1_LIDARR_MUSIC_ROOT="/mnt/user/Music-New" # must match root path set in Lidarr exactly
# Radarr — movie library
RADARR_URL="http://192.168.50.2:7878"
RADARR_API_KEY="d43a3ec6cf1549edb4af0cc63f98b2a9"
RADARR_MOVIES_ROOT="/mnt/user/Movies" # must match the root path set in Radarr
RADARR_ORPHAN_AGE=7
RADARR_EXTENSIONS=("mkv" "mp4" "avi" "m4v" "wmv" "mov")
RADARR_PROTECTED_PATTERNS=("*.jpg" "*.jpeg" "*.png" "*.nfo" "*.srt" "*.sub" "*.ass" "*.ssa")
LIDARR_ORPHAN_AGE=7 # days before untracked file eligible for deletion
LIDARR_EXTENSIONS=("flac" "mp3" "m4a" "wav" "aac" "ogg" "opus" "wma")
LIDARR_PROTECTED_PATTERNS=("*.jpg" "*.jpeg" "*.png" "*.nfo" "*.lrc")
# never deleted — cover art, metadata, lyrics
# ── Sonarr ────────────────────────────────────────────────────────────────────────────────────
# HOST1 Sonarr manages Tv_Shows — HOST2 Sonarr manages Anime_Shows
# Scripts run on each server and hit their own local Sonarr instance
HOST1_SONARR_URL="http://192.168.50.2:8989"
HOST1_SONARR_API_KEY="130decd3db5b4c25afad64864cd03f9f"
HOST1_SONARR_TV_ROOT="/mnt/user/Tv_Shows" # must match root path set in HOST1 Sonarr exactly
HOST2_SONARR_URL="http://localhost:8989" # HOST2 local Sonarr — update with actual port
HOST2_SONARR_API_KEY="your-host2-sonarr-api-key"
HOST2_SONARR_TV_ROOT="/mnt/user/Anime_Shows" # must match root path set in HOST2 Sonarr exactly
SONARR_ORPHAN_AGE=7
SONARR_EXTENSIONS=("mkv" "mp4" "avi" "m4v" "ts" "wmv" "mov")
SONARR_PROTECTED_PATTERNS=("*.jpg" "*.jpeg" "*.png" "*.nfo" "*.srt" "*.sub" "*.ass" "*.ssa")
# never deleted — artwork, metadata, subtitles
# ── Radarr ────────────────────────────────────────────────────────────────────────────────────
# HOST1 Radarr manages Movies — HOST2 Radarr manages Anime_Movies
# Scripts run on each server and hit their own local Radarr instance
HOST1_RADARR_URL="http://192.168.50.2:7878"
HOST1_RADARR_API_KEY="d43a3ec6cf1549edb4af0cc63f98b2a9"
HOST1_RADARR_MOVIES_ROOT="/mnt/user/Movies" # must match root path set in HOST1 Radarr exactly
HOST2_RADARR_URL="http://localhost:7878" # HOST2 local Radarr — update with actual port
HOST2_RADARR_API_KEY="your-host2-radarr-api-key"
HOST2_RADARR_MOVIES_ROOT="/mnt/user/Anime_Movies" # must match root path set in HOST2 Radarr exactly
RADARR_ORPHAN_AGE=7
RADARR_EXTENSIONS=("mkv" "mp4" "avi" "m4v" "wmv" "mov")
RADARR_PROTECTED_PATTERNS=("*.jpg" "*.jpeg" "*.png" "*.nfo" "*.srt" "*.sub" "*.ass" "*.ssa")
# ==============================================================================================
# ── TRANSCODES ────────────────────────────────────────────────────────────────────────────────
@@ -1090,8 +1126,15 @@ ZFS_REPORT_IGNORE_POOLS=(
# ━━━ Emby Session Report ━━━
# Requires API key from Emby Settings → API Keys in the Emby WebUI.
# No persistent writes — queries fresh each run.
EMBY_URL="http://localhost:8096"
EMBY_API_KEY="0c27448d93a7431f9ac63569f7655829"
# Each server has its own Emby instance with its own API key.
# detect_hosts() selects the correct URL and key at runtime.
HOST1_EMBY_URL="http://localhost:8096"
HOST1_EMBY_API_KEY="0c27448d93a7431f9ac63569f7655829"
HOST2_EMBY_URL="http://localhost:8096" # same port — different server, different key
HOST2_EMBY_API_KEY="your-host2-emby-api-key"
EMBY_REPORT_DAYS=7 # number of days to include in the report period
EMBY_REPORT_TOP_N=10 # number of top content items to show in report
+17
View File
@@ -19,6 +19,8 @@
# not include these in its tracked file API response. Without protection these would
# be classified as orphans and deleted — breaking Lidarr and Emby metadata display.
#
# Lidarr runs on HOST1 only — music library is HOST1's source of truth.
# If run on HOST2 this script exits cleanly with no action.
# All configuration in Master.conf under Arr Cleanup section.
# Supports --dry-run to preview what would be deleted without making changes.
# -----------------------------------------------------------------------------------------------
@@ -54,6 +56,21 @@ if ! command -v jq >/dev/null 2>&1; then
exit 1
fi
# Lidarr runs on HOST1 only — exit cleanly if running on HOST2
detect_hosts
if [[ "$LOCAL_SERVER_NAME" != "$HOST1" ]]; then
info "Lidarr runs on $HOST1 only — skipping on $LOCAL_SERVER_NAME"
exit 0
fi
LIDARR_URL="$HOST1_LIDARR_URL"
LIDARR_API_KEY="$HOST1_LIDARR_API_KEY"
LIDARR_MUSIC_ROOT="$HOST1_LIDARR_MUSIC_ROOT"
info "Lidarr instance: $LOCAL_SERVER_NAME$LIDARR_URL"
info "Music root: $LIDARR_MUSIC_ROOT"
require_var LIDARR_URL
require_var LIDARR_API_KEY
require_var LIDARR_MUSIC_ROOT
+18
View File
@@ -19,6 +19,8 @@
# (*.srt, *.sub, *.ass) but does not include these in its tracked file API response.
# Without protection these would be classified as orphans and deleted.
#
# HOST1 Radarr manages Movies. HOST2 Radarr manages Anime_Movies.
# detect_hosts() selects the correct URL, API key, and root path at runtime.
# All configuration in Master.conf under Arr Cleanup section.
# Supports --dry-run to preview what would be deleted without making changes.
# -----------------------------------------------------------------------------------------------
@@ -54,6 +56,22 @@ if ! command -v jq >/dev/null 2>&1; then
exit 1
fi
# Select correct Radarr instance based on which server is running this script
detect_hosts
if [[ "$LOCAL_SERVER_NAME" == "$HOST1" ]]; then
RADARR_URL="$HOST1_RADARR_URL"
RADARR_API_KEY="$HOST1_RADARR_API_KEY"
RADARR_MOVIES_ROOT="$HOST1_RADARR_MOVIES_ROOT"
else
RADARR_URL="$HOST2_RADARR_URL"
RADARR_API_KEY="$HOST2_RADARR_API_KEY"
RADARR_MOVIES_ROOT="$HOST2_RADARR_MOVIES_ROOT"
fi
info "Radarr instance: $LOCAL_SERVER_NAME$RADARR_URL"
info "Movies root: $RADARR_MOVIES_ROOT"
require_var RADARR_URL
require_var RADARR_API_KEY
require_var RADARR_MOVIES_ROOT
+18
View File
@@ -19,6 +19,8 @@
# (*.srt, *.sub, *.ass) but does not include these in its tracked file API response.
# Without protection these would be classified as orphans and deleted.
#
# HOST1 Sonarr manages Tv_Shows. HOST2 Sonarr manages Anime_Shows.
# detect_hosts() selects the correct URL, API key, and root path at runtime.
# All configuration in Master.conf under Arr Cleanup section.
# Supports --dry-run to preview what would be deleted without making changes.
# -----------------------------------------------------------------------------------------------
@@ -54,6 +56,22 @@ if ! command -v jq >/dev/null 2>&1; then
exit 1
fi
# Select correct Sonarr instance based on which server is running this script
detect_hosts
if [[ "$LOCAL_SERVER_NAME" == "$HOST1" ]]; then
SONARR_URL="$HOST1_SONARR_URL"
SONARR_API_KEY="$HOST1_SONARR_API_KEY"
SONARR_TV_ROOT="$HOST1_SONARR_TV_ROOT"
else
SONARR_URL="$HOST2_SONARR_URL"
SONARR_API_KEY="$HOST2_SONARR_API_KEY"
SONARR_TV_ROOT="$HOST2_SONARR_TV_ROOT"
fi
info "Sonarr instance: $LOCAL_SERVER_NAME$SONARR_URL"
info "TV root: $SONARR_TV_ROOT"
require_var SONARR_URL
require_var SONARR_API_KEY
require_var SONARR_TV_ROOT
+27 -4
View File
@@ -159,6 +159,9 @@
#/mnt/user/appdata/unraid_scripts/Monitors/zfs_memory_snapshot.sh
#
# ━━━ Orchestrators ━━━
# Orchestrators run their child scripts in the correct order.
# Individual scripts below are still accessible for manual runs or testing.
#
#/mnt/user/appdata/unraid_scripts/Orchestrators/daily_sync.sh
#/mnt/user/appdata/unraid_scripts/Orchestrators/media_management.sh
#/mnt/user/appdata/unraid_scripts/Orchestrators/transcode_management.sh
@@ -173,6 +176,8 @@
# ━━━ Rsync — Individual Media Shares (ad hoc) ━━━
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Movies
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Tv_Shows
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Music
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Music_Videos
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Anime_Shows
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Anime_Shows-Old
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Anime_Movies
@@ -181,8 +186,8 @@
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Intros
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Kids_Movies
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Kids_Tv_Shows
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Music_Videos
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Nextcloud
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/Sports
#/mnt/user/appdata/unraid_scripts/Rsync/rsync.sh /mnt/user/stand-up_comedy
#
# ━━━ Docker Essentials ━━━
@@ -191,14 +196,32 @@
#/mnt/user/appdata/unraid_scripts/Docker_Essentials/docker_weekly_restart.sh
#/mnt/user/appdata/unraid_scripts/Docker_Essentials/docker_network_connect.sh
#
# ━━━ Media ━━━
# media_management.sh runs all of these in order — individual entries for manual use.
# Always --dry-run --log first on arr cleanup scripts before running live.
#
#/mnt/user/appdata/unraid_scripts/Media/media_shares_permissions.sh
#/mnt/user/appdata/unraid_scripts/Media/media_cleaner.sh anime --dry-run
#/mnt/user/appdata/unraid_scripts/Media/media_cleaner.sh anime
#/mnt/user/appdata/unraid_scripts/Media/media_cleaner.sh media --dry-run
#/mnt/user/appdata/unraid_scripts/Media/media_cleaner.sh media
#/mnt/user/appdata/unraid_scripts/Media/lidarr_cleanup.sh --dry-run --log
#/mnt/user/appdata/unraid_scripts/Media/lidarr_cleanup.sh
#/mnt/user/appdata/unraid_scripts/Media/sonarr_cleanup.sh --dry-run --log
#/mnt/user/appdata/unraid_scripts/Media/sonarr_cleanup.sh
#/mnt/user/appdata/unraid_scripts/Media/radarr_cleanup.sh --dry-run --log
#/mnt/user/appdata/unraid_scripts/Media/radarr_cleanup.sh
#
# ━━━ Transcodes ━━━
# transcode_management.sh runs cleanup then manager every 3min — schedule this.
# ramdisk_setup.sh runs once at array start — separate User Script entry.
# transcode_manager.sh and transcode_cleanup.sh can be run individually if needed.
# transcode_management.sh runs cleanup then manager — schedule that, not the individuals.
# ramdisk_setup.sh runs once at array start.
# transcode_manager.sh and transcode_cleanup.sh available for individual manual runs.
#
#/mnt/user/appdata/unraid_scripts/Transcodes/ramdisk_setup.sh
#/mnt/user/appdata/unraid_scripts/Orchestrators/transcode_management.sh
#/mnt/user/appdata/unraid_scripts/Transcodes/transcode_manager.sh --dry-run
#/mnt/user/appdata/unraid_scripts/Transcodes/transcode_manager.sh
#/mnt/user/appdata/unraid_scripts/Transcodes/transcode_cleanup.sh --dry-run
#/mnt/user/appdata/unraid_scripts/Transcodes/transcode_cleanup.sh
#
# ━━━ Tools ━━━