Commit Graph
293 Commits
Author SHA1 Message Date
Gmer4Lfe 588cde1cc4 Transcodes echo/log audit pass
ramdisk_setup.sh: path/size detail lines → log (already in log block above);
status done → echo. transcode_cleanup.sh: flip-back decision line and status
done → echo. transcode_manager.sh: clean-run single-line summary → echo.
Manual-Transcoding.md: added Output Tiers section.
2026-05-21 17:07:23 -04:00
Gmer4Lfe 5ccfb895c1 Tools echo/log audit pass — 9 scripts + Manual
No setup banners to remove (Tools folder was already clean). Fix log→echo
on summary status/conclusion lines across container_data_export, emby_database_repair,
recreate_shares, zfs_pool_scrub, and fallback_state_reset (safety check + two summary
detail lines). Fix log→echo on status display lines in watchdog_skip_list_manager
(skip list empty, restart history lines). Move per-item "to add" preview echoes to
log in emby_to_lidarr/radarr/sonarr_sync; fix nothing-to-do log→echo in all three.
Add output tiers section to Manual-Tools.md.
2026-05-21 16:58:32 -04:00
Gmer4Lfe 789d376eb3 Rsync echo/log audit pass — rsync.sh + Manual
Fix log→echo on success status line in summary block. Add output tiers
section to Manual-Rsync.md. No setup banner (script was already clean);
all section headers and transfer identity block correctly remain echo.
2026-05-21 16:51:09 -04:00
Gmer4Lfe a4edeab5eb Media echo/log audit pass — 11 scripts + Manual
Remove setup banners from all 8 scripts that had them (discovery scripts
use comment-only setup sections). Move per-item/detail echoes to log in
arr_sync, lidarr_missing_art, lidarr/radarr/sonarr_cleanup (scan progress,
API query status, root/orphan config lines), and per-title lines in
radarr_tmdb_removed / sonarr_tvdb_removed. Fix log→echo on clean-status
summary lines in arrs_failed_stalled_recovery, media_cleaner, and both
removed-title scripts. Add output tiers section to Manual-Media.md.
2026-05-21 16:48:08 -04:00
Gmer4Lfe c1c12cbe73 Fallback echo/log audit pass — fallback.sh, fallback_test.sh + Manual
Remove setup banners from fallback.sh and fallback_test.sh. Add Host Detection
to fallback.sh OPERATIONAL SAFEGUARDS; add Lock Acquisition + Host Detection to
fallback_test.sh. Add output tiers section to Manual-Fallback.md documenting
daemon vs one-shot output behaviour.
2026-05-21 16:33:36 -04:00
Gmer4Lfe 0b992a9054 Docker_Essentials echo/log audit pass — all 8 scripts + Manual
Consistent two-tier output model across the entire folder:
- Per-container banners, action lines, and list details → log (ENABLE_LOGGING=true only)
- Section headers, summaries, counts, and status conclusions → echo (always visible)
- Warnings and errors always visible regardless of log setting
- Blank echo lines inside loops removed

All scripts: added Lock Acquisition and Host Detection entries to OPERATIONAL SAFEGUARDS.

Setup banners removed from docker_watchdog.sh, docker_weekly_restart.sh,
downloaders_reset.sh (noise before any work happens).

docker_watchdog.sh: removed success "Running as root" / "Docker found" setup lines;
info() → log() for daemon-recovered and per-cycle header; removed per-cycle echo separator.

docker_update.sh + docker_update_remaining.sh: docker pull stdout suppressed when
ENABLE_LOGGING=false to prevent orphaned Status: lines appearing without container context;
restructured pull block to use PIPESTATUS for exit code capture.

downloaders_reset.sh: 11× info() → log() for all per-item API operation lines.

docker_weekly_restart.sh: removed duplicate restart-order echo (build_restart_order
already logs it internally).

