diff --git a/Configurations/master.conf b/Configurations/master.conf index 20f15b9..0aba428 100644 --- a/Configurations/master.conf +++ b/Configurations/master.conf @@ -401,6 +401,7 @@ # syncs WEEKLY_SYNC_SHARES → restarts → then iterates WEEKLY_MAINTENANCE_SCRIPTS. # Schedule: 30 2 * * 0 (Sunday 2:30am) WEEKLY_MAINTENANCE_SCRIPTS=( + "Docker_Essentials/docker_update.sh --weekly" # pull latest images for WEEKLY_RESTART_CONTAINERS before restart "Docker_Essentials/docker_weekly_restart.sh" # weekly container restarts after sync "System_Essentials/clear_logs.sh" # purge aged logs — Sunday only, low priority "Media/playback_aware_lidarr_discovery.sh" # behavior-driven music discovery using weekly Emby playback history @@ -408,6 +409,10 @@ "Media/playback_aware_sonarr_discovery.sh" # behavior-driven TV discovery using TMDB recommendations ) +# Pull updates for WEEKLY_RESTART_CONTAINERS before docker_weekly_restart.sh runs. +# Set false to skip — docker_weekly_restart.sh still runs regardless. + WEEKLY_CONTAINER_UPDATES=true + # Pull updates for all running containers NOT in daily/weekly managed lists. # Ensures every deployed container receives at least one image pull per month. # Set false to skip. diff --git a/Docker_Essentials/docker_update.sh b/Docker_Essentials/docker_update.sh index 8911ead..742459f 100755 --- a/Docker_Essentials/docker_update.sh +++ b/Docker_Essentials/docker_update.sh @@ -5,16 +5,18 @@ # # PURPOSE # ───────────────────────────────────────────────────────────────────────────── -# Pulls the latest images for configured containers. Two modes: normal (daily) -# and remainder (weekly). +# Pulls the latest images for configured containers. Three modes: # -# Normal mode is called by daily_sync_maintenance.sh before docker_daily_restart.sh. +# Normal mode — called by daily_sync_maintenance.sh before docker_daily_restart.sh. # Containers stay running during the pull — no extra downtime beyond what the # nightly restart already causes. # -# Remainder mode is called by weekly_sync_maintenance.sh as the final update step. -# It catches everything that normal mode and the weekly sync window did not already -# update — derived automatically from docker ps, nothing to configure. +# Weekly mode — called by weekly_sync_maintenance.sh via WEEKLY_MAINTENANCE_SCRIPTS +# before docker_weekly_restart.sh. Pulls WEEKLY_RESTART_CONTAINERS so the +# subsequent restart lands on the fresh image. +# +# Remainder mode — called by monthly_maintenance.sh. Catches everything not +# already owned by daily or weekly — derived from docker ps, nothing to configure. # # ============================================================================================== # OPERATIONAL MODEL @@ -25,13 +27,17 @@ # Pull → compare old vs new image ID → mark updated or already current. # docker_daily_restart.sh runs after — containers restart onto the fresh image. # -# Remainder mode (weekly): +# Weekly mode: +# Targets WEEKLY_RESTART_CONTAINERS — same list used by docker_weekly_restart.sh. +# Pull → compare → rebuild if changed. +# docker_weekly_restart.sh runs after — containers restart onto the fresh image. +# +# Remainder mode (monthly): # Targets all currently running containers NOT in: # DAILY_RESTART_CONTAINERS — already updated daily +# WEEKLY_RESTART_CONTAINERS — already updated weekly # emby + critical-data profiles — updated inline by the weekly sync window # FALLBACK_*_TIER* — owned by the remote server's update cycle -# WEEKLY_RESTART_CONTAINERS are included — docker_weekly_restart.sh restarts -# them but doesn't pull images; remainder is the only place they get updated. # Pull → compare → prune dangling images. # # ============================================================================================== @@ -68,9 +74,9 @@ # Root Enforcement # Docker operations require root privileges. # -# DAILY_CONTAINER_UPDATES Toggle -# Normal mode exits cleanly when disabled. docker_daily_restart.sh still runs -# regardless — update and restart are independent operations. +# DAILY_CONTAINER_UPDATES / WEEKLY_CONTAINER_UPDATES Toggles +# Each mode exits cleanly when disabled. Restart scripts run regardless — +# update and restart are independent operations. # # Fallback Exclusion # Remainder mode excludes containers owned by the remote server's update cycle @@ -93,6 +99,10 @@ # Enable or disable normal mode. docker_daily_restart.sh runs regardless. # (default: true) # +# WEEKLY_CONTAINER_UPDATES +# Enable or disable weekly mode. docker_weekly_restart.sh runs regardless. +# (default: true) +# # MONTHLY_REMAINING_UPDATES # Enable or disable remainder mode. (default: true) # @@ -106,6 +116,10 @@ # Containers updated in normal mode. Aliased by detect_hosts() → # DAILY_RESTART_CONTAINERS # +# HOST*_WEEKLY_RESTART_CONTAINERS +# Containers updated in weekly mode. Aliased by detect_hosts() → +# WEEKLY_RESTART_CONTAINERS +# # ============================================================================================== # RUNTIME MODES # ============================================================================================== @@ -114,6 +128,10 @@ # Normal mode — pull latest images for DAILY_RESTART_CONTAINERS # Called by daily_sync_maintenance.sh before docker_daily_restart.sh # +# docker_update.sh --weekly +# Weekly mode — pull latest images for WEEKLY_RESTART_CONTAINERS +# Called by weekly_sync_maintenance.sh (WEEKLY_MAINTENANCE_SCRIPTS) before docker_weekly_restart.sh +# # docker_update.sh --remainder # Remainder mode — pull all running containers not in managed lists, # restart those that received updates, prune dangling images @@ -134,15 +152,16 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../load_config.sh" -# Pre-parse --remainder before parse_args (unknown args pass through to PARSED_ARGS) +# Pre-parse mode flags before parse_args (unknown args pass through to PARSED_ARGS) REMAINDER_MODE=false +WEEKLY_MODE=false _filtered_args=() for _arg in "$@"; do - if [[ "$_arg" == "--remainder" ]]; then - REMAINDER_MODE=true - else - _filtered_args+=("$_arg") - fi + case "$_arg" in + --remainder) REMAINDER_MODE=true ;; + --weekly) WEEKLY_MODE=true ;; + *) _filtered_args+=("$_arg") ;; + esac done unset _arg @@ -182,6 +201,11 @@ if [[ "$REMAINDER_MODE" == true ]]; then [[ -n "$_c" ]] && _exclude["$_c"]=1 done + # Weekly containers — updated by docker_update.sh --weekly + for _c in "${WEEKLY_RESTART_CONTAINERS[@]}"; do + [[ -n "$_c" ]] && _exclude["$_c"]=1 + done + # Weekly sync-window containers (emby + critical-data) — updated inline by weekly_sync_maintenance.sh _weekly_str="${PROFILE_CRITICAL_CONTAINER_NAMES[emby]:-} ${PROFILE_CRITICAL_CONTAINER_NAMES[critical-data]:-}" read -r -a _weekly_arr <<< "$_weekly_str" @@ -209,6 +233,19 @@ if [[ "$REMAINDER_MODE" == true ]]; then [[ -z "${_exclude[$_c]+x}" ]] && TARGET_CONTAINERS+=("$_c") done unset _all_running _exclude _c +elif [[ "$WEEKLY_MODE" == true ]]; then + if [[ "${WEEKLY_CONTAINER_UPDATES:-true}" != "true" ]]; then + echo "WEEKLY_CONTAINER_UPDATES=false — skipping weekly container updates" + exit 0 + fi + + if [[ ${#WEEKLY_RESTART_CONTAINERS[@]} -eq 0 ]]; then + warn "WEEKLY_RESTART_CONTAINERS is empty for $MY_ID — nothing to update" + warn "Check HOST${MY_ID#HOST}_WEEKLY_RESTART_CONTAINERS in host*.conf" + exit 0 + fi + + TARGET_CONTAINERS=("${WEEKLY_RESTART_CONTAINERS[@]}") else if [[ "${DAILY_CONTAINER_UPDATES:-true}" != "true" ]]; then echo "DAILY_CONTAINER_UPDATES=false — skipping container updates" @@ -231,11 +268,16 @@ if [[ "$SHOW_STATUS" == true ]]; then echo "" echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━" echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)" - echo "$ICON_GEAR Mode: $([[ "$REMAINDER_MODE" == true ]] && echo "remainder" || echo "normal (daily)")" if [[ "$REMAINDER_MODE" == true ]]; then - echo "$ICON_CONTAINERS Containers: ${#TARGET_CONTAINERS[@]} running (excluding daily, weekly sync, and fallback)" + echo "$ICON_GEAR Mode: remainder (monthly)" + echo "$ICON_CONTAINERS Containers: ${#TARGET_CONTAINERS[@]} running (excluding daily, weekly, sync-window, fallback)" for _c in "${TARGET_CONTAINERS[@]}"; do echo " $_c"; done + elif [[ "$WEEKLY_MODE" == true ]]; then + echo "$ICON_GEAR Mode: weekly" + echo "$ICON_CONTAINERS Containers: ${TARGET_CONTAINERS[*]}" + echo "$ICON_GEAR Enabled: ${WEEKLY_CONTAINER_UPDATES:-true}" else + echo "$ICON_GEAR Mode: normal (daily)" echo "$ICON_CONTAINERS Containers: ${TARGET_CONTAINERS[*]}" echo "$ICON_GEAR Enabled: ${DAILY_CONTAINER_UPDATES:-true}" fi @@ -257,8 +299,11 @@ fi echo "" if [[ "$REMAINDER_MODE" == true ]]; then echo "━━━ $ICON_CONTAINERS Docker Update (remainder) — $(date '+%Y-%m-%d %H:%M:%S') ━━━" - echo "$ICON_CONTAINERS Updating ${#TARGET_CONTAINERS[@]} container(s) (not in daily or weekly sync)" + echo "$ICON_CONTAINERS Updating ${#TARGET_CONTAINERS[@]} container(s) (not in daily, weekly, or sync window)" log "$ICON_CONTAINERS Remainder targets: ${TARGET_CONTAINERS[*]}" +elif [[ "$WEEKLY_MODE" == true ]]; then + echo "━━━ $ICON_CONTAINERS Docker Update (weekly) — $(date '+%Y-%m-%d %H:%M:%S') ━━━" + log "$ICON_CONTAINERS Containers: ${TARGET_CONTAINERS[*]}" else echo "━━━ $ICON_CONTAINERS Docker Update — $(date '+%Y-%m-%d %H:%M:%S') ━━━" log "$ICON_CONTAINERS Containers: ${TARGET_CONTAINERS[*]}" @@ -382,6 +427,8 @@ END=$(date +%s) # ============================================================================================== if [[ "$REMAINDER_MODE" == true ]]; then echo "━━━━━ $ICON_SUMMARY DOCKER UPDATE (REMAINDER) SUMMARY ━━━━━" +elif [[ "$WEEKLY_MODE" == true ]]; then + echo "━━━━━ $ICON_SUMMARY DOCKER UPDATE (WEEKLY) SUMMARY ━━━━━" else echo "━━━━━ $ICON_SUMMARY DOCKER UPDATE SUMMARY ━━━━━" fi diff --git a/Plugin/unraid/user_script_plug-in.sh b/Plugin/unraid/user_script_plug-in.sh index 0c68ecd..842f6f2 100755 --- a/Plugin/unraid/user_script_plug-in.sh +++ b/Plugin/unraid/user_script_plug-in.sh @@ -329,8 +329,9 @@ # Critical-Data full clean auth stack mirror # 7. Start remote containers dependency order, new image, verify each container up # 8. Start local containers dependency order, new image, verify each container up -# 9. docker_weekly_restart.sh restart less-critical services: NextCloud, AdGuard, Immich -# 10. WEEKLY_MAINTENANCE_SCRIPTS — clear_logs.sh + playback_aware_*.sh discovery scripts. +# 9. docker_update.sh --weekly pull latest images for WEEKLY_RESTART_CONTAINERS +# 10. docker_weekly_restart.sh restart less-critical services: NextCloud, AdGuard, Immich +# 11. WEEKLY_MAINTENANCE_SCRIPTS — clear_logs.sh + playback_aware_*.sh discovery scripts. # playback_aware_lidarr_discovery.sh: 0–5 music adds/week # based on your Emby play history + Last.fm similar artists. # playback_aware_radarr_discovery.sh: 0–5 movie adds/week @@ -659,9 +660,11 @@ # Containers stay running during the pull. Rebuilds containers that received a new image. # docker_daily_restart.sh restarts the rest. Toggle: DAILY_CONTAINER_UPDATES in master.conf. # -# Remainder (monthly) — targets all running containers not in managed lists. -# Excludes daily list, emby+critical-data sync-window containers, -# and fallback containers owned by the remote server's update cycle. +# Weekly (--weekly) — targets WEEKLY_RESTART_CONTAINERS before docker_weekly_restart.sh. +# Rebuilds containers that received a new image. Toggle: WEEKLY_CONTAINER_UPDATES in master.conf. +# +# Remainder (--remainder, monthly) — targets all running containers not in managed lists. +# Excludes daily, weekly, emby+critical-data sync-window, and fallback containers. # Rebuilds containers that received a new image. Toggle: MONTHLY_REMAINING_UPDATES in master.conf. # # bash /boot/config/plugins/varaverk/Docker_Essentials/docker_update.sh --dry-run