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>
Pulls the latest image for every running container not already covered
by the daily update (DAILY_RESTART_CONTAINERS) or weekly restart
(WEEKLY_RESTART_CONTAINERS) lists. Runs at the end of WEEKLY_MAINTENANCE_SCRIPTS.
Exclusion set is derived automatically — no list to maintain.
Together with docker_update.sh, every deployed container gets at least
one image pull per week without relying on the CA Update Applications plugin.
Toggle: WEEKLY_REMAINING_UPDATES=true/false in master.conf.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pulls the latest image for each container in DAILY_RESTART_CONTAINERS
before docker_daily_restart.sh runs. Containers stay running during the
pull — no extra downtime. Mirrors the weekly update pattern exactly.
Toggle: DAILY_CONTAINER_UPDATES=true/false in master.conf.
Pull failures are non-fatal — the daily restart proceeds regardless.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After offboard, the former partner's hostname is written to
/boot/config/partnership_blocklist.db. This blocks passive reconnection:
- --check skips the remote entirely (no auto-reconnect noise)
- rsync.sh refuses to sync with a blocklisted host
- --onboard warns about the previous offboard but proceeds,
and clears the block on success (onboard = deliberate intent)
New --unblock <hostname> mode removes an entry to permit re-onboarding
without running a full --onboard first. --status shows the full blocklist.
Blocklist file survives reboots (/boot/config) and Tailscale reconnections —
application-layer guard that complements Tailscale device removal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rsync output is fully captured — nothing visible while it runs.
Adds a "Rsync running — this may take a while..." line before each
attempt so the Unraid log viewer shows transfer progress clearly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
${!REMOTE_ID:-unknown} with REMOTE_ID="" is a fatal bash error that terminates
the entire function — not just the line. All subsequent aliases (EMBY_CONTAINER,
TRANSCODE_SSD, RAMDISK_LOW_GB, SSH_KEY) were never set, causing awk syntax errors
and "SSD fallback path missing" warnings in every transcode script invocation.
Guard with an explicit empty check instead of relying on the :- fallback,
which bash does not apply when the indirect expansion itself is invalid.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>