Manual-Docker_Essentials.md: documented the two-tier output model and watchdog
silent-when-healthy exception in the flag reference section.
2026-05-21 16:22:30 -04:00
Gmer4Lfe e932936acc Add docker availability check to all scripts that use docker commands
22 scripts used docker without verifying it's present. Consistent with the
pattern already established in Docker_Essentials scripts. Added after acquire_lock
and before detect_hosts in each script's setup section.
2026-05-20 18:35:34 -04:00
Gmer4Lfe 740710e0d0 Add missing acquire_lock to 8 scripts across Docker_Essentials, Rsync, Partnership, Old_Arch
docker_container_stop, docker_update, docker_update_remaining — concurrent Docker
operations on the same containers would conflict; now locked.

rsync.sh — two rsync processes running against the same share simultaneously
would produce incomplete or corrupted mirrors; now locked.

partnership_onboard, ssh_setup — one-shot setup scripts that mutate SSH config and
deploy containers; concurrent runs would produce undefined state; now locked.

Old_Arch_Still_Works: arr_cleanup, continuous_scripts_status — legacy scripts still
sourcing load_config.sh; added lock for consistency even in old-arch context.

partnership_manager.sh intentionally left unchanged — it uses a conditional lock
that excludes read-only "check" mode and "offboard" mode (which delegates to
partnership_offboard.sh, which has its own lock).
2026-05-20 18:03:03 -04:00
Gmer4Lfe 5c13495a6c Add missing acquire_lock calls to arr_sync, bulk_permissions_repair, container_data_export
arr_sync.sh had acquire_lock documented in OPERATIONAL SAFEGUARDS header but the
call was never present in the code — two sync instances could run simultaneously.
bulk_permissions_repair.sh and container_data_export.sh had no lock at all.

All three are now consistent with every other script in Media/ and Tools/.
2026-05-20 17:55:18 -04:00
Gmer4Lfe 649a3b7b62 Docs pass: update headers and READMEs for all new scripts
Script headers (6 files):
- Add OPERATIONAL SAFEGUARDS section to all discovery + emby sync scripts
- Add STATE FILES section to all 3 discovery scripts
- Add CONFIGURATION section to emby_to_*_sync.sh
- Rename USAGE → RUNTIME MODES in emby_to_*_sync.sh (doc standard)
- Fix SONARR_DISCOVERY_MONITOR_MODE default doc: "future" → "all"

Media/README-Media.md:
- Remove "WIP prototype" label; describe all 3 discovery scripts
- Add discovery scripts to scripts table and HOW THE SCRIPTS RELATE diagram
- Add weekly discovery schedule block to EXECUTION ORDER section
- Update intro to mention behavior-driven discovery

Media/Manual-Media.md:
- Add configuration reference sections for all 3 discovery scripts
- Add flag reference sections for all 3 discovery scripts

Tools/README-Tools.md:
- Add "Library Sync Bootstrap" category and emby_to_*_sync.sh to scripts table
- Add emby sync scripts to HOW THE SCRIPTS RELATE diagram

Tools/Manual-Tools.md:
- Update emby sync notes: search commands now fire immediately after add

README.md:
- Update Media folder description to include discovery
- Update weekly schedule to show discovery scripts
- Update README table entry for Media
2026-05-20 17:48:30 -04:00
Gmer4Lfe 644225c4dc Fix Sonarr discovery monitor mode: future → all
future only monitors seasons not yet aired — shows with all existing
seasons would add as unmonitored with nothing to search. all monitors
everything so SeriesSearch actually finds episodes to grab.
2026-05-20 17:36:27 -04:00
Gmer4Lfe 6ffe5bea70 Add Sonarr discovery; wire search commands to all arr adds
- New: Media/playback_aware_sonarr_discovery.sh — two-stage TV show
  discovery using Emby episode play history → TMDB TV recommendations.
  Multi-user aware: diversity score (0-50) is primary seed driver so one
  user binge-watching alone cannot dominate. Per-user episode cap (default 8)
  limits single-user volume contribution. TMDB→TVDB via external_ids for
  reliable Sonarr lookup. monitor=future by default.

- Add to WEEKLY_MAINTENANCE_SCRIPTS; Sonarr discovery config block in
  master.conf (threshold=52, lookback=14d, max_adds=3, user_ep_cap=8).

