Platform adapter: rename System_Essentials, add Plugin/unraid/adapter.sh, wire call sites

- Rename unRAID_Essentials/ → System_Essentials/ (git detects as rename)
- Add Plugin/unraid/adapter.sh: 13 platform_*() functions providing OS-agnostic API
  for storage health, service management, mover, user scripts, notifications,
  disk temps, and platform command validation
- Update load_config.sh: detect PLATFORM (unraid/truenas/unknown), export SCRIPTS_DIR,
  auto-source Plugin/$PLATFORM/adapter.sh after common.sh
- Wire all call sites: replace direct rc.d, pgrep/pkill, var.ini, dynamix.cfg,
  disks.ini, and validate_unraid_cmd calls with platform_*() functions across
  watchdogs, orchestrators, and System_Essentials scripts
- Update all documentation: rename refs, update webgui escalation logic,
  add platform adapter section to Plugin README, update main README with
  portability vision and corrected self-healing stack description
This commit is contained in:
Gmer4Lfe
2026-06-04 18:14:34 -04:00
parent de50a01ab2
commit 369a9e6c19
73 changed files with 522 additions and 228 deletions
+1 -1
View File
@@ -112,7 +112,7 @@ if [[ "$EUID" -ne 0 ]]; then
exit 1
fi
validate_unraid_cmd \
platform_require_cmd \
"/usr/local/emhttp/plugins/dynamix/scripts/notify" \
"" "" \
"unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
+9 -9
View File
@@ -104,7 +104,7 @@ if [[ "$EUID" -ne 0 ]]; then
exit 1
fi
validate_unraid_cmd \
platform_require_cmd \
"/usr/local/emhttp/plugins/dynamix/scripts/notify" \
"" "" \
"unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
@@ -132,16 +132,16 @@ if [[ "$SHOW_STATUS" == true ]]; then
echo " $ICON_ERROR WebGUI: NOT responding"
fi
pgrep -x nginx >/dev/null 2>&1 && \
platform_is_service_running nginx && \
echo " $ICON_SUCCESS nginx: running ✅" || \
echo " $ICON_ERROR nginx: NOT running"
pgrep -f "php-fpm" >/dev/null 2>&1 && \
platform_is_service_running php-fpm && \
FPM_COUNT=$(pgrep -fc "php-fpm" 2>/dev/null || echo "?") && \
echo " $ICON_SUCCESS php-fpm: running ($FPM_COUNT workers) ✅" || \
echo " $ICON_ERROR php-fpm: NOT running"
pgrep emhttpd >/dev/null 2>&1 && \
platform_is_service_running emhttp && \
echo " $ICON_SUCCESS emhttp: running ✅" || \
echo " $ICON_ERROR emhttp: NOT running"
echo "━━━━━━━━━━━━━━━━━━━━━━━"
@@ -185,10 +185,10 @@ if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would restart nginx"
else
warn "Restarting nginx..."
if /etc/rc.d/rc.nginx restart >/dev/null 2>&1; then
if platform_restart_service nginx; then
# Verify nginx actually running
sleep 2
if pgrep -x nginx >/dev/null 2>&1; then
if platform_is_service_running nginx; then
warn "nginx restarted ✅"
else
error "nginx not running after restart command"
@@ -216,9 +216,9 @@ if [[ "$RECOVERY_OK" == false ]]; then
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would restart php-fpm"
else
if /etc/rc.d/rc.php-fpm restart >/dev/null 2>&1; then
if platform_restart_service php-fpm; then
sleep 2
if pgrep -f "php-fpm" >/dev/null 2>&1; then
if platform_is_service_running php-fpm; then
warn "php-fpm restarted ✅"
else
error "php-fpm not running after restart command"
@@ -249,7 +249,7 @@ if [[ "$RECOVERY_OK" == false ]]; then
else
if /usr/local/sbin/emhttp stop >/dev/null 2>&1 && /usr/local/sbin/emhttp start >/dev/null 2>&1; then
sleep 2
if pgrep emhttpd >/dev/null 2>&1; then
if platform_is_service_running emhttp; then
warn "emhttp restarted ✅"
else
error "emhttp not running after restart command"
+9 -19
View File
@@ -256,9 +256,9 @@ log "$ICON_CONTAINERS Tier1: watched=${#WATCHDOG_CONTAINERS[@]} required=${#WAT
# Validate unRAID-specific commands used by this script
# If rc.docker is missing or changed, daemon restart will fail — better to know now
validate_unraid_cmd "/etc/rc.d/rc.docker" "" "" "Docker rc.d script" || warn "rc.docker not found — daemon restart unavailable if needed"
platform_require_cmd "/etc/rc.d/rc.docker" "" "" "Docker rc.d script" || warn "rc.docker not found — daemon restart unavailable if needed"
validate_unraid_cmd "/usr/local/emhttp/plugins/dynamix/scripts/notify" "" "" "unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
platform_require_cmd "/usr/local/emhttp/plugins/dynamix/scripts/notify" "" "" "unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
# Ensure state files exist
touch "$WATCHDOG_STATE_FILE" "$WATCHDOG_CONTAINER_RESTART_LOG" \
@@ -453,15 +453,8 @@ flush_notify() {
NOTIFY_EVENTS=()
}
# Returns 0 if parity check is currently running
# Unraid 7.3+: mdResync in var.ini (non-zero = check/sync in progress)
# Older: parity-date.txt contained "progress" — check both for compatibility
is_parity_running() {
local resync
resync=$(awk -F'"' '/^mdResync=/{print $2}' /var/local/emhttp/var.ini 2>/dev/null)
[[ -n "$resync" && "$resync" != "0" ]] && return 0
grep -q "progress" /var/local/emhttp/parity-date.txt 2>/dev/null
}
# is_parity_running — delegates to adapter
is_parity_running() { platform_is_maintenance_running; }
# ==============================================================================================
# ── DOCKER DAEMON HEALTH CHECK ────────────────────────────────────────────────────────────────
@@ -567,16 +560,14 @@ check_docker_daemon() {
notify "Docker daemon hung on $(hostname) — attempting restart" "Docker Watchdog" "warning"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would restart Docker daemon via /etc/rc.d/rc.docker restart"
warn "DRY RUN — would restart Docker daemon via platform_restart_service docker"
return 1
fi
# Restart daemon — unRAID uses rc.d scripts, not systemd
# timeout 180: rc.docker stops all containers before restarting — without a limit this
# can block for 30+ min on a busy host, holding the orchestrator lock the entire time.
# timeout 180: Docker daemon stop can block for 30+ min on a busy host.
WATCHDOG_DAEMON_RESTARTED=true
set_strikes "daemon_restarted_flag" "true" "$WATCHDOG_STATE_FILE"
if timeout 180 /etc/rc.d/rc.docker restart >/dev/null 2>&1; then
if timeout 180 platform_restart_service docker; then
log "Docker daemon restart issued — waiting ${WATCHDOG_DAEMON_RESTART_WAIT}s..."
sleep "$WATCHDOG_DAEMON_RESTART_WAIT"
@@ -598,8 +589,8 @@ check_docker_daemon() {
return 1
fi
else
# rc.docker not found or failed — flag immediately, stability_watchdog escalates
error "Failed to issue Docker daemon restart — /etc/rc.d/rc.docker not found or failed"
# platform_restart_service returned non-zero — flag immediately, stability_watchdog escalates
error "Failed to issue Docker daemon restart — platform_restart_service docker failed"
set_strikes "daemon_confirmed_down" "true" "$WATCHDOG_STATE_FILE"
queue_notify "Docker daemon restart command failed on $(hostname) — stability_watchdog escalating" "critical"
flush_notify
@@ -632,7 +623,6 @@ CYCLE_START=$(date +%s)
done
# ── Skip list visibility ─────────────────────────────────────────────────────────────────
local _skip_contents
_skip_contents=$(cat "$DOCKER_WATCHDOG_FAILED_FILE" 2>/dev/null | tr '\n' ' ' | xargs)
[[ -n "$_skip_contents" ]] && warn "$ICON_SKIP Skip list active: $_skip_contents — manual intervention needed"
+6 -10
View File
@@ -119,7 +119,7 @@ if [[ "$EUID" -ne 0 ]]; then
exit 1
fi
validate_unraid_cmd \
platform_require_cmd \
"/usr/local/emhttp/plugins/dynamix/scripts/notify" \
"" "" \
"unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
@@ -302,12 +302,8 @@ check_abort_conditions() {
fi
fi
# Unraid 7.3+: parity state is in var.ini (mdResync != 0 means check/sync in progress)
# Older: parity-date.txt contained "progress" — check both for compatibility
_md_resync=$(awk -F'"' '/^mdResync=/{print $2}' /var/local/emhttp/var.ini 2>/dev/null)
_parity_running=false
[[ -n "$_md_resync" && "$_md_resync" != "0" ]] && _parity_running=true
grep -q "progress" /var/local/emhttp/parity-date.txt 2>/dev/null && _parity_running=true
platform_is_maintenance_running && _parity_running=true
if [[ "$_parity_running" == true ]]; then
if [[ "$SYS_WATCHDOG_ABORT_ON_PARITY" == true ]]; then
error "Parity check running — aborting reboot"
@@ -451,7 +447,7 @@ do_reboot() {
fi
warn "Stopping User Scripts..."
pkill -f "/tmp/user.scripts" 2>/dev/null || true
platform_stop_user_scripts
warn "Syncing disks..."
sync
@@ -726,12 +722,12 @@ echo "━━━ $ICON_REBOOT Stability Watchdog — $(date '+%Y-%m-%d %H:%M:%S')
# ── sshd — try restart before escalating ─────────────────────────────────────────────────
if [[ "$SYS_WATCHDOG_CHECK_SSHD" == true ]]; then
if ! pgrep -x sshd >/dev/null 2>&1; then
if ! platform_is_service_running sshd; then
warn "sshd not running — attempting restart..."
if [[ "$DRY_RUN" == false ]]; then
/etc/rc.d/rc.sshd start >/dev/null 2>&1
platform_restart_service sshd
sleep 3
if pgrep -x sshd >/dev/null 2>&1; then
if platform_is_service_running sshd; then
warn "sshd restarted successfully ✅"
reset_strikes "sshd"
notify "sshd was down on $(hostname) ($MY_ID) — restarted automatically" \
+1 -1
View File
@@ -45,7 +45,7 @@ if [[ "$EUID" -ne 0 ]]; then
exit 1
fi
validate_unraid_cmd \
platform_require_cmd \
"/usr/local/emhttp/plugins/dynamix/scripts/notify" \
"" "" \
"unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"