massive update. Master conf split, now modular with a load sceriprt to drive all configs to scripts. with unraid scpecific safeguard tests , and improved standardized ux. including dynamic host detect, who am i who else it there. EVERY SINGLE SCRIPT UPDATED. DEBATING THAT THIS IS ACUALLY V2
This commit is contained in:
+157
-51
@@ -1,53 +1,136 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# --------------------------------- Array Start Orchestrator -----------------------------------
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# Single entry point for "At Startup of Array" in User Scripts plugin.
|
||||
# Launches everything configured in ARRAY_START_SCRIPTS in Master.conf.
|
||||
# ==============================================================================================
|
||||
# ================================= Array Start Orchestrator ===================================
|
||||
# ==============================================================================================
|
||||
# Single entry point for "At Startup of Array" in the User Scripts plugin.
|
||||
# Launches everything configured in ARRAY_START_SCRIPTS in master.conf.
|
||||
# This script exits after launching all scripts — unRAID sees it complete normally.
|
||||
#
|
||||
# What it launches (configured in Master.conf ARRAY_START_SCRIPTS):
|
||||
# Transcodes/ramdisk_setup.sh — creates tmpfs + symlink before Emby starts (one-shot)
|
||||
# unRAID_Essentials/docker_syslog_filter.sh — suppress veth log noise (one-shot)
|
||||
# unRAID_Essentials/php_fpm_max_children.sh — WebGUI performance tuning (one-shot)
|
||||
# Docker_Essentials/docker_network_connect.sh — ensure networks exist + connect containers (one-shot)
|
||||
# unRAID_Essentials/system_watchdog.sh — system health monitor (continuous loop)
|
||||
# Docker_Essentials/docker_watchdog.sh — container health monitor (continuous loop)
|
||||
# Failover/failover.sh — mutual failover monitor (continuous loop)
|
||||
# ── WHAT IT LAUNCHES ──────────────────────────────────────────────────────────────────────────
|
||||
# Configured in master.conf ARRAY_START_SCRIPTS — no changes to this script ever needed.
|
||||
# Current order (order matters — see below):
|
||||
#
|
||||
# One-shot scripts run and exit naturally — array_start.sh confirms completion.
|
||||
# Continuous scripts run until array stops or SIGTERM received.
|
||||
# This orchestrator exits after launching all scripts — unRAID sees it complete normally.
|
||||
# ONE-SHOT (run and exit naturally):
|
||||
# unRAID_Essentials/inotify_tuning.sh — raise inotify limits before containers start
|
||||
# unRAID_Essentials/docker_syslog_filter.sh — suppress veth log noise before logs fill
|
||||
# unRAID_Essentials/php_fpm_max_children.sh — WebGUI performance tuning
|
||||
# Transcodes/ramdisk_setup.sh — create tmpfs + symlink before Emby starts
|
||||
# Docker_Essentials/docker_network_connect.sh — ensure networks + container connections
|
||||
#
|
||||
# Add or remove scripts: edit ARRAY_START_SCRIPTS in Master.conf.
|
||||
# Order matters — ramdisk first, network before watchdogs, watchdogs before failover.
|
||||
# No changes to this script ever needed.
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# CONTINUOUS (run until array stops):
|
||||
# unRAID_Essentials/system_watchdog.sh — system health monitor (last line of defense)
|
||||
# Docker_Essentials/docker_watchdog.sh — container health monitor
|
||||
# Failover/failover.sh — mutual failover monitor
|
||||
#
|
||||
# ── WHY ORDER MATTERS ─────────────────────────────────────────────────────────────────────────
|
||||
# inotify_tuning.sh — must run BEFORE Code-Server and other containers start
|
||||
# containers that start with low inotify limits keep them ✅
|
||||
# docker_syslog_filter — must run BEFORE any container starts creating veth interfaces
|
||||
# ramdisk_setup.sh — must run BEFORE Emby starts transcoding
|
||||
# docker_network_connect — must run BEFORE watchdogs check container states
|
||||
# system_watchdog.sh — before docker_watchdog (system > container priority)
|
||||
# docker_watchdog.sh — before failover (containers must be healthy for failover)
|
||||
# failover.sh — last — needs everything else stable to make decisions
|
||||
#
|
||||
# ── ONE-SHOT vs CONTINUOUS DETECTION ─────────────────────────────────────────────────────────
|
||||
# Script is launched in background with bash script.sh &
|
||||
# After 1 second: if PID still alive → continuous (running in background)
|
||||
# if PID dead + exit 0 → one-shot completed successfully
|
||||
# if PID dead + exit N → failure
|
||||
#
|
||||
# ── SAFEGUARDS ────────────────────────────────────────────────────────────────────────────────
|
||||
# Root check — all launched scripts require root
|
||||
# acquire_lock — prevents duplicate array start launches
|
||||
# detect_hosts() — MY_ID in notifications
|
||||
# validate_unraid_cmd — notify validated before use
|
||||
# chmod +x auto-fix — non-executable scripts fixed before launch
|
||||
# Full path on failure — shows exact path for debugging
|
||||
# notify on failures — alert if any script fails to launch
|
||||
#
|
||||
# ── CONFIGURATION (master.conf) ───────────────────────────────────────────────────────────────
|
||||
# ARRAY_START_SCRIPTS — ordered list of scripts to launch at array start
|
||||
#
|
||||
# ── USAGE ─────────────────────────────────────────────────────────────────────────────────────
|
||||
# array_start.sh — normal launch (called by User Scripts at array start)
|
||||
# array_start.sh --dry-run — show what would be launched without launching
|
||||
# array_start.sh --status — show configured scripts and their current state
|
||||
# array_start.sh --log — verbose output per script
|
||||
# ==============================================================================================
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ECOSYSTEM_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
source "$ECOSYSTEM_ROOT/Master.conf"
|
||||
source "$ECOSYSTEM_ROOT/common.sh"
|
||||
source "$ECOSYSTEM_ROOT/load_config.sh"
|
||||
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# ━━━ $ICON_GEAR Setup ━━━
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "━━━ $ICON_GEAR Array Start — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
|
||||
parse_args "$@"
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Setup ━━━
|
||||
# ==============================================================================================
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
error "Must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
success "Running as root"
|
||||
validate_unraid_cmd \
|
||||
"/usr/local/emhttp/plugins/dynamix/scripts/notify" \
|
||||
"" "" \
|
||||
"unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
|
||||
|
||||
SCRIPT_COUNT=${#ARRAY_START_SCRIPTS[@]}
|
||||
info "Launching $SCRIPT_COUNT script(s)..."
|
||||
acquire_lock
|
||||
|
||||
detect_hosts
|
||||
|
||||
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — scripts will not be launched"
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Status ━━━
|
||||
# ==============================================================================================
|
||||
if [[ "$SHOW_STATUS" == true ]]; then
|
||||
echo ""
|
||||
echo "━━━━━ $ICON_SUMMARY ARRAY START STATUS ━━━━━"
|
||||
echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)"
|
||||
echo "$ICON_GEAR Scripts: ${#ARRAY_START_SCRIPTS[@]} configured"
|
||||
echo ""
|
||||
|
||||
for relative_path in "${ARRAY_START_SCRIPTS[@]}"; do
|
||||
[[ -z "$relative_path" ]] && continue
|
||||
script_path="$ECOSYSTEM_ROOT/$relative_path"
|
||||
script_name=$(basename "$script_path")
|
||||
|
||||
if [[ ! -f "$script_path" ]]; then
|
||||
echo " $ICON_ERROR $script_name — FILE NOT FOUND"
|
||||
echo " $script_path"
|
||||
continue
|
||||
fi
|
||||
|
||||
[[ ! -x "$script_path" ]] && flag=" (not executable — will auto-fix)" || flag=""
|
||||
|
||||
# Check if currently running
|
||||
if pgrep -f "$script_path" >/dev/null 2>&1; then
|
||||
RUN_PID=$(pgrep -f "$script_path" | head -1)
|
||||
echo " $ICON_RUNNING $script_name — RUNNING (PID $RUN_PID)${flag}"
|
||||
else
|
||||
echo " $ICON_NOT_RUNNING $script_name — not running${flag}"
|
||||
fi
|
||||
done
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Launch Scripts ━━━
|
||||
# ==============================================================================================
|
||||
echo ""
|
||||
echo "━━━ $ICON_GEAR Array Start — $MY_ID — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
|
||||
log "Ecosystem root: $ECOSYSTEM_ROOT"
|
||||
log "Launching ${#ARRAY_START_SCRIPTS[@]} script(s)..."
|
||||
echo ""
|
||||
|
||||
START=$(date +%s)
|
||||
LAUNCHED=0
|
||||
FAILED=0
|
||||
FAILED_SCRIPTS=()
|
||||
|
||||
for relative_path in "${ARRAY_START_SCRIPTS[@]}"; do
|
||||
[[ -z "$relative_path" ]] && continue
|
||||
@@ -55,57 +138,80 @@ for relative_path in "${ARRAY_START_SCRIPTS[@]}"; do
|
||||
SCRIPT_PATH="$ECOSYSTEM_ROOT/$relative_path"
|
||||
SCRIPT_NAME=$(basename "$SCRIPT_PATH")
|
||||
|
||||
# File existence check
|
||||
if [[ ! -f "$SCRIPT_PATH" ]]; then
|
||||
error "$SCRIPT_NAME — not found at $SCRIPT_PATH"
|
||||
((FAILED++))
|
||||
error "$SCRIPT_NAME — not found"
|
||||
error " Expected: $SCRIPT_PATH"
|
||||
(( FAILED++ ))
|
||||
FAILED_SCRIPTS+=("$SCRIPT_NAME")
|
||||
continue
|
||||
fi
|
||||
|
||||
# Auto-fix permissions — chmod +x if needed
|
||||
if [[ ! -x "$SCRIPT_PATH" ]]; then
|
||||
error "$SCRIPT_NAME — not executable"
|
||||
((FAILED++))
|
||||
warn "$SCRIPT_NAME — not executable, fixing..."
|
||||
chmod +x "$SCRIPT_PATH" || {
|
||||
error "$SCRIPT_NAME — chmod +x failed"
|
||||
(( FAILED++ ))
|
||||
FAILED_SCRIPTS+=("$SCRIPT_NAME")
|
||||
continue
|
||||
}
|
||||
fi
|
||||
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
warn "DRY RUN — would launch: $SCRIPT_NAME"
|
||||
(( LAUNCHED++ ))
|
||||
continue
|
||||
fi
|
||||
|
||||
info "$ICON_START Launching $SCRIPT_NAME..."
|
||||
log "$ICON_START Launching $SCRIPT_NAME..."
|
||||
bash "$SCRIPT_PATH" &
|
||||
PID=$!
|
||||
|
||||
# Brief pause to let script initialize and catch immediate failures
|
||||
# Brief settle — 1s enough to detect immediate failures
|
||||
sleep 1
|
||||
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
success "$SCRIPT_NAME — running (PID $PID)"
|
||||
((LAUNCHED++))
|
||||
# Still running → continuous script
|
||||
warn "$SCRIPT_NAME — running (PID $PID) ✅"
|
||||
(( LAUNCHED++ ))
|
||||
else
|
||||
# Script exited — check if it was a one-shot (exit 0) or a failure
|
||||
# Exited — check if one-shot success or failure
|
||||
wait "$PID"
|
||||
EXIT_CODE=$?
|
||||
if [[ "$EXIT_CODE" -eq 0 ]]; then
|
||||
success "$SCRIPT_NAME — completed (one-shot)"
|
||||
((LAUNCHED++))
|
||||
log "$SCRIPT_NAME — completed (one-shot) ✅"
|
||||
(( LAUNCHED++ ))
|
||||
else
|
||||
error "$SCRIPT_NAME — exited with code $EXIT_CODE"
|
||||
((FAILED++))
|
||||
error " Path: $SCRIPT_PATH"
|
||||
(( FAILED++ ))
|
||||
FAILED_SCRIPTS+=("$SCRIPT_NAME")
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# ━━━ $ICON_SUMMARY Summary ━━━
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
END=$(date +%s)
|
||||
|
||||
# ==============================================================================================
|
||||
# ━━━ Summary ━━━
|
||||
# ==============================================================================================
|
||||
echo ""
|
||||
echo "━━━━━ $ICON_SUMMARY ARRAY START SUMMARY ━━━━━"
|
||||
echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)"
|
||||
echo "$ICON_SUCCESS Launched: $LAUNCHED"
|
||||
echo "$ICON_ERROR Failed: $FAILED"
|
||||
echo "$ICON_TIME Time: $(date '+%H:%M:%S')"
|
||||
[[ "$FAILED" -gt 0 ]] && echo "$ICON_ERROR Failed: $FAILED — ${FAILED_SCRIPTS[*]}"
|
||||
echo "$ICON_TIME Duration: $(format_duration $(( END - START )))"
|
||||
echo ""
|
||||
|
||||
if [[ "$FAILED" -gt 0 ]]; then
|
||||
echo "$ICON_WARN Status: $FAILED script(s) failed to launch — check logs"
|
||||
notify "Array start on $(hostname) — $FAILED script(s) failed to launch" "Array Start" "warning"
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
warn "DRY RUN — no scripts launched"
|
||||
elif [[ "$FAILED" -gt 0 ]]; then
|
||||
warn "Status: $FAILED script(s) failed — ${FAILED_SCRIPTS[*]}"
|
||||
notify "Array start on $(hostname) ($MY_ID) — $FAILED script(s) failed: ${FAILED_SCRIPTS[*]}" \
|
||||
"Array Start" "warning"
|
||||
else
|
||||
echo "$ICON_DONE Status: $ICON_SUCCESS All scripts launched"
|
||||
log "$ICON_DONE Status: all $LAUNCHED script(s) launched ✅"
|
||||
fi
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
Reference in New Issue
Block a user