- Fix: all arr add scripts were not triggering searches after adding.
  Added _radarr_command/_lidarr_command/_sonarr_command helpers and fire
  MoviesSearch/ArtistSearch/SeriesSearch immediately after each successful
  add. Affects: playback_aware_radarr_discovery.sh, emby_to_lidarr_sync.sh,
  emby_to_radarr_sync.sh, emby_to_sonarr_sync.sh.
2026-05-20 17:27:07 -04:00
Gmer4Lfe 9d371f6e27 Tune Radarr discovery threshold to 52 2026-05-20 17:07:26 -04:00
Gmer4Lfe 548c662709 Fix Radarr discovery: activity log seeding + calibrate threshold
- Stage 1 rewritten to use Emby activity log (playback.stop events)
  with ItemId batch-fetching instead of per-library UserData sort;
  SortBy=DatePlayed requires UserId context and errored server-wide

- Scoring simplified: recency (0-50) + play frequency across all
  users (0-50); CommunityRating is not exposed by Emby Items API
  so TMDB rating scoring moved entirely to Stage 2

- Batch IDs in groups of 100 — 1500+ unique item IDs in a 30-day
  window exceeded GET URL limits on a single request

- Threshold lowered to 50 (from 60); with diverse-genre seeds,
  recommendations rarely appear across multiple seeds so breadth
  score stays at 10/40 — threshold 50 yields ~5 adds per run at
  good quality (rating 7.0+, 1k+ votes)

- HOST1_TMDB_API_KEY moved to sit under Radarr section in
  master_host1.conf where it logically belongs
2026-05-20 17:05:35 -04:00
Gmer4Lfe 4ab3fa26d1 Add Radarr discovery + tighten arr sync filters
- playback_aware_radarr_discovery.sh: new two-stage movie discovery
  using recently watched Emby movies as seeds and TMDB recommendations
  as the similarity engine; scores on recency + rating + vote count;
  adds HOST*_TMDB_API_KEY alias to detect_hosts() in common.sh

- emby_to_sonarr_sync.sh: restrict to SONARR_EMBY_LIBRARIES allowlist
  (Anime, Kids Shows, Stand-Up Comedy, TV shows) — excludes Youtube
  and Recorded Sports libraries; add garbage title filter for multi-
  season folder names (S01-S03) and bare bracket tags ([Prof])

- emby_to_radarr_sync.sh: add _is_episode_title filter to block anime
  episode files stored in Movies library (underscore/dot patterns,
  fansub bracket format, episode markers, codec metadata strings)

- emby_to_lidarr_sync.sh: add U+FFFD Unicode replacement character
  filter alongside the existing ASCII ? filter for encoding corruption

- master.conf: RADARR_DISCOVERY_* settings, SONARR/RADARR_EMBY_LIBRARIES
  allowlists, Radarr discovery added to WEEKLY_MAINTENANCE_SCRIPTS
2026-05-20 16:51:49 -04:00
Gmer4Lfe 7ccb7e0e67 feat: two-stage Lidarr discovery + Emby→arr sync tools
Lidarr Discovery (playback_aware_lidarr_discovery.sh):
- Complete rewrite to two-stage pipeline: Stage 1 scores weekly Emby
  plays → top seeds; Stage 2 runs Last.fm getSimilar on seeds → scores
  candidates → adds top 0-5 to Lidarr
- Per-user influence cap (35%) prevents single listener dominating discovery
- Requires 2+ seeds to accept a candidate (single-seed skipped)
- Last.fm similarity limit 10 for tighter, higher-quality candidates
- 30-day reject cooldown history; MAX_ADDS=5 cap enforced
- Root folder fetched from Lidarr API at runtime (no config path)
- Added to WEEKLY_MAINTENANCE_SCRIPTS (uncommented)

Emby→arr sync tools (Tools/):
- emby_to_lidarr_sync.sh: finds Emby music artists not in Lidarr, adds them
  - Dirty tag filter: comma-list, feat./ft., &, vs, " - " patterns skipped
  - Root folder fetched from Lidarr API at runtime
