From 83195ebb9e8366da2e93a17f3297cb27b24a8388 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sun, 24 May 2026 23:10:31 -0400 Subject: [PATCH] monthly_maintenance: reschedule to 0 0 15 * * (15th at midnight) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously ran daily at 3am with internal self-gating. Now scheduled directly on the 15th — uptime and interval gates still apply; a skip means next month's 15th. --- Orchestrators/monthly_maintenance.sh | 9 ++++----- user_script_plug-in.sh | 15 +++++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Orchestrators/monthly_maintenance.sh b/Orchestrators/monthly_maintenance.sh index 9dd46bc..d4d5d82 100644 --- a/Orchestrators/monthly_maintenance.sh +++ b/Orchestrators/monthly_maintenance.sh @@ -7,15 +7,14 @@ # 1. Server uptime >= MONTHLY_UPTIME_THRESHOLD_DAYS days # 2. Last run was >= MONTHLY_RUN_INTERVAL_DAYS days ago (or never run) # -# ── WHY UPTIME-TRIGGERED, NOT CRON ─────────────────────────────────────────────────────────── +# ── WHY UPTIME-GATED ───────────────────────────────────────────────────────────────────────── # A scheduled reboot resets uptime. Monthly tasks (ZFS scrub, SMART long test) need a # stable, settled system — not one that just rebooted. Uptime-gating ensures maintenance # only runs after the server has been healthy for a full month, never immediately post-boot. -# The daily cron is just the trigger mechanism. The uptime and interval checks inside -# the script are what enforce the monthly cadence. +# If uptime or interval gate is not met on the 15th, the run is skipped until next month. # # ── HOW TO CALL ────────────────────────────────────────────────────────────────────────────── -# Cron: 0 3 * * * — daily 3am check. Script self-gates — calling it daily is safe. +# Schedule: 0 0 15 * * (15th of each month at midnight) # Silent exit 0 when either gate is not met. Only outputs when maintenance actually fires. # # ── STATE FILE ──────────────────────────────────────────────────────────────────────────────── @@ -153,7 +152,7 @@ if [[ "$SHOW_STATUS" == true ]]; then fi echo "" - echo " Schedule: 0 3 * * * (daily check — script self-gates)" + echo " Schedule: 0 0 15 * * (15th of each month at midnight)" echo " Force flag: --force bypasses both gates" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" exit 0 diff --git a/user_script_plug-in.sh b/user_script_plug-in.sh index 5ce8f4b..52eb6b2 100644 --- a/user_script_plug-in.sh +++ b/user_script_plug-in.sh @@ -26,7 +26,7 @@ # sunday_morning_coffee_report.sh 7am Sunday — full weekly digest # weekly_health_digest.sh 8am daily — profile-controlled health notification # system_tuning_monitor.sh every 6 hours — inotify + php-fpm trend tracking -# monthly_maintenance.sh 3am daily — uptime-gated monthly tasks (self-gates to monthly) +# monthly_maintenance.sh 15th monthly — uptime-gated heavy tasks (ZFS scrub, SMART long test) # # ── INDIVIDUAL SCRIPTS ──────────────────────────────────────────────────────────────────────── # Every child script is also listed below, individually. @@ -90,7 +90,7 @@ # before rsync_stop) — fallback runs as a bare subprocess, not via /tmp/user.scripts, # so it is not caught by user_scripts_stop.sh. # v2.6 — monthly_maintenance.sh: uptime-gated orchestrator for heavy monthly tasks (ZFS scrub, -# SMART long test). Schedule 0 3 * * * — script self-gates to monthly cadence. +# SMART long test). Schedule 0 0 15 * * — 15th of each month at midnight. # storage_watchdog.sh + network_watchdog.sh: pool growth + connectivity watchdogs, # called via SYSTEM_WATCHDOG_SCRIPTS by system_watchdog.sh (watchdog chain, no cron). # webgui_watchdog.sh moved from standalone cron to SYSTEM_WATCHDOG_SCRIPTS chain. @@ -346,17 +346,16 @@ # ── MONTHLY MAINTENANCE ─────────────────────────────────────────────────────────────────────── -# Schedule: 0 3 * * * (daily 3am check — script self-gates to monthly cadence) +# Schedule: 0 0 15 * * (15th of each month at midnight) # Background: YES # # Runs heavy tasks that require a long-stable, settled system. Fires only when BOTH gates pass: # 1. Server uptime >= MONTHLY_UPTIME_THRESHOLD_DAYS (default: 30 days) # 2. Last run was >= MONTHLY_RUN_INTERVAL_DAYS ago (default: 30 days) # -# Why uptime-gated not cron: a scheduled reboot resets uptime. Monthly tasks (ZFS scrub, -# SMART extended tests) need a system that has been healthy for a full month — not one that -# just rebooted. The daily 3am cron is just the trigger. The gates inside enforce the cadence. -# Silent exit 0 when either gate is not met — calling daily is always safe. +# If either gate is not met on the 15th, the run is skipped until next month's 15th. +# A reboot between the 14th and 15th will defer maintenance — which is intentional; +# heavy tasks (ZFS scrub, SMART long test) should not run on a freshly rebooted system. # # Configure via master.conf MONTHLY_MAINTENANCE_SCRIPTS. Scripts planned but not yet built: # zfs_pool_scrub.sh ZFS pool integrity scrub (Tools/) @@ -1436,7 +1435,7 @@ # 0 1 * * * 1am daily: # Orchestrators/daily_sync_maintenance.sh # -# 0 3 * * * 3am daily (fires monthly — self-gated by uptime + interval): +# 0 0 15 * * 15th of each month at midnight: # Orchestrators/monthly_maintenance.sh # # 0 7 * * 0 Sunday 7am: