MY_ID is not exported and is unset until detect_hosts runs, so the DDNS and NPM checks were silently resolving empty config and skipping themselves every cycle.
145 lines
7.6 KiB
Bash
Executable File
145 lines
7.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# ==============================================================================================
|
|
# ================================= CONFIGURATION LOADER =======================================
|
|
# ==============================================================================================
|
|
#
|
|
# PURPOSE
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Single entry point for all configuration sourcing across the ecosystem.
|
|
# Every script sources this file instead of sourcing conf files directly.
|
|
#
|
|
# ==============================================================================================
|
|
# OPERATIONAL MODEL
|
|
# ==============================================================================================
|
|
#
|
|
# Sourcing order (order is load-bearing):
|
|
# 1. Detects OS platform → PLATFORM=unraid|truenas|unknown; exports SCRIPTS_DIR
|
|
# 2. Sources master.conf — shared config: hostnames, thresholds, toggles, profiles, job lists
|
|
# 3. Auto-discovers and sources all host*.conf files present in Configurations/
|
|
# Each host conf extends the shared profile arrays and adds host-specific credentials
|
|
# 4. Sources common.sh — shared functions: detect_hosts, logging, notifications, etc.
|
|
# 5. Sources Plugin/<platform>/adapter.sh — platform_*() functions for OS-specific ops
|
|
#
|
|
# USAGE IN SCRIPTS
|
|
# Scripts in subdirectories (Rsync/, Docker_Essentials/ etc.):
|
|
# SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# source "$SCRIPT_DIR/../load_config.sh"
|
|
#
|
|
# Scripts in the repo root:
|
|
# SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# source "$SCRIPT_DIR/load_config.sh"
|
|
#
|
|
# SPARSE CHECKOUT NOTE
|
|
# Sparse checkout controls which host*.conf files each server receives.
|
|
# HOST1 only pulls Configurations/host1.conf — never HOST2's credentials.
|
|
# HOST2 only pulls Configurations/host2.conf — never HOST1's credentials.
|
|
# This loader sources whatever conf files ARE present — sparse checkout handles the rest.
|
|
#
|
|
# ==============================================================================================
|
|
# DESIGN PRINCIPLES
|
|
# ==============================================================================================
|
|
#
|
|
# Zero-Script Expansion
|
|
# Without this loader, adding a new server required updating every script to
|
|
# source the new host conf. With this loader: create host3.conf in the repo,
|
|
# commit and push — all servers auto-discover it on next git pull. No script
|
|
# changes required.
|
|
#
|
|
# ==============================================================================================
|
|
|
|
# ━━━ Locate config root ━━━
|
|
# load_config.sh always lives in the repo root.
|
|
# Scripts call it from subdirectories using ../ — resolve to the actual root.
|
|
LOAD_CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# ━━━ Platform detection ━━━
|
|
# PLATFORM drives the adapter layer — Plugin/<platform>/adapter.sh
|
|
# Each platform adapter provides the same function API; scripts stay OS-agnostic.
|
|
if [[ -f /etc/unraid-version ]]; then PLATFORM="unraid"
|
|
elif [[ -f /etc/truenas ]]; then PLATFORM="truenas"
|
|
else PLATFORM="unknown"
|
|
fi
|
|
export PLATFORM SCRIPTS_DIR="$LOAD_CONFIG_DIR"
|
|
|
|
# ━━━ Source shared config ━━━
|
|
# master.conf must be sourced first — it declares the shared PROFILE_* arrays
|
|
# that Host confs extend. Sourcing host confs before master.conf would fail.
|
|
if [[ ! -f "$LOAD_CONFIG_DIR/Configurations/master.conf" ]]; then
|
|
echo "[FATAL] master.conf not found at $LOAD_CONFIG_DIR/Configurations/master.conf" >&2
|
|
echo "[FATAL] Check TARGET_DIR and git pull status" >&2
|
|
exit 1
|
|
fi
|
|
source "$LOAD_CONFIG_DIR/Configurations/master.conf"
|
|
|
|
# ━━━ Auto-discover and source all host*.conf files ━━━
|
|
# Sorted for consistent load order — HOST1 before HOST2 before HOST3 etc.
|
|
# Each host conf extends the shared PROFILE_* arrays and adds host-specific vars.
|
|
# Missing files are silently skipped — sparse checkout intentionally withholds some.
|
|
# At least one host conf must be present or the ecosystem has no identity to work with.
|
|
_host_confs_loaded=0
|
|
declare -A _disk_conf_basenames=()
|
|
|
|
# Use a sorted array glob — avoids word-splitting on paths with spaces
|
|
while IFS= read -r _conf; do
|
|
[[ -f "$_conf" ]] || continue
|
|
source "$_conf"
|
|
(( _host_confs_loaded++ ))
|
|
_disk_conf_basenames["$(basename "$_conf")"]=1
|
|
[[ "${ENABLE_LOGGING:-false}" == "true" ]] && \
|
|
echo "[LOG] Loaded host config: $(basename "$_conf")" >&2
|
|
done < <(printf '%s\n' "$LOAD_CONFIG_DIR/Configurations"/host*.conf 2>/dev/null | sort)
|
|
|
|
if [[ "$_host_confs_loaded" -eq 0 ]]; then
|
|
echo "[FATAL] No host*.conf files found in $LOAD_CONFIG_DIR" >&2
|
|
echo "[FATAL] At least one host conf required — check git pull and sparse checkout" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ━━━ Source partner confs from /tmp cache ━━━
|
|
# conf_sync.sh pulls partner host*.conf files into /tmp/.cache/vv/d/
|
|
# on array start and after any conf save. Sourcing them here makes partner vars
|
|
# (HOST2_*, HOST3_*, …) available without committing credentials to the git repo
|
|
# or violating sparse checkout — partner confs live in RAM only, cleared on reboot.
|
|
# Confs already loaded from disk are skipped — disk copy is authoritative.
|
|
_VV_CONF_CACHE="/tmp/.cache/vv/d"
|
|
if [[ -d "$_VV_CONF_CACHE" ]]; then
|
|
while IFS= read -r _conf; do
|
|
[[ -f "$_conf" ]] || continue
|
|
_conf_base="$(basename "$_conf")"
|
|
# Skip if already sourced from disk
|
|
[[ -n "${_disk_conf_basenames[$_conf_base]:-}" ]] && continue
|
|
source "$_conf"
|
|
[[ "${ENABLE_LOGGING:-false}" == "true" ]] && \
|
|
echo "[LOG] Loaded cached partner config: $_conf_base" >&2
|
|
done < <(printf '%s\n' "$_VV_CONF_CACHE"/host*.conf 2>/dev/null | sort)
|
|
fi
|
|
unset _VV_CONF_CACHE _conf_base _disk_conf_basenames
|
|
|
|
# ━━━ Source shared functions ━━━
|
|
# common.sh sourced last — it defines detect_hosts(), which needs HOST* vars to be set.
|
|
# It does NOT call it. Each script calls detect_hosts() itself, so MY_ID and REMOTE_ID
|
|
# are unset until it does — anything building HOST*-prefixed variable names must come after.
|
|
if [[ ! -f "$LOAD_CONFIG_DIR/common.sh" ]]; then
|
|
echo "[FATAL] common.sh not found at $LOAD_CONFIG_DIR/common.sh" >&2
|
|
exit 1
|
|
fi
|
|
source "$LOAD_CONFIG_DIR/common.sh"
|
|
|
|
# ━━━ Source platform adapter ━━━
|
|
# Provides platform_*() functions used by common.sh and scripts.
|
|
# Guard lets the ecosystem run before Plugin/<platform>/adapter.sh exists.
|
|
_adapter="$LOAD_CONFIG_DIR/Plugin/$PLATFORM/adapter.sh"
|
|
[[ -f "$_adapter" ]] && source "$_adapter"
|
|
|
|
# ━━━ Derived path constants ━━━
|
|
# Centralised here so every script that sources load_config.sh has them without
|
|
# re-deriving from SCRIPTS_DIR or hardcoding /var/log or /tmp paths inline.
|
|
CONF_DIR="${SCRIPTS_DIR}/Configurations"
|
|
LOG_DIR="/var/log/varaverk"
|
|
VV_CACHE_DIR="/tmp/vv_cache"
|
|
CONF_RAM_CACHE_DIR="/tmp/.cache/vv/d" # tmpfs — cleared every reboot, repopulated by conf_sync.sh
|
|
ARR_CACHE_DIR="/tmp/arr_cache" # tmpfs — cleared every reboot, restored from DATA_DIR backup by arr_cache_age_seconds()
|
|
export CONF_DIR LOG_DIR VV_CACHE_DIR CONF_RAM_CACHE_DIR ARR_CACHE_DIR
|
|
|
|
# ━━━ Cleanup ━━━
|
|
unset _conf _host_confs_loaded _adapter LOAD_CONFIG_DIR |