- emby_to_sonarr_sync.sh: finds Emby series not in Sonarr, adds them
  - TVDB ID matching with title fallback
- emby_to_radarr_sync.sh: finds Emby movies not in Radarr, adds them
  - TMDB ID matching with title fallback
- All three: searchForMissing*: false (monitoring only, no searches triggered)
- All three documented in Tools/Manual-Tools.md
2026-05-19 23:34:32 -04:00
Gmer4Lfe b4d2a90568 feat: orchestrator housekeeping — watchdog array, script mapping, orch reorder
- master.conf: add WATCHDOG_ORCHESTRATOR_SCRIPTS array; watchdog config moved
  from standalone section into orch block alongside all other tiers
- watchdog_orchestrator.sh: iterate WATCHDOG_ORCHESTRATOR_SCRIPTS instead of
  hardcoded paths; display name derived from filename; status block updated
- master.conf orch section reordered: Array Stop → Array Start → Watchdog (1min)
  → Critical (15min) → Intermediate (4hr) → Daily (1am) → Weekly (Sunday)
- arrs_failed_stalled_recovery.sh added to INTERMEDIATE_MAINTENANCE_SCRIPTS
- lidarr_missing_art.sh moved from intermediate to daily
- clear_logs.sh added to WEEKLY_MAINTENANCE_SCRIPTS (was documented but orphaned)
- playback_aware_lidarr_discovery.sh placed in weekly (commented out, WIP)
- master_host1.conf: Slskd added to DAILY_RESTART_CONTAINERS
2026-05-19 21:01:35 -04:00
Gmer4Lfe e13f2fa14f feat: slskd reconnect guard in downloaders_reset, mass v2 sync
- downloaders_reset: connection check block before slskd API sections;
  triggers PUT /api/v0/server reconnect if disconnected, polls 60s,
  gates Stuck Searches and Dead Transfer Records on SLSKD_CONNECTED
- Sync all modified/new/deleted files from v2 refactor across Docker_Essentials,
  Media, Monitors, Partnership, Rsync, Tools, Transcodes, unRAID_Essentials,
  common.sh, master confs, and new Manual/README docs
