diff --git a/Media/Manual-Media.md b/Media/Manual-Media.md index 351fbb2..d2d2095 100644 --- a/Media/Manual-Media.md +++ b/Media/Manual-Media.md @@ -632,6 +632,27 @@ No recovery possible after deletion. --- +### play_state_sync.sh + +`play_state_sync.sh` +Sync played/unplayed state and resume positions from local Emby to the remote Emby. +Only items played within PLAY_SYNC_DAYS are synced. + +`play_state_sync.sh --full` +Ignore PLAY_SYNC_DAYS — sync all played items regardless of age. May be slow on large +libraries. Use after a new Emby install or database restore to rebuild full play history. + +`play_state_sync.sh --dry-run` +Show what would be synced without writing any state. + +`play_state_sync.sh --status` +Show configured servers, reachability, and user counts. + +`play_state_sync.sh --log` +Verbose output — show each item comparison. + +--- + ### arrs_failed_stalled_recovery.sh `arrs_failed_stalled_recovery.sh` diff --git a/Orchestrators/README-Orchestrators.md b/Orchestrators/README-Orchestrators.md index c2756a9..f3f6e37 100644 --- a/Orchestrators/README-Orchestrators.md +++ b/Orchestrators/README-Orchestrators.md @@ -71,7 +71,7 @@ until someone manually opens Lidarr, identifies the problem, blocklists the rele and triggers a new search. This takes minutes to do — but nobody does it at 3am when it usually happens. -The fix: `arrs_failed_stalled_recovery.sh` runs every 6 hours. It finds all +The fix: `arrs_failed_stalled_recovery.sh` runs every 4 hours (via `intermediate_sync_maintenance.sh`). It finds all `importFailed`, `importPending`, `error`, and `stalled` items, blocklists them, removes them from the queue, and triggers a new search — automatically. By morning the failed import has already been replaced by a working one. No manual intervention required. @@ -172,11 +172,10 @@ without `--log`. | `array_started.sh` | All array startup scripts in order | `array_start` event (Varaverk plugin hook) | | `watchdog_orchestrator.sh` | resource → docker → system → api_renew → stability watchdogs | Every 15 minutes | | `transcode_management.sh` | Cleanup then manager — order critical | Every 7 minutes | -| `arrs_failed_stalled_recovery.sh` | Failed import + stalled download recovery | Every 6 hours | | `daily_sync_maintenance.sh` | git pull → sync → media maintenance → restarts | 1am daily | | `weekly_sync_maintenance.sh` | Stop → update → clean sync → start → weekly restarts | 2:30am Sunday | | `monthly_maintenance.sh` | Uptime-triggered heavy tasks — ZFS scrub, SMART tests | Daily check, fires when uptime ≥ 30d | -| `intermediate_sync_maintenance.sh` | arr library sync, artwork, failed recovery | Every 4 hours | +| `intermediate_sync_maintenance.sh` | arr sync + arrs_failed_stalled_recovery + optional rsync | Every 4 hours | --- @@ -390,7 +389,7 @@ and Lidarr. Blocklists the bad release, removes it from the queue, and triggers new search — hands-free recovery while you sleep. ```bash -# Scheduled: 0 */6 * * * (every 6 hours) +# Called by: intermediate_sync_maintenance.sh (every 4 hours) ``` --- diff --git a/Partnership/Manual-Partnership.md b/Partnership/Manual-Partnership.md index e489c83..7a6aa51 100644 --- a/Partnership/Manual-Partnership.md +++ b/Partnership/Manual-Partnership.md @@ -430,6 +430,29 @@ Called automatically by `partnership_manager.sh --offboard`. Can also be run dir | `--status` | Show state files, blocklist, SSH key status | | `--unblock ` | Remove hostname from blocklist | +### partnership_transfer.sh + +Owner-only. Transfers ownership to the current mirror — swaps roles without moving +containers. Run via `partnership_manager.sh --transfer --confirm=`. + +| Flag | Effect | +|------|--------| +| `--confirm=` | Required confirmation string (from `PARTNERSHIP_TRANSFER_CONFIRM` in master.conf) | +| `--dry-run` | Preview all steps without executing | +| `--log` | Verbose per-step output | + +### onboard_cancel.sh + +Removes SSH keys between hosts in the specified direction. Safe to run at any onboard +phase — clears the corresponding setup.db flags. + +| Flag | Effect | +|------|--------| +| `--direction=h1` | Remove HOST1 → HOST2 key (default) | +| `--direction=h2` | Remove HOST2 → HOST1 key | +| `--direction=both` | Both directions | +| `--dry-run` | Preview without making changes | + ### ssh_setup.sh | Flag | Effect | diff --git a/Partnership/README-Partnership.md b/Partnership/README-Partnership.md index 3a5be3e..33d4b25 100644 --- a/Partnership/README-Partnership.md +++ b/Partnership/README-Partnership.md @@ -141,7 +141,9 @@ independently at 4-hour cadence. | `partnership_onboard.sh` | One-time setup — SSH keys, stack deploy, arr bootstrap | Manually, once per server per partnership | | `partnership_offboard.sh` | Clean separation — both paths, both roles | Via `partnership_manager.sh --offboard`; or directly | | `partnership_manager.sh` | Dispatcher + monitor — onboard WebUIs, health check, transfer, status | `--check` every 30min; all other modes manually | +| `partnership_transfer.sh` | Transfer ownership from current owner to current mirror | Via `partnership_manager.sh --transfer`; owner only | | `ssh_setup.sh` | SSH key generation, remote install, auth validation | Called by onboard; manually for re-keying or validation | +| `onboard_cancel.sh` | Remove SSH keys in one or both directions, clear setup flags | During cancelled or failed onboard; manual cleanup | --- diff --git a/Plugin/README-Plugin.md b/Plugin/README-Plugin.md index d23ce68..0e6c522 100644 --- a/Plugin/README-Plugin.md +++ b/Plugin/README-Plugin.md @@ -76,6 +76,7 @@ so behaviour stays consistent without a shell dependency. | Script | Role | When It Runs | |--------|------|--------------| | `dev_install.sh` | Symlinks `Plugin/unraid/` into Unraid's web server | Once, manually, after cloning or moving the repo | +| `build.sh` | Packages the plugin as a `.txz` for release | Before publishing a new plugin version | --- diff --git a/Tools/Manual-Tools.md b/Tools/Manual-Tools.md index 8e825e6..48b64fb 100644 --- a/Tools/Manual-Tools.md +++ b/Tools/Manual-Tools.md @@ -11,7 +11,8 @@ making any changes. - [emby_to_lidarr_sync.sh](#emby_to_lidarr_syncsh) - [emby_to_sonarr_sync.sh](#emby_to_sonarr_syncsh) - [emby_to_radarr_sync.sh](#emby_to_radarr_syncsh) -- [fallback_state_reset.sh](#fallback_state_resetsh) *(not yet built — manual workaround)* +- [fallback_state_reset.sh](#fallback_state_resetsh) +- [docker_prune_images.sh](#docker_prune_imagessh) - [watchdog_skip_list_manager.sh](#watchdog_skip_list_managersh) - [bulk_permissions_repair.sh](#bulk_permissions_repairsh) - [container_data_export.sh](#container_data_exportsh) @@ -143,10 +144,13 @@ bash Tools/emby_to_radarr_sync.sh ## fallback_state_reset.sh -> **Not yet built.** Use the manual workaround below. +Resets the fallback state file to NORMAL and clears all tier flags. State file only — +does NOT start or stop any containers. After reset, fallback.sh resumes from NORMAL on +its next cycle. -Planned: reset the fallback state file to NORMAL and clear all tier flags. State file -only — does NOT start or stop any containers. +**Only run after verifying the stack is actually in a normal state** — right containers +on the right server, DDNS correct, no active fallback in progress. Resetting state during +a real fallback causes fallback.sh to stop covering the remote until the next detection cycle. ### When to Use @@ -164,11 +168,18 @@ After a dev/debug session → state left in a non-NORMAL state from testing ``` -### Manual Workaround +### Usage ```bash -# Verify before resetting: +fallback_state_reset.sh # show current state, prompt for YES before resetting +fallback_state_reset.sh --status # show current state file contents only +fallback_state_reset.sh --dry-run # show what the new state file would contain, no write +fallback_state_reset.sh --force # reset without confirmation prompt (for scripted use) +``` +### Verify Before Resetting + +```bash # Right containers on right server? continuous_scripts_status.sh # shows fallback current state @@ -180,17 +191,8 @@ pgrep -f "fallback.sh" # empty output = not running # Both servers Tailscale connected? tailscale status # both hosts should show active - -# Check current state file: -cat /boot/config/fallback_state.db - -# Reset to NORMAL (only after confirming containers and DDNS are correct): -echo "state=NORMAL" > /boot/config/fallback_state.db ``` -Resetting during an actual fallback causes fallback.sh to think everything is normal -and stop covering the remote — services go offline until the next detection cycle. - ### What the State File Contains ```bash @@ -614,18 +616,14 @@ Subsequent runs skip the migration and only create the symlinks. ### Calling from array_started.sh -To auto-restore Claude data on every boot without launching an interactive session: - -```bash -# In /boot/config/go or array_started.sh: -/path/to/Tools/claude_startup.sh --setup -``` +`array_started.sh` calls `claude_startup.sh` directly (no flags). This sets up the +symlinks only — no interactive session is launched. That is the default behavior. ### Usage ```bash -claude_startup.sh # set up persistent symlinks and launch Claude -claude_startup.sh --setup # set up symlinks only — no launch (for array_started.sh) +claude_startup.sh # set up persistent symlinks only (default — used by array_started.sh) +claude_startup.sh --launch # set up symlinks and launch Claude interactively ``` --- @@ -697,6 +695,28 @@ ramdisk_stop.sh --log # verbose — show each step --- +## docker_prune_images.sh + +Removes orphaned Docker images that accumulate after container updates. Two modes: + +**Default (dangling only)** — removes untagged images (no name, no container reference). +Safe — running containers are never affected. Use routinely after update cycles. + +**`--all` (full orphan cleanup)** — first removes stopped/exited containers, then removes +all images not used by any running container. Use when you've removed apps and want to +recover the disk space. CAUTION: also removes intentionally stopped containers. + +### Usage + +```bash +docker_prune_images.sh # remove dangling (untagged) images only +docker_prune_images.sh --all # remove stopped containers, then all unused images +docker_prune_images.sh --dry-run # show what would be removed without making changes +docker_prune_images.sh --status # show dangling images and stopped containers +``` + +--- + ## Adding a New Tool Write the tool when you solve a problem manually with bash commands. You'll face it again. diff --git a/Tools/README-Tools.md b/Tools/README-Tools.md index 144f979..d68df3e 100644 --- a/Tools/README-Tools.md +++ b/Tools/README-Tools.md @@ -125,6 +125,7 @@ The relationship is one-way: Tools act on state that other scripts have written. | `recreate_shares.sh` | Share directories missing after fresh install or disk rebuild | After fresh unRAID install or disk replacement on HOST2 | | `continuous_scripts_status.sh` | Need a live view of watchdog and fallback state | Any time — manual dashboard, no schedule | | `claude_startup.sh` | Claude Code session setup after reboot — symlinks persistent storage | After each unRAID reboot, or called by array_started.sh | +| `docker_prune_images.sh` | Remove dangling or unused Docker images accumulated after updates | After update cycles, or when disk space is low | | `ramdisk_stop.sh` | Safely stop the transcode ramdisk — redirect symlink to SSD, unmount, update state | Before re-running ramdisk_setup.sh with new size or thresholds | | `emby_to_lidarr_sync.sh` | Add all Emby album artists not yet tracked in Lidarr | After Lidarr setup, database wipe, or when you suspect gaps | | `emby_to_sonarr_sync.sh` | Add all Emby TV series not yet tracked in Sonarr | After Sonarr setup, database wipe, or when you suspect gaps | diff --git a/Transcodes/README-Transcoding.md b/Transcodes/README-Transcoding.md index 6c0663a..4d9cb96 100644 --- a/Transcodes/README-Transcoding.md +++ b/Transcodes/README-Transcoding.md @@ -132,8 +132,8 @@ Both are called by `transcode_management.sh` in the correct order. | Script | Role | When It Runs | |--------|------|-------------| | `ramdisk_setup.sh` | Create tmpfs, SSD fallback dir, symlink, transcoding-temp | At array start (via array_started.sh) | -| `transcode_cleanup.sh` | Remove stale files, check for flip-back opportunity | Every 3 min via transcode_management.sh — runs first | -| `transcode_manager.sh` | Check usage, flip symlink, safety checks, session display, daily log | Every 3 min via transcode_management.sh — runs second | +| `transcode_cleanup.sh` | Remove stale files, check for flip-back opportunity | Every 7 minutes via transcode_management.sh — runs first | +| `transcode_manager.sh` | Check usage, flip symlink, safety checks, session display, daily log | Every 7 minutes via transcode_management.sh — runs second | --- diff --git a/Watchdogs/Manual-Watchdogs.md b/Watchdogs/Manual-Watchdogs.md index a8d2ced..8cc0f20 100644 --- a/Watchdogs/Manual-Watchdogs.md +++ b/Watchdogs/Manual-Watchdogs.md @@ -572,7 +572,7 @@ safety concerns. ### Reboot Rate Limit ```bash -SYS_WATCHDOG_REBOOT_WINDOW_HRS=2 # window in hours +SYS_WATCHDOG_REBOOT_WINDOW_HRS=12 # window in hours SYS_WATCHDOG_REBOOT_LIMIT=3 # max reboots within the window ``` diff --git a/Watchdogs/stability_watchdog.sh b/Watchdogs/stability_watchdog.sh index 0c14a44..414509c 100755 --- a/Watchdogs/stability_watchdog.sh +++ b/Watchdogs/stability_watchdog.sh @@ -73,9 +73,9 @@ # master.conf — System Watchdog section # Full variable listing in master.conf. Key variables: # -# SYS_WATCHDOG_REBOOT_WINDOW_HRS — reboot rate limit window (default: 2) +# SYS_WATCHDOG_REBOOT_WINDOW_HRS — reboot rate limit window (default: 12) # SYS_WATCHDOG_MAX_REBOOTS — max reboots in window before giving up (default: 3) -# SYS_WATCHDOG_STRIKES — consecutive failures before reboot (default: 3) +# SYS_WATCHDOG_STRIKE_LIMIT — consecutive failures before reboot (default: 2) # SYS_WATCHDOG_OOM_LIMIT — OOM kills/cycle to trigger URGENT bypass (default: 3) # SYS_WATCHDOG_MEM_SHUTDOWN_EXCLUDED — containers exempt from memory shutdown #