From 387382ec9f5eeb05ce145278c2375993d15e1ade Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Fri, 21 Aug 2026 22:50:09 -0400 Subject: [PATCH] Media Stack called every node local, and a host whose watchdogs never ran reported all clear --- Plugin/unraid/include/arrs.php | 6 ++++++ Plugin/unraid/include/monitor.php | 19 +++++++++++++++++++ Plugin/unraid/pages/monitor.php | 14 +++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Plugin/unraid/include/arrs.php b/Plugin/unraid/include/arrs.php index 9598df3..5453d84 100644 --- a/Plugin/unraid/include/arrs.php +++ b/Plugin/unraid/include/arrs.php @@ -460,6 +460,12 @@ function vv_arrs_all(): array { $cacheFile = VV_CACHE_DIR . '/arrs_remote_' . $h . '.json'; if (file_exists($cacheFile)) { $node = json_decode(file_get_contents($cacheFile), true) ?: []; + // The cache file was written by vv_arrs_local_node() ON THAT HOST, where the node is by + // definition local — so it arrives claiming 'local' => true and, re-emitted verbatim, + // made every node on every host report as this one. Ownership is decided here, by who + // is reading the file, not by who wrote it. + $node['local'] = false; + $node['host'] = $h; $node['cached'] = true; $node['cache_age'] = time() - (int)filemtime($cacheFile); $result[] = $node; diff --git a/Plugin/unraid/include/monitor.php b/Plugin/unraid/include/monitor.php index f312e21..8f86781 100644 --- a/Plugin/unraid/include/monitor.php +++ b/Plugin/unraid/include/monitor.php @@ -310,8 +310,27 @@ function vv_watchdog_summary(): array { && $rwLevel === 0 && $daemonStrikes === 0 && $oomCount === 0 && $reboots === 0 && $npmStrikes === 0 && $nicState === 'up' && $sshdOk; + // "No strikes" and "never ran" are not the same fact. Every strike file read above defaults an + // absent file to zero, so a host where the watchdogs have never executed reports exactly like + // one they just swept clean — a green card standing in for no information at all. HOST2 showed + // that green for four days on a STATE_DIR holding no watchdog file whatsoever, because its + // schedule.json never had the orchestrator enabled. + // + // $healthy stays a verdict about strikes; the caller is told separately whether there was + // anything to form a verdict from. + $lastRun = 0; + foreach ([ + 'watchdog_orch_hb.count', 'container_watchdog_state.db', 'resource_watchdog_state.db', + 'system_watchdog_state.db', 'storage_watchdog_state.db', 'network_watchdog_state.db', + ] as $f) { + $p = STATE_DIR . '/' . $f; + if (is_file($p)) $lastRun = max($lastRun, (int)@filemtime($p)); + } + return [ 'healthy' => $healthy, + 'last_run' => $lastRun ?: null, + 'never_ran' => $lastRun === 0, 'ctr_strikes' => $ctrStrikes, 'rw_level' => $rwLevel, 'rw_paused' => array_values(array_filter(explode(',', $rw['rm_paused_containers'] ?? ''))), diff --git a/Plugin/unraid/pages/monitor.php b/Plugin/unraid/pages/monitor.php index 23c5871..22f803a 100644 --- a/Plugin/unraid/pages/monitor.php +++ b/Plugin/unraid/pages/monitor.php @@ -1476,8 +1476,16 @@ function vvPollMonitor(live) { const issueCount = ctrNames.length + stabNames.length + storIssues + (daemonHit ? 1 : 0) + (oom > 0 ? 1 : 0) + (reboots > 0 ? 1 : 0) + (npmStrikes > 0 ? 1 : 0); - const bannerCls = healthy ? 'vv-banner-ok' : (reboots || oom || daemonHit ? 'vv-banner-err' : 'vv-banner-warn'); - const bannerTxt = healthy ? '✓ All clear' : `⚠ ${issueCount} issue${issueCount !== 1 ? 's' : ''}`; + // A host whose watchdogs have never executed has no verdict to report. Every strike set + // reads absent state as zero, so "All clear" here would be standing in for no data — + // which is the failure this card's own header warns about. Said plainly instead. + const neverRan = wd.never_ran === true; + const bannerCls = neverRan ? 'vv-banner-warn' + : healthy ? 'vv-banner-ok' + : (reboots || oom || daemonHit ? 'vv-banner-err' : 'vv-banner-warn'); + const bannerTxt = neverRan ? '○ Never run on this host' + : healthy ? '✓ All clear' + : `⚠ ${issueCount} issue${issueCount !== 1 ? 's' : ''}`; let html = `
${bannerTxt}`; if (reboots > 0) html += `${reboots} reboot${reboots !== 1 ? 's' : ''}/12h`; @@ -1601,7 +1609,7 @@ function vvPollMonitor(live) { const wdCard = document.getElementById('vv-watchdog-card'); if (wdCard) { wdCard.classList.remove('vv-accent-ok','vv-accent-warn','vv-accent-err'); - if (healthy) wdCard.classList.add('vv-accent-ok'); + if (healthy && !neverRan) wdCard.classList.add('vv-accent-ok'); else if (reboots > 0 || oom > 0 || daemonHit) wdCard.classList.add('vv-accent-err'); else wdCard.classList.add('vv-accent-warn'); }