2026-05-19 20:00:10 -04:00
Gmer4Lfe 5cb16d4b18 fix: repair slskd search and transfer cleanup in downloaders_reset
Searches: grep was potentially matching nested IDs from search result
objects. Switch to splitting JSON at { boundaries and requiring
"searchText" presence — only top-level search objects have that field.

Transfers: DELETE /api/v0/transfers/downloads/{username} returns 405
(endpoint does not exist). Replace with per-user GET then per-file
DELETE /api/v0/transfers/downloads/{username}/{id}, using the same
{-split + state grep approach to extract terminal-state file IDs.
2026-05-19 15:48:47 -04:00
Gmer4Lfe aa6d165725 feat: add fallback.sh --stop for clean array shutdown
Fallback runs as a bare subprocess (cmdline: bash .../Fallback/fallback.sh),
not via /tmp/user.scripts, so user_scripts_stop.sh cannot find it.
Adding --stop mode closes that gap in the array shutdown sequence.

fallback.sh --stop: reads lock file (/tmp/unraid_locks/fallback.lock) to
get the running PID, sends SIGTERM (hits the existing trap that sets
FALLBACK_RUNNING=false), waits up to 10s, SIGKILLs if still alive.

master.conf: insert Fallback/fallback.sh --stop as step 2 in
ARRAY_STOP_SCRIPTS (after user_scripts_stop, before rsync_stop).

user_script_plug-in.sh: update ARRAY STOPPING block to show 5-step order
and add v2.5 changelog entry.
2026-05-18 22:04:07 -04:00
Gmer4LfeandClaude Sonnet 4.6 75510cfd54 docs: remove arrs_failed_stalled_recovery from orchestrators header list
It's a Media/ individual script, not an orchestrator — belongs in the
individual scripts section only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:44:47 -04:00
Gmer4LfeandClaude Sonnet 4.6 6fdc27b00b docs: update user_script_plug-in.sh to v2.4
Add array_stopping.sh (At Stopping of Array) and watchdog_orchestrator.sh
(every minute) as new scheduled orchestrators. Add docker_container_stop.sh
and resource_watchdog.sh individual script entries. Update system_watchdog
and docker_watchdog descriptions to reflect single-pass architecture. Fix
paths: git_pull_execute.sh (root-level), continuous_scripts_status.sh (Tools/).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:41:59 -04:00
Gmer4Lfe 32a0d47155 refactor: archive Python arr_cleanup and retire continuous_scripts_status
Add Old_Arch_Still_Works/ folder as staging area for scripts awaiting
native platform support or retirement. Python arr_cleanup.sh/.py parked
here until Unraid ships Python natively — fully built and config-driven,
ready to activate. continuous_scripts_status.sh retired from Tools.
2026-05-17 00:58:27 -04:00
Gmer4LfeandClaude Sonnet 4.6 9a5f6f88f2 refactor: rename resource_manager → resource_watchdog, RM_ → RW_
Consistent naming with the watchdog family (system_watchdog, docker_watchdog).
File renamed, all RM_ config variables and internal references updated to RW_
across master.conf, master_host1.conf, common.sh, docker_watchdog.sh,
system_watchdog.sh, watchdog_orchestrator.sh, and sunday_morning_coffee_report.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 18:31:09 -04:00
Gmer4LfeandClaude Sonnet 4.6 309546e615 feat: watchdog architecture v2 — resource manager + single-pass orchestrator
Introduce a four-layer self-healing stack replacing the continuous-loop watchdogs:

- resource_manager.sh (new): single-pass pressure reduction layer; throttles
  SABnzbd/qBit at level 1, docker-pauses background containers at level 2,
  docker-stops optional containers and signals docker_watchdog to defer at
  level 3; graduated recovery with hysteresis

- watchdog_orchestrator.sh (new, Orchestrators/): runs resource_manager →
  docker_watchdog → system_watchdog in sequence; intended for per-minute cron
  via User Scripts; startup grace, acquire_lock to prevent pile-up, heartbeat

- docker_watchdog.sh: de-looped to single-pass; daemon strikes persisted to
  state file across runs; cross-script coordination reads RM_STATE_FILE instead
  of SYS_WATCHDOG_STATE_FILE

- system_watchdog.sh: de-looped to single-pass; stripped of all container
  management (shutdown_non_essential_containers removed); reboot-only last resort

- master.conf: removed system_watchdog and docker_watchdog from
  ARRAY_START_SCRIPTS; added WATCHDOG ORCHESTRATOR and RESOURCE MANAGER sections

- master_host1.conf: added RM_PAUSE_CONTAINERS and RM_STOP_CONTAINERS arrays

- common.sh: aliased RM_PAUSE_CONTAINERS and RM_STOP_CONTAINERS via detect_hosts()

- continuous_scripts_status.sh: moved to Tools/ (preserved for future use)

- sunday_morning_coffee_report.sh: watchdog section updated to use state file
  mtime checks instead of is_running; added Resource Manager subsection;
  fixed mem_shutdown grep filter pointing to wrong state file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 17:41:59 -04:00
Gmer4LfeandClaude Sonnet 4.6 f16c962ac0 feat: rename array orchestrators, add docker_update remainder mode
- Rename array_start.sh → array_started.sh, array_stop.sh → array_stopping.sh
  to clarify these are event-driven (array has started/is stopping), not imperative
- Update all references across 9 files (master.conf, user_script_plug-in.sh,
  watchdogs, continuous_scripts_status.sh, claude_startup.sh)
- Add --remainder mode to docker_update.sh: updates all running containers
  excluding daily containers, weekly sync-window containers (emby + critical-data),
  and fallback coverage containers (FALLBACK_${MY_ID}_COVERS_${REMOTE_ID}_TIER*)
  Fallback containers excluded because the remote server owns their version —
  independent updates risk writeback incompatibility on handback
- weekly_sync_maintenance.sh calls docker_update.sh --remainder as final step
- git_pull_execute.sh: add safe.directory config to fix dubious ownership error
  when running as root on a directory owned by uid 1000

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 22:12:08 -04:00
FailedProxy eaade9a9d4 moved kernel folder 2026-05-10 20:12:36 -04:00
Gmer4LfeandClaude Sonnet 4.6 0ae31b5fa6 feat: Tailscale resolution hardening, partnership offboard completion, Emby provisioning
common.sh:
- Add resolve_tailscale_ip() helper — tries `tailscale ip -4` first, falls back to
  parsing `tailscale status` output; handles hosts where MagicDNS short-name resolution
  is not active
- Add PARTNERSHIP_OWN_CONTAINERS alias in detect_hosts()
- Add aliasing for 4 Emby provisioning vars (PARTNERSHIP_PROVISION_EMBY_ADMIN,
  PARTNERSHIP_EMBY_ADMIN_USER, PARTNERSHIP_EMBY_ADMIN_PASS, PARTNERSHIP_EMBY_PORT)

Partnership/partnership_manager.sh:
- Replace 9 bare `tailscale ip -4` calls with resolve_tailscale_ip()
- Add read_remote_conf_var() and read_remote_conf_array() — SSH to mirror, source its
  own load_config.sh + detect_hosts(), return aliased variable; solves sparse-checkout
  problem where HOST1 cannot read master_host2.conf directly
- Add derive_short_name() — strips unraid- prefix, capitalises first char
- Add cleanup_partner_containers() — removes partner containers via FolderView3 folder
  if enabled, else falls back to FALLBACK_*_COVERS_*_TIER* arrays
- Add cleanup_owner_containers_on_mirror() — SSH to mirror, stops and removes containers
  matching *-${OWNER_SHORT} naming convention
- Add start_own_stack() and start_mirror_own_stack() — restart own containers locally
  or on mirror via SSH using PARTNERSHIP_OWN_CONTAINERS
- Add provision_emby_admin() — reads mirror credentials via read_remote_conf_var, checks
  for username collision, creates user + sets password + grants admin policy via Emby API
- Add revoke_emby_admin() — looks up mirror username on local Emby, deletes via REST API
- Wire offboard paths (both mirror-initiated and owner-initiated) to call container
  cleanup and stack restart; update --check finalisation paths accordingly
- Fix write_state_file in --onboard not gated on DRY_RUN (was writing ACTIVE state on
  dry runs)

master_host1.conf:
- Add HOST1_PARTNERSHIP_OWN_CONTAINERS array
- Add partnership Emby provisioning config (toggle + port + per-host credentials)

master_host2.conf:
- Add HOST2_PARTNERSHIP_OWN_CONTAINERS array
- Add HOST2_PARTNERSHIP_EMBY_ADMIN_USER and HOST2_PARTNERSHIP_EMBY_ADMIN_PASS

Tailscale fix applied to:
- Initial_run/ssh_setup.sh (2 callsites)
- unRAID_Essentials/rsync_stop.sh (1 callsite)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 20:09:13 -04:00
FailedProxy 6948755c86 added decision engine 2026-05-10 20:07:19 -04:00
FailedProxy 62cbea7141 updated to do 2026-05-10 19:39:10 -04:00
FailedProxy 8ec97162e7 updated playback aware 2026-05-10 18:04:05 -04:00
FailedProxy dd55ec0761 added. playback aware lidarr discovery tool. still stand alone 2026-05-10 15:26:01 -04:00
Gmer4LfeandClaude Sonnet 4.6 a03280d6d3 docs(user_script_plug-in): v2.3 — document all new scripts and fix moved paths
New orchestrator: intermediate_sync_maintenance.sh (0 */4 * * *)
New scripts: docker_update, docker_update_remaining, downloaders_reset,
arr_sync, lidarr_missing_art, radarr_tmdb_removed, sonarr_tvdb_removed
New section: Initial_run/ with ssh_setup.sh and partnership_onboard.sh
Moved: arrs_failed_stalled_recovery → Media/, fallback_state_reset +
watchdog_skip_list_manager → Tools/
Renamed: partnership_manage.sh → partnership_manager.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 21:36:37 -04:00
Gmer4LfeandClaude Sonnet 4.6 f277ce92d5 feat: intermediate orchestrator + arr_sync blocklist end-to-end + mesh sync
Add intermediate_sync_maintenance.sh (0 */4 * * *) — arr library sync as
fixed first step, optional mid-day rsync (INTERMEDIATE_SYNC_SHARES, empty
by default), then INTERMEDIATE_MAINTENANCE_SCRIPTS. Wired with full rsync
infrastructure (temperature abort, check_rsync_enabled, INTERMEDIATE_RSYNC_ENABLED
toggle) matching daily/weekly pattern. lidarr_missing_art.sh scheduled here.

arr_sync.sh: blocklist --add now end-to-end — looks up real display name
from local arr API, writes TSV, deletes from local arr API (deleteFiles=false),
SSHes each remote node and deletes from their arr API. Files become orphans
for arr_cleanup safety pass.

master.conf: DEFAULT_RSYNC_OPTS updated (--partial, --timeout=60,
--numeric-ids; --no-whole-file removed). Media share comments updated to
mesh model.

master_host1.conf + master_host2.conf: both hosts now push all media shares
bidirectionally (true mesh — no ownership per share, arr_cleanup enforces truth).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 15:24:35 -04:00
Gmer4LfeandClaude Sonnet 4.6 6674dd4c17 Add SSH key revocation to offboard flow
On offboard, neither server should retain SSH access to the other.
Keys are now revoked as the final step before Tailscale removal — after
all state pushes and syncs are complete so no SSH operation is cut short.

Revocation runs in both owner-initiated offboard and when --check
finalises a mirror-requested offboard. Both directions are handled:
  - Our pubkey removed from remote's authorized_keys via SSH (identified
    by key comment keyname@hostname set by ssh_setup.sh at keygen time)
  - Remote's pubkey removed from local authorized_keys (matched by
    @REMOTE_SERVER_NAME suffix — unique across the authorized_keys file)

