diff --git a/Configurations/master.conf b/Configurations/master.conf index f78ae30..2ace255 100644 --- a/Configurations/master.conf +++ b/Configurations/master.conf @@ -296,6 +296,7 @@ ARRAY_START_SCRIPTS=( "Plugin/unraid/System_Essentials/unraid_api_key_renew.sh" # re-register Varaverk API key — registry is ephemeral "System_Essentials/conf_sync.sh" # pull partner confs + push own conf into /tmp/.vv/ RAM cache + "System_Essentials/conf_cache_restore.sh" # load partner confs from persistent backup if conf_sync couldn't reach partner "Transcodes/ramdisk_setup.sh" # creates ramdisk + symlink before Emby starts "System_Essentials/docker_syslog_filter.sh" # suppress veth noise before logs fill "Plugin/unraid/System_Essentials/php_fpm_max_children.sh" # WebGUI performance tuning @@ -311,6 +312,7 @@ # Run sequentially (foreground) — each must complete before the next starts. # Order matters: user scripts first (prevents new ops), then data movement, then containers. ARRAY_STOP_SCRIPTS=( + "System_Essentials/conf_cache_save.sh" # snapshot partner conf RAM cache → /boot before anything stops "Plugin/unraid/System_Essentials/user_scripts_stop.sh" # stop background scripts before they start new ops "Fallback/fallback.sh --stop" # gracefully stop fallback (not caught by user_scripts_stop) "System_Essentials/rsync_stop.sh --rsync-only" # kill rsync; skip container recovery (handled below) diff --git a/Deployment/master.conf.template b/Deployment/master.conf.template index d6fbd7c..d7176d0 100644 --- a/Deployment/master.conf.template +++ b/Deployment/master.conf.template @@ -292,6 +292,8 @@ # Watchdogs (resource_watchdog, docker_watchdog, system_watchdog) are cronned via # watchdog_orchestrator.sh — NOT launched here. ARRAY_START_SCRIPTS=( + "System_Essentials/conf_sync.sh" # pull partner confs + push own conf into /tmp/.vv/ RAM cache + "System_Essentials/conf_cache_restore.sh" # load partner confs from persistent backup if conf_sync couldn't reach partner "Transcodes/ramdisk_setup.sh" # creates ramdisk + symlink before Emby starts "unRAID_Essentials/docker_syslog_filter.sh" # suppress veth noise before logs fill "unRAID_Essentials/php_fpm_max_children.sh" # WebGUI performance tuning @@ -306,6 +308,7 @@ # Run sequentially (foreground) — each must complete before the next starts. # Order matters: user scripts first (prevents new ops), then data movement, then containers. ARRAY_STOP_SCRIPTS=( + "System_Essentials/conf_cache_save.sh" # snapshot partner conf RAM cache → /boot before anything stops "unRAID_Essentials/user_scripts_stop.sh" # stop background scripts before they start new ops "Fallback/fallback.sh --stop" # gracefully stop fallback (not caught by user_scripts_stop) "unRAID_Essentials/rsync_stop.sh --rsync-only" # kill rsync; skip container recovery (handled below) diff --git a/System_Essentials/conf_cache_restore.sh b/System_Essentials/conf_cache_restore.sh new file mode 100755 index 0000000..f89e4fb --- /dev/null +++ b/System_Essentials/conf_cache_restore.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# ============================================================================================== +# ============================= Conf Cache Restore ============================================= +# ============================================================================================== +# +# PURPOSE +# ───────────────────────────────────────────────────────────────────────────── +# Runs at array start after conf_sync.sh. Checks whether partner confs made it +# into the RAM cache. If any are missing (partner was unreachable at boot) and +# a persistent backup exists from the previous shutdown, loads the missing confs +# from backup into the RAM cache so scripts like fallback.sh have partner vars. +# +# Always removes the persistent backup when done — used or not. +# +# Normal reboot (partner up): +# conf_sync.sh pulls fresh → RAM cache complete → backup not needed → removed +# +# Edge case (partner down at boot): +# conf_sync.sh fails to pull → RAM cache missing partner → backup loaded into +# RAM → backup removed → fallback.sh runs with last-known-good partner vars +# +# Own conf is never in the backup — it's always on disk. +# ============================================================================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/../load_config.sh" + +parse_args "$@" +detect_hosts + +RAM_CACHE="/tmp/.vv/config/cached/.confs" +SAVE_DIR="/boot/config/varaverk/conf_bak" + +[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made" + +if [[ ! -d "$SAVE_DIR" ]]; then + log "No persistent conf backup found — nothing to restore" + exit 0 +fi + +restored=0 +for conf in "$SAVE_DIR"/host*.conf; do + [[ -f "$conf" ]] || continue + base="$(basename "$conf")" + [[ "${base,,}" == "${MY_ID,,}.conf" ]] && continue + + if [[ -f "$RAM_CACHE/$base" ]]; then + log "$base already in RAM cache (conf_sync succeeded) — skipping" + continue + fi + + if [[ "$DRY_RUN" == true ]]; then + warn "DRY RUN — would restore $base → RAM cache" + (( restored++ )) + continue + fi + + mkdir -p "$RAM_CACHE" + if cp "$conf" "$RAM_CACHE/$base"; then + echo "Restored $base from persistent backup → RAM cache ✅" + (( restored++ )) + else + warn "Failed to restore $base" + fi +done + +[[ "$restored" -gt 0 ]] && \ + warn "Loaded $restored partner conf(s) from persistent backup — partner was unreachable at array start" + +if [[ "$DRY_RUN" == false ]]; then + rm -rf "$SAVE_DIR" + log "Persistent conf backup cleared" +else + warn "DRY RUN — would remove $SAVE_DIR" +fi + +exit 0 diff --git a/System_Essentials/conf_cache_save.sh b/System_Essentials/conf_cache_save.sh new file mode 100755 index 0000000..f5c9fdd --- /dev/null +++ b/System_Essentials/conf_cache_save.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# ============================================================================================== +# ============================= Conf Cache Save ================================================ +# ============================================================================================== +# +# PURPOSE +# ───────────────────────────────────────────────────────────────────────────── +# Snapshots the partner conf RAM cache to /boot/config/varaverk/conf_bak/ on +# array stop. Survives reboot. Used by conf_cache_restore.sh at next array start +# to reload partner vars into RAM when the partner is unreachable at boot time. +# +# Runs as the first step in ARRAY_STOP_SCRIPTS — while the RAM cache is fresh +# and before anything else changes. If partner is reachable at next start, +# conf_sync.sh gets a fresh copy and the backup is never used. If partner is +# down, the backup fills the gap so fallback.sh has the vars it needs. +# +# Only partner confs are saved — own conf is always on disk. +# Location is outside the git repo and outside the main plugin folder. +# ============================================================================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/../load_config.sh" + +parse_args "$@" +detect_hosts + +RAM_CACHE="/tmp/.vv/config/cached/.confs" +SAVE_DIR="/boot/config/varaverk/conf_bak" + +[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no files will be written" + +if [[ ! -d "$RAM_CACHE" ]]; then + log "No RAM conf cache found — nothing to save" + exit 0 +fi + +saved=0 +for conf in "$RAM_CACHE"/host*.conf; do + [[ -f "$conf" ]] || continue + base="$(basename "$conf")" + [[ "${base,,}" == "${MY_ID,,}.conf" ]] && continue + + if [[ "$DRY_RUN" == true ]]; then + warn "DRY RUN — would save $base → $SAVE_DIR/" + (( saved++ )) + continue + fi + + mkdir -p "$SAVE_DIR" + if cp "$conf" "$SAVE_DIR/$base"; then + echo "Saved $base → $SAVE_DIR ✅" + (( saved++ )) + else + warn "Failed to save $base" + fi +done + +if [[ "$saved" -eq 0 ]]; then + log "No partner confs in RAM cache — nothing saved" +else + echo "Conf cache saved: $saved partner conf(s) → $SAVE_DIR" +fi