Auth stack certs tab, arrs db fallbacks, cert monitor cache, conf parser fix

- Auth stack: fold cert monitor into Auth Stack page as fourth tab (Certs);
  remove standalone cert page and top-level tab
- cert_monitor.sh: write JSON status cache to State_Files/cert_status.json
  after each run; expose per-domain days/expiry via _CERT_DAYS/_CERT_EXPIRY globals
- api/cert.php: new — serves cached cert status; falls back to configured
  domains as UNKN when no cache exists; POST action=run triggers live check
- arrs db fallbacks: vv_arr_cleanup_stats/discovery_stats/recovery_stats now
  read from data/*.db files when log JSON files don't yet exist
- config.php vv_conf_vars(): unescape bash \$ → $ so passwords with dollar
  signs read correctly from conf files
- host1.conf: fill in HOST1_NPM_USER/PASS and HOST1_LLDAP_USER/PASS
- Partnership adapter pattern: Unraid-specific container logic extracted to
  Plugin/unraid/Partnership/; platform-agnostic structure stays in Partnership/
- First-run wizard: uniform multi-step flow for all hosts; HOST2 pull moved
  to checklist; auto SSH keygen and API key creation on save
- api/checklist.php: live setup checklist with pull_master action
- Fullscreen toggle: hide Unraid header/menu; state persists via localStorage
This commit is contained in:
Gmer4Lfe
2026-06-05 23:17:30 -04:00
parent 17012bcd8c
commit 9c3ace95a7
43 changed files with 1605 additions and 1167 deletions
+247
View File
@@ -0,0 +1,247 @@
#!/bin/bash
# ==============================================================================================
# ============================= PHP-FPM Max Children ===========================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Raises PHP-FPM pm.max_children to prevent WebGUI slowdowns under load. Run
# once at array start via ARRAY_START_SCRIPTS. Idempotent — silent when the
# value is already correct, no restart on clean boot.
#
# unRAID's WebGUI runs through PHP-FPM. The default pm.max_children is very
# low (48). Under load — multiple users, Docker operations, heavy dashboard
# usage — all PHP workers saturate and new requests queue. The WebGUI becomes
# slow or unresponsive.
#
# PHP_MAX_CHILDREN=250 is appropriate for 128GB RAM: ~2MB per worker = ~500MB
# total. Too high wastes RAM; too low causes slowdowns.
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Idempotent Content Check
# Reads the current pm.max_children value before writing. If already at
# target → silent exit, no PHP-FPM restart. Restarting PHP-FPM unnecessarily
# disrupts active WebGUI sessions on every boot.
#
# Pattern Match Before Write
# Verifies the sed pattern finds pm.max_children in the config before
# applying any change. Prevents silent failures where sed succeeds but
# writes nothing because the key was missing or commented out.
#
# Apply Sequence
# 1. Read current pm.max_children from PHP_CONF
# 2. If already at target → exit silently
# 3. Verify sed pattern matches before writing
# 4. Apply sed replacement
# 5. Restart PHP-FPM via rc.php-fpm
# 6. Verify PHP-FPM process running after restart
# 7. Read back config to confirm value applied
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
# Root Required
# Writing to /etc/php83/ requires root.
#
# Single Instance Lock
# acquire_lock prevents concurrent runs at array start.
#
# Process Verify
# Confirms PHP-FPM running after restart — errors if it failed to start.
#
# Config Verify
# Reads back config after restart to confirm the value was actually applied.
#
# Silent on Success
# Runs every boot — no noise when already correct.
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# master.conf
#
# PHP_MAX_CHILDREN
# Target pm.max_children value. (default: 250)
#
# PHP_CONF
# Path to PHP-FPM www.conf. (default: /etc/php83/php-fpm.d/www.conf)
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# php_fpm_max_children.sh
# Read current value. Update and restart PHP-FPM only if changed. Silent if correct.
#
# php_fpm_max_children.sh --dry-run
# Show current vs target value. No config write or restart.
#
# php_fpm_max_children.sh --status
# Show current pm.max_children, target, and PHP-FPM process state.
#
# php_fpm_max_children.sh --log
# Verbose output showing idempotent check, config write, and restart result.
#
# ==============================================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../../load_config.sh"
parse_args "$@"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root — writing system config requires root"
exit 1
fi
platform_require_cmd \
"/usr/local/emhttp/plugins/dynamix/scripts/notify" \
"" "" \
"unRAID notify script" || warn "unRAID notify script not found — native notifications disabled"
validate_int PHP_MAX_CHILDREN "$PHP_MAX_CHILDREN"
require_var PHP_CONF
acquire_lock
detect_hosts
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made"
# ==============================================================================================
# ━━━ Status ━━━
# ==============================================================================================
if [[ "$SHOW_STATUS" == true ]]; then
echo ""
echo "━━━━━ $ICON_SUMMARY PHP-FPM STATUS ━━━━━"
echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)"
echo "$ICON_GEAR Config file: $PHP_CONF"
echo "$ICON_PHP Target: pm.max_children = $PHP_MAX_CHILDREN"
echo ""
if [[ -f "$PHP_CONF" ]]; then
CURRENT_VAL=$(grep -E "^pm\.max_children" "$PHP_CONF" 2>/dev/null | \
awk '{print $NF}')
if [[ "${CURRENT_VAL:-0}" -eq "$PHP_MAX_CHILDREN" ]]; then
echo " $ICON_SUCCESS Current: pm.max_children = $CURRENT_VAL (correct ✅)"
else
echo " $ICON_WARN Current: pm.max_children = ${CURRENT_VAL:-not set} (would update)"
fi
else
echo " $ICON_ERROR Config file not found: $PHP_CONF"
fi
echo ""
if pgrep -f "php-fpm" >/dev/null 2>&1; then
FPM_COUNT=$(pgrep -fc "php-fpm" 2>/dev/null || echo "?")
echo " $ICON_SUCCESS PHP-FPM: running ($FPM_COUNT worker(s))"
else
echo " $ICON_ERROR PHP-FPM: NOT running"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━"
exit 0
fi
# ==============================================================================================
# ━━━ PHP-FPM Config ━━━
# ==============================================================================================
START=$(date +%s)
if [[ ! -f "$PHP_CONF" ]]; then
error "PHP config file not found: $PHP_CONF"
notify "PHP-FPM config not found on $(hostname) ($MY_ID) — $PHP_CONF missing" \
"PHP-FPM" "warning"
exit 1
fi
# ── Idempotent check ─────────────────────────────────────────────────────────────────────────
CURRENT_VAL=$(grep -E "^pm\.max_children" "$PHP_CONF" 2>/dev/null | awk '{print $NF}')
if [[ "${CURRENT_VAL:-0}" -eq "$PHP_MAX_CHILDREN" ]]; then
echo "pm.max_children already $PHP_MAX_CHILDREN"
exit 0
fi
warn "pm.max_children: ${CURRENT_VAL:-not set}$PHP_MAX_CHILDREN"
# ── Verify pattern exists before writing ─────────────────────────────────────────────────────
if ! grep -qE "^pm\.max_children" "$PHP_CONF" 2>/dev/null; then
error "pm.max_children not found in $PHP_CONF — cannot apply"
error "Add 'pm.max_children = $PHP_MAX_CHILDREN' to $PHP_CONF manually"
notify "PHP-FPM pm.max_children not found in config on $(hostname) ($MY_ID)" \
"PHP-FPM" "warning"
exit 1
fi
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would set pm.max_children = $PHP_MAX_CHILDREN in $PHP_CONF"
warn "DRY RUN — would restart PHP-FPM"
exit 0
fi
# ── Apply setting ─────────────────────────────────────────────────────────────────────────────
log "Applying pm.max_children = $PHP_MAX_CHILDREN..."
if ! sed -i "s/^pm\.max_children.*/pm.max_children = $PHP_MAX_CHILDREN/" "$PHP_CONF"; then
error "Failed to update $PHP_CONF"
notify "PHP-FPM config update failed on $(hostname) ($MY_ID)" \
"PHP-FPM" "warning"
exit 1
fi
log "Config updated"
# ── Restart PHP-FPM ──────────────────────────────────────────────────────────────────────────
log "Restarting PHP-FPM..."
if ! platform_restart_service php-fpm; then
error "PHP-FPM restart command failed"
notify "PHP-FPM restart failed on $(hostname) ($MY_ID)" \
"PHP-FPM" "warning"
exit 1
fi
sleep 3 # Allow PHP-FPM workers to initialise
# ── Verify process running ────────────────────────────────────────────────────────────────────
if ! pgrep -f "php-fpm" >/dev/null 2>&1; then
error "PHP-FPM not running after restart — WebGUI may be broken"
notify "PHP-FPM failed to start after config update on $(hostname) ($MY_ID)" \
"PHP-FPM" "warning"
exit 1
fi
# ── Verify config reflects target ────────────────────────────────────────────────────────────
APPLIED_VAL=$(grep -E "^pm\.max_children" "$PHP_CONF" 2>/dev/null | awk '{print $NF}')
if [[ "${APPLIED_VAL:-0}" -ne "$PHP_MAX_CHILDREN" ]]; then
warn "Config reads pm.max_children = ${APPLIED_VAL:-unknown} — expected $PHP_MAX_CHILDREN"
warn "Check $PHP_CONF manually"
else
log "Verified: pm.max_children = $APPLIED_VAL"
fi
FPM_WORKERS=$(pgrep -fc "php-fpm" 2>/dev/null || echo "?")
log "$ICON_PHP Workers running: $FPM_WORKERS"
END=$(date +%s)
# ==============================================================================================
# ━━━ Summary ━━━
# ==============================================================================================
echo ""
echo "━━━━━ $ICON_SUMMARY PHP-FPM SUMMARY ━━━━━"
echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)"
echo "$ICON_GEAR Config file: $PHP_CONF"
echo "$ICON_PHP Applied: pm.max_children = $PHP_MAX_CHILDREN"
echo "$ICON_TIME Duration: $(format_duration $(( END - START )))"
echo ""
echo "$ICON_DONE Status: done ✅"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 0