Non-fatal: SSH failure logs a manual revocation instruction; local
cleanup still runs. Summary shows per-direction revocation status.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 10:21:01 -04:00
Gmer4LfeandClaude Sonnet 4.6 4821dbdfb4 config: update HOST1 Sonarr API key
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 10:06:35 -04:00
Gmer4LfeandClaude Sonnet 4.6 b65f572367 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>
2026-05-09 09:53:40 -04:00
Gmer4LfeandClaude Sonnet 4.6 009820e981 refactor: rename failover/HA → fallback across entire codebase
Removes all references to "failover" and "HA" (high availability)
terminology from variable names, config keys, state values, rsync
profile names, directory paths, and user-visible strings.

Mapping:
  FAILOVER_*              → FALLBACK_*
  FAILOVER_HOST*_RUNS_FOR → FALLBACK_HOST*_COVERS
  critical-failover       → critical-fallback
  emby-failover           → emby-fallback
  appdata-Failover/       → appdata-Fallback/
  "FAILOVER" state value  → "FALLBACK"
  failover_start key      → fallback_start
  Failover/ directory     → Fallback/
  failover.sh             → fallback.sh
  failover_state.db       → fallback_state.db
  -Failover folder suffix → -Fallback

State machine: NORMAL | FALLBACK | DARK (unchanged)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 19:28:21 -04:00
Gmer4LfeandClaude Sonnet 4.6 4e22f5d1f7 feat(docker): add docker_update_remaining.sh for weekly catch-all image pulls
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>
2026-05-08 19:13:50 -04:00
Gmer4LfeandClaude Sonnet 4.6 0adfe04173 feat(docker): add docker_update.sh for daily container image pulls
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>
2026-05-08 19:12:00 -04:00
Gmer4LfeandClaude Sonnet 4.6 69464ba385 feat(partnership): add blocklist to block access after offboard
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>
2026-05-08 18:59:29 -04:00
Gmer4LfeandClaude Sonnet 4.6 09e9cec0c3 feat(rsync): print status message when transfer starts
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>
2026-05-08 18:53:41 -04:00
Gmer4LfeandClaude Sonnet 4.6 10da8108e5 fix: detect_hosts() aborts when REMOTE_ID is empty on single-server sparse checkout
${!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>
2026-05-08 18:41:48 -04:00
Gmer4LfeandClaude Sonnet 4.6 5526bc1eca v2 post-migration bug fixes, lidarr_missing_art port, and Partnership SSH/FolderView3 enhancements
Bug fixes across the ecosystem after v1→v2 architecture migration and Unraid 7.2.5 upgrade:

- common.sh: fix _alias_array() phantom empty element (removed [@]:-} pattern), fix
  resolve_remote_ip() with Tailscale FQDN lowercase + awk fallback, add FANART/LASTFM
  key aliases in detect_hosts(), global [@]:-} sweep across 10+ scripts
