From 9145a66cef33ea2eb5ccaeb30bcbc9bfacf70182 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Thu, 6 Aug 2026 22:24:30 -0400 Subject: [PATCH] Surface server_reboot.sh on the Tools card without moving it out of the shutdown chain it belongs to --- Plugin/unraid/include/scheduler.php | 43 +++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/Plugin/unraid/include/scheduler.php b/Plugin/unraid/include/scheduler.php index 539db26..ff094ed 100644 --- a/Plugin/unraid/include/scheduler.php +++ b/Plugin/unraid/include/scheduler.php @@ -308,23 +308,37 @@ function vv_tools_scripts(): array { // Background writers managed automatically — not user-facing tools static $EXCLUDE = ['api_cache_writer.sh', 'remote_arr_cache_writer.sh']; + // Scripts that live outside Tools/ but are run by hand often enough to belong on the card. + // Named individually rather than by adopting their folder: System_Essentials also holds + // conf_sync, rsync_stop and the rest of the shutdown chain, and putting those in front of the + // operator as ordinary tools misrepresents what they are. + // + // server_reboot.sh stays where it is because it is not a standalone utility — it is the head + // of the clean-shutdown sequence, calling array_stopping.sh, mover_stop.sh and + // user_scripts_stop.sh in order, and the System_Essentials documentation describes it as that + // chain. Moving the file to match the UI would break the grouping that explains it. + static $ADOPTED = ['System_Essentials/server_reboot.sh']; + $schedule = vv_schedule_load(); $scripts = []; - $collect = function(string $dir, string $relPrefix) use ($schedule, $EXCLUDE, &$scripts): void { + $entryFor = function(string $path, string $rel) use ($schedule): array { + $entry = $schedule[$rel] ?? []; + return [ + 'id' => $rel, + 'label' => vv_pretty_label(basename($path, '.sh')), + 'desc' => vv_script_description($path), + 'enabled' => (bool)($entry['enabled'] ?? false), + 'cron' => $entry['cron'] ?? '', + 'log_enabled' => (bool)($entry['log_enabled'] ?? false), + ]; + }; + + $collect = function(string $dir, string $relPrefix) use ($EXCLUDE, $entryFor, &$scripts): void { foreach (glob("$dir/*.sh") ?: [] as $path) { $base = basename($path); if (in_array($base, $EXCLUDE, true)) continue; - $rel = $relPrefix . $base; - $entry = $schedule[$rel] ?? []; - $scripts[] = [ - 'id' => $rel, - 'label' => vv_pretty_label(basename($path, '.sh')), - 'desc' => vv_script_description($path), - 'enabled' => (bool)($entry['enabled'] ?? false), - 'cron' => $entry['cron'] ?? '', - 'log_enabled' => (bool)($entry['log_enabled'] ?? false), - ]; + $scripts[] = $entryFor($path, $relPrefix . $base); } }; @@ -337,6 +351,13 @@ function vv_tools_scripts(): array { $collect($toolsDir, "Plugin/$platform/Tools/"); } + // Adopted individually. Skipped silently when absent so a host without the script — or a + // sparse checkout that never pulled it — shows one fewer tool rather than a broken row. + foreach ($ADOPTED as $rel) { + $path = SCRIPTS_DIR . '/' . $rel; + if (is_file($path)) $scripts[] = $entryFor($path, $rel); + } + usort($scripts, fn($a, $b) => strcmp($a['label'], $b['label'])); return $scripts; }