From bf7a2cc9115a6fa1fbdc4d31847f254df239e26d Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Thu, 6 Aug 2026 23:16:28 -0400 Subject: [PATCH] Point scripts at the shared host sections, and fix the two reasons those sections could never be found --- Plugin/unraid/include/confform.php | 75 +++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/Plugin/unraid/include/confform.php b/Plugin/unraid/include/confform.php index de4056e..655fb50 100644 --- a/Plugin/unraid/include/confform.php +++ b/Plugin/unraid/include/confform.php @@ -63,24 +63,24 @@ const VV_SCRIPT_CONF_SECTIONS = [ 'Docker_Essentials/downloaders_reset.sh' => ['Downloaders Reset', 'Downloaders'], // Watchdogs 'Watchdogs/docker_watchdog.sh' => ['Docker Watchdog'], - 'Watchdogs/resource_watchdog.sh' => ['Pressure Thresholds'], + 'Watchdogs/resource_watchdog.sh' => ['Pressure Thresholds', 'Downloaders', 'SABnzbd Throttle', 'qBittorrent Throttle'], 'Watchdogs/System/network_watchdog.sh' => ['Network Watchdog'], 'Plugin/unraid/Watchdogs/System/webgui_watchdog.sh' => ['WebGUI Watchdog'], // Media 'Media/media_cleaner.sh' => ['Media Cleaner'], 'Media/media_shares_permissions.sh' => ['Media Permissions'], // Arrs Stack - 'Arrs_Stack/radarr_cleanup.sh' => ['Arr Cleanup'], - 'Arrs_Stack/lidarr_cleanup.sh' => ['Arr Cleanup'], - 'Arrs_Stack/sonarr_cleanup.sh' => ['Arr Cleanup'], + 'Arrs_Stack/radarr_cleanup.sh' => ['Arr Cleanup', 'Radarr'], + 'Arrs_Stack/lidarr_cleanup.sh' => ['Arr Cleanup', 'Lidarr'], + 'Arrs_Stack/sonarr_cleanup.sh' => ['Arr Cleanup', 'Sonarr'], // Monitors 'Monitors/cert_monitor.sh' => ['Certificate Monitor'], 'Monitors/backup_verify.sh' => ['Backup Verify'], 'Monitors/smart_health.sh' => ['SMART Health'], 'Monitors/bandwidth_monitor.sh' => ['Bandwidth Monitor'], - 'Monitors/emby_session_report.sh' => ['Emby Session Report'], + 'Monitors/emby_session_report.sh' => ['Emby Session Report', 'Emby'], 'Monitors/zfs_memory_snapshot.sh' => ['ZFS Report', 'ZFS Memory Snapshot'], - 'Monitors/weekly_health_digest.sh' => ['Health Digest'], + 'Monitors/weekly_health_digest.sh' => ['Health Digest', 'Certificate Monitor'], 'Monitors/system_tuning_monitor.sh' => ['System Tuning Monitor'], // ── Added after auditing the conf against this map ──────────────────────────────────────── // 99 named subsections existed; 35 were reachable. The rest were configured and documented in @@ -89,8 +89,8 @@ const VV_SCRIPT_CONF_SECTIONS = [ // unambiguously belong to one script are listed: a wrong mapping puts someone else's settings // under a script and is worse than the gap it closes. 'Arrs_Stack/arr_download_orphan_cleaner.sh' => ['Download Orphan Cleaner (arr_download_orphan_cleaner.sh)'], - 'Arrs_Stack/radarr_classification_scan.sh' => ['Arr Content Classification (radarr/sonarr_classification_scan.sh)'], - 'Arrs_Stack/sonarr_classification_scan.sh' => ['Arr Content Classification (radarr/sonarr_classification_scan.sh)'], + 'Arrs_Stack/radarr_classification_scan.sh' => ['Arr Content Classification (radarr/sonarr_classification_scan.sh)', 'Radarr'], + 'Arrs_Stack/sonarr_classification_scan.sh' => ['Arr Content Classification (radarr/sonarr_classification_scan.sh)', 'Sonarr'], 'Arrs_Stack/arr_full_rescan.sh' => ['Arr Full Library Rescan'], 'Arrs_Stack/arr_corruption_scan.sh' => ['Corruption Scan'], 'Arrs_Stack/arrs_failed_stalled_recovery.sh' => ['Arr Failed/Stalled Recovery', 'Arr Recovery Toggles'], @@ -99,7 +99,7 @@ const VV_SCRIPT_CONF_SECTIONS = [ 'Fallback/fallback_test.sh' => ['Failover Test'], 'Rsync/rsync.sh' => ['Rsync Enable/Disable', 'Rsync Defaults', 'Rsync Profile System', 'Rsync Merge Auto-Promote'], - 'System_Essentials/server_reboot.sh' => ['Reboot'], + 'System_Essentials/server_reboot.sh' => ['Reboot', 'Emby'], 'System_Essentials/clear_logs.sh' => ['Clear Logs'], 'System_Essentials/inotify_tuning.sh' => ['inotify Tuning'], 'System_Essentials/docker_syslog_filter.sh' => ['Syslog Filter'], @@ -107,9 +107,39 @@ const VV_SCRIPT_CONF_SECTIONS = [ 'Plugin/unraid/System_Essentials/php_fpm_max_children.sh' => ['PHP-FPM'], 'Watchdogs/stability_watchdog.sh' => ['Strike and Reboot Loop Settings', 'RAM Reboot Threshold', 'OOM Bypass Settings'], - 'AI/ai_index.sh' => ['AI Retrieval Index', 'AI Master Switch'], - 'AI/ai_query.sh' => ['AI Retrieval Index', 'AI Master Switch'], + 'AI/ai_index.sh' => ['AI Retrieval Index', 'AI Master Switch', 'Ollama'], + 'AI/ai_query.sh' => ['AI Retrieval Index', 'AI Master Switch', 'Ollama'], 'AI/ai_token_sync.sh' => ['AI Feature Toggles'], + // ── Shared host sections ────────────────────────────────────────────────────────────────── + // A script's settings are not only the ones named after it. Anything talking to Lidarr reads + // the host's Lidarr block; anything reading playback reads Emby. Those blocks are where the + // URL and API key actually live, so a script that could not work without them was showing a + // Config form that omitted the very settings most likely to be wrong. + // + // Several scripts pointing at one section is intended, not duplication — the arr cleanups + // already shared 'Arr Cleanup' this way. Writes are confined to the parsed line range, so a + // section edited from two places still edits the same lines. + 'Arrs_Stack/lidarr_missing_art.sh' => ['Lidarr'], + 'Arrs_Stack/lidarr_release_fixer.sh' => ['Lidarr'], + 'Arrs_Stack/lidarr_duplicate_artist_cleanup.sh' => ['Lidarr'], + 'Arrs_Stack/playback_aware_lidarr_discovery.sh' => ['Lidarr', 'Emby'], + 'Arrs_Stack/playback_aware_radarr_discovery.sh' => ['Radarr', 'Emby'], + 'Arrs_Stack/playback_aware_sonarr_discovery.sh' => ['Sonarr', 'Emby'], + 'Arrs_Stack/radarr_tmdb_removed.sh' => ['Radarr'], + 'Arrs_Stack/sonarr_tvdb_removed.sh' => ['Sonarr'], + 'Tools/emby_to_lidarr_sync.sh' => ['Emby', 'Lidarr'], + 'Tools/emby_to_radarr_sync.sh' => ['Emby', 'Radarr'], + 'Tools/emby_to_sonarr_sync.sh' => ['Emby', 'Sonarr'], + 'Tools/emby_database_repair.sh' => ['Emby'], + 'Tools/bulk_permissions_repair.sh' => ['Media Permissions'], + 'Tools/trailer_folder_migration.sh' => ['Media Permissions'], + 'Transcodes/transcode_manager.sh' => ['Transcode Manager', 'Transcode Server Array'], + // fallback.sh owns the whole failover surface: which tiers it covers, how long it waits, what + // it does to DDNS, and what it hands back. All four sections are its configuration. + 'Fallback/fallback.sh' => ['Fallback Tiers — What HOSTN Wants Covered When Down', + 'Tier Delays — HOSTN Outage Timers', + 'Internet Loss', 'DDNS', + 'Play State Sync — Handback'], ]; function vv_conf_has_sections(string $id): bool { @@ -122,13 +152,24 @@ function vv_conf_has_sections(string $id): bool { function vv_conf_parse_subsection(string $raw, string $subName, string $filename): ?array { $lines = explode("\n", $raw); $n = count($lines); - $needle = mb_strtolower(trim(preg_replace('/\s+/', ' ', $subName))); + // Host slot normalised on both sides. Section titles carry the host they belong to — the + // template ships "Tier Delays — HOSTN Outage Timers" and conf_upgrade substitutes it to HOST1 + // or HOST2 per machine — so a literal name in the map can only ever match one host, and on + // the other it silently finds nothing. Folding HOST back to HOSTN makes one entry correct + // everywhere, which matters because this map is shared code and the conf files are not. + $slot = fn(string $s): string + => preg_replace('/\bhost\d+\b/', 'hostn', mb_strtolower(trim(preg_replace('/\s+/', ' ', $s)))); + $needle = $slot($subName); $start = -1; + // /u is load-bearing, not tidiness. Without it the character class matches BYTES, and an + // em-dash (E2 80 94) is built entirely from bytes that also appear in ━ and ─. So a name + // containing one terminated early: "Tier Delays — HOSTN Outage Timers" captured as "Tier + // Delays", matched nothing, and every section with a dash in its title was unreachable — + // silently, because an unfound section is defined to return no fields. for ($i = 0; $i < $n; $i++) { - if (!preg_match('/^#\s*[━─]{2,}\s+([A-Za-z].+?)\s+[━─]{2,}/', $lines[$i], $m)) continue; - $t = mb_strtolower(trim(preg_replace('/\s+/', ' ', $m[1]))); - if ($t === $needle) { $start = $i + 1; break; } + if (!preg_match('/^#\s*[━─]{2,}\s+([A-Za-z].+?)\s+[━─]{2,}/u', $lines[$i], $m)) continue; + if ($slot($m[1]) === $needle) { $start = $i + 1; break; } } if ($start === -1) return null; @@ -230,7 +271,9 @@ function vv_conf_all_groups(string $filename): array { $headers = []; for ($i = 0; $i < $n; $i++) { - if (preg_match('/^#\s*[━─]{2,}\s+([A-Za-z].+?)\s+[━─]{2,}/', $lines[$i], $m)) { + // /u for the same reason as the locator above: without it a name containing an em-dash is + // truncated at the dash, and the full-settings view labels the group with half its title. + if (preg_match('/^#\s*[━─]{2,}\s+([A-Za-z].+?)\s+[━─]{2,}/u', $lines[$i], $m)) { $headers[] = ['name' => trim(preg_replace('/\s+/', ' ', $m[1])), 'line' => $i]; } }