- webgui_restart.sh: fix emhttp detection (pgrep emhttpd) and restart command for 7.2.5
  (/usr/local/sbin/emhttp stop && start — rc.emhttp removed in 7.2.5)
- bandwidth_monitor.sh, continuous_scripts_status.sh: fix 'local' keyword outside function
- backup_verify.sh: fix resolve_remote_ip() called before detect_hosts()
- Orchestrators: fix script display duplication bug in status output (${entry##*/})
- rsync_stop.sh, git_pull_execute.sh, partnership_manager.sh, coffee_report: lowercase all
  tailscale ip -4 call sites to match Tailscale's lowercase device names
- master_host1.conf: fix SSH key path (gmer4lfe_rsync_automation), add FANART/LASTFM keys
- master_host2.conf: add FANART/LASTFM API keys

New: Media/lidarr_missing_art.sh
- Full ecosystem port of standalone Lidarr artwork fetcher
- Fetches missing album art via fanart.tv + Last.fm APIs
- @tsv batch extraction: 1 jq call per API response vs N*albums (8050 albums in 24s)
- HOST guard (HOST1 only), --status, --dry-run, acquire_lock

New: Initial_run/ssh_setup.sh
- Generates {hostname}_rsync_automation ed25519 keypair (skip if exists, --force to regen)
- ssh-copy-id to remote via Tailscale IP, auto-updates master_host*.conf
- --validate mode: strike tracking (SSH_MAX_STRIKES, SSH_STRIKE_RESET_HRS),
  notify at limit — Tailscale-unreachable remote does NOT count as SSH strike

New: Initial_run/partnership_onboard.sh
- Orchestrator: ssh_setup.sh then partnership_manager.sh --onboard in one command

Partnership/partnership_manager.sh: FolderView3 integration
- Derive partner folder name at runtime (strip unraid- prefix case-insensitively)
- --onboard: create {Mirror}-Failover folder with failover tier containers
- --offboard (both paths): stop + rm containers in folder, remove JSON entry
- --check: calls ssh_setup.sh --validate when IP resolves but SSH state empty
- --status: shows FolderView3 folder state and containers inline

master.conf: SSH_MAX_STRIKES, SSH_STRIKE_RESET_HRS, PARTNERSHIP_FOLDERVIEW3,
PARTNERSHIP_FOLDERVIEW3_URL added to Partnership section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 18:20:23 -04:00
FailedProxy 7cecda6b90 added lidar missing art checker 2026-05-08 16:26:22 -04:00
FailedProxy 35707a4191 common var fix 2026-05-04 18:03:51 -04:00
FailedProxy ec7de648dc massive update. Master conf split, now modular with a load sceriprt to drive all configs to scripts. with unraid scpecific safeguard tests , and improved standardized ux. including dynamic host detect, who am i who else it there. EVERY SINGLE SCRIPT UPDATED. DEBATING THAT THIS IS ACUALLY V2 2026-05-03 17:16:49 -04:00
FailedProxy 2691a35e80 same 2026-04-30 20:57:23 -04:00
FailedProxy 84b54ccb1d same 2026-04-30 20:54:42 -04:00
FailedProxy d520e94180 same 2026-04-30 20:51:34 -04:00