Put everything Varaverk persists under one root, state included

This commit is contained in:
Gmer4Lfe
2026-08-08 23:26:46 -04:00
parent d5c36db531
commit f1603349cc
11 changed files with 420 additions and 77 deletions
+43 -19
View File
@@ -95,22 +95,36 @@ function vv_wd_parse_kv(string $text): array {
return $out;
}
// Restart log: "container|timestamp" one per line
// Restart log: "container|2026-08-02 13:15:07" one per line.
//
// The second field is a formatted local timestamp, not an epoch — docker_watchdog.sh writes it
// with date '+%Y-%m-%d %H:%M:%S' because its own rolling-window trim compares the strings
// lexically in awk, which is correct for that format. This function used to cast it with (int),
// which stops at the first non-digit and yielded 2026 for every line ever written. 2026 is below
// any plausible cutoff, so every entry was discarded and both restart panels — the Monitor card
// and the Watchdog page — were permanently empty. Not visibly broken: an empty list reads
// exactly like "nothing has restarted", which is the answer you least want to be wrong about
// during a restart loop.
//
// Parsed, not reformatted. Changing what the watchdog writes would strand every existing entry
// and every awk comparison in Tools/watchdog_skip_list_manager.sh.
function vv_wd_parse_restart_log(string $text, int $windowSeconds = 86400): array {
$now = time();
$cutoff = $now - $windowSeconds;
$cutoff = time() - $windowSeconds;
$entries = [];
foreach (explode("\n", trim($text)) as $line) {
$line = trim($line);
if (!$line || !str_contains($line, '|')) continue;
[$name, $ts] = explode('|', $line, 2);
$ts = (int)$ts;
[$name, $raw] = explode('|', $line, 2);
$ts = vv_wd_restart_ts(trim($raw));
if ($ts >= $cutoff) $entries[] = ['name' => trim($name), 'ts' => $ts];
}
usort($entries, fn($a, $b) => $b['ts'] - $a['ts']);
return $entries;
}
// vv_wd_restart_ts() lives in common.php — include/monitor.php parses the same file and does not
// include this one, so a helper defined here would be a fatal on the dashboard.
// Skip list: one container name per line
function vv_wd_parse_skiplist(string $text): array {
return array_values(array_filter(array_map('trim', explode("\n", $text))));
@@ -239,28 +253,38 @@ function vv_wd_remote_data(string $ip, string $sshKey, string $restartLogPath):
// /proc/meminfo is passed as a raw section (not awk-parsed) to avoid quoting
// fragility — escapeshellarg() single-quotes the whole command so awk \$2
// inside double-quotes is unreliable across Unraid builds.
// State files live under the REMOTE's own SCRIPTS_DIR/State_Files (may differ
// from ours in flash mode) — resolve it once, same idiom as vv_remote_state_cmd().
// State files live under the REMOTE's own SCRIPTS_DIR (may differ from ours in flash mode),
// so it is resolved on the far side — same idiom as vv_remote_state_cmd().
//
// The layout is probed rather than assumed. State moved from SCRIPTS_DIR/State_Files to
// DATA_DIR/state, and the histories from DATA_DIR's root into DATA_DIR/db, but a partner is
// not guaranteed to have pulled that yet — and this is the call that reports whether the
// partner's watchdogs are healthy. Guessing wrong returns empty strings for every state
// file, which reads as "partner has no strikes" rather than as an error. Probing costs one
// directory test and makes the answer correct in both directions, which also means the two
// hosts can be upgraded in either order.
$restartLogName = basename($restartLogPath);
$cmd = 'sd=$(grep -m1 SCRIPTS_DIR= /boot/config/plugins/varaverk/varaverk.cfg 2>/dev/null'
. ' | cut -d\'"\' -f2); sd="${sd:-/boot/config/plugins/varaverk}"; '
. 'sf="$sd/data/state"; [ -d "$sf" ] || sf="$sd/State_Files"; '
. 'db="$sd/data/db"; [ -d "$db" ] || db="$sd/data"; '
. "printf 'UPTIME:%s\nLOAD:%s\nCORES:%s\nDAEMON:%s\nOOM:%s\nBASELINECOUNT:%s\nBASELINEAGE:%s\n---MEMINFO---\n%s\n---RW---\n%s\n---DOCK---\n%s\n---SKIP---\n%s\n---SYS---\n%s\n---REBOOT---\n%s\n---RESTART---\n%s\n---STORAGE---\n%s\n---NETWORK---\n%s\n' "
. '"$(cat /proc/uptime|cut -d\" \" -f1)" '
. '"$(cat /proc/loadavg|cut -d\" \" -f1)" '
. '"$(nproc)" '
. '"$(docker info >/dev/null 2>&1 && echo ok || echo err)" '
. '"$(cat "$sd/State_Files/system_watchdog_oom.db" 2>/dev/null||echo 0)" '
. '"$(wc -l < "$sd/State_Files/watchdog_appdata_growth.db" 2>/dev/null||echo 0)" '
. '"$(stat -c %Y "$sd/State_Files/watchdog_appdata_growth.db" 2>/dev/null||echo 0)" '
. '"$(cat "$sf/system_watchdog_oom.db" 2>/dev/null||echo 0)" '
. '"$(wc -l < "$sf/watchdog_appdata_growth.db" 2>/dev/null||echo 0)" '
. '"$(stat -c %Y "$sf/watchdog_appdata_growth.db" 2>/dev/null||echo 0)" '
. '"$(cat /proc/meminfo 2>/dev/null)" '
. '"$(cat "$sd/State_Files/resource_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sd/State_Files/container_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sd/State_Files/docker_watchdog_failed.db" 2>/dev/null)" '
. '"$(cat "$sd/State_Files/system_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sd/State_Files/system_watchdog_reboots.db" 2>/dev/null)" '
. '"$(cat "$sd/data/' . $restartLogName . '" 2>/dev/null)" '
. '"$(cat "$sd/State_Files/storage_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sd/State_Files/network_watchdog_state.db" 2>/dev/null)"';
. '"$(cat "$sf/resource_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sf/container_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sf/docker_watchdog_failed.db" 2>/dev/null)" '
. '"$(cat "$sf/system_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sf/system_watchdog_reboots.db" 2>/dev/null)" '
. '"$(cat "$db/' . $restartLogName . '" 2>/dev/null)" '
. '"$(cat "$sf/storage_watchdog_state.db" 2>/dev/null)" '
. '"$(cat "$sf/network_watchdog_state.db" 2>/dev/null)"';
$out = vv_pt_ssh($ip, $sshKey, $cmd, 8);
if (!$out) return null;
@@ -366,7 +390,7 @@ function vv_wd_all(): array {
$currentHost = vv_detect_host();
$tsPeers = vv_pt_ts_peers();
$masterRaw = vv_read_conf_raw('master.conf');
$restartLog = DATA_DIR . '/container_restart_history.db';
$restartLog = DB_DIR . '/container_restart_history.db';
// Config thresholds from master.conf
$cfg = [