Varaverk: FallBack + Watchdog tabs; plugin path restructure to Plugin/unraid/

- FallBack tab: per-node tier inventory + active fallback card with duration, tier, handback strikes, running container status
- Watchdog tab: live system health (RAM bar + thresholds, load, uptime, daemon), docker watchdog strikes + skip list + restart history, stability strikes + reboot log, resource pressure alert card, config inventory (mem limits, required, pause/stop lists)
- Swapped partnership/arrs tab order; FallBack between partnership and watchdog
- Plugin source tree moved from Plugin/usr/local/emhttp/plugins/varaverk/ to Plugin/unraid/
- Deployment/ conf templates added
This commit is contained in:
Gmer4Lfe
2026-05-28 22:24:50 -04:00
parent 64d95aa991
commit fb051b60c1
73 changed files with 5896 additions and 462 deletions
+93
View File
@@ -0,0 +1,93 @@
<?php
// Config file parser and writer.
// Reads master.conf and the appropriate host*.conf based on running host.
define('PLUGIN_CFG', '/boot/config/plugins/varaverk/varaverk.cfg');
$_vv_cfg = @parse_ini_file(PLUGIN_CFG) ?: [];
define('SCRIPTS_DIR', $_vv_cfg['SCRIPTS_DIR'] ?? '/mnt/user/appdata/unraid_scripts');
define('CONF_DIR', SCRIPTS_DIR . '/Configurations');
define('LOG_DIR', '/var/log/varaverk');
unset($_vv_cfg);
function vv_get_hostname(): string {
return trim(shell_exec('hostname -s') ?: '');
}
// Mirror of common.sh resolve_tailscale_ip(): tries `tailscale ip -4` first (Tailscale manages
// the mapping so this survives IP changes), falls back to parsing `tailscale status` text.
function vv_resolve_tailscale_ip(string $hostname): string {
$h = strtolower($hostname);
$ip = trim(shell_exec('tailscale ip -4 ' . escapeshellarg($h) . ' 2>/dev/null') ?: '');
if ($ip) return $ip;
$out = shell_exec('tailscale status 2>/dev/null') ?: '';
foreach (explode("\n", $out) as $line) {
$cols = preg_split('/\s+/', trim($line));
if (isset($cols[1]) && stripos($cols[1], $h . '.') === 0) return $cols[0];
}
return '';
}
function vv_detect_host(): string {
// Reads master.conf for HOST1="name" (or HOST1_NAME="name") and matches running hostname.
// Returns 'host1', 'host2', 'host3', ... or 'unknown'. Works for any number of hosts.
$master = vv_read_conf_raw('master.conf');
preg_match_all('/^\s*(HOST\d+)(?:_NAME)?\s*=\s*["\']?(\S+?)["\']?\s*$/m', $master, $m);
$hostname = vv_get_hostname();
foreach ($m[1] as $i => $key) {
if (strcasecmp($hostname, trim($m[2][$i])) === 0) return strtolower($key);
}
return 'unknown';
}
function vv_is_owner(): bool {
return vv_detect_host() === 'host1';
}
function vv_read_conf_raw(string $filename): string {
$path = CONF_DIR . '/' . $filename;
return file_exists($path) ? file_get_contents($path) : '';
}
function vv_write_conf_raw(string $filename, string $content): bool {
$path = CONF_DIR . '/' . $filename;
return file_put_contents($path, $content) !== false;
}
function vv_get_conf_files(): array {
// Returns conf files this host is allowed to view/edit
$host = vv_detect_host();
$files = [];
if ($host === 'host1') {
// Owner sees master.conf + their own host conf
$files[] = 'master.conf';
$files[] = 'host1.conf';
} elseif (preg_match('/^host(\d+)$/', $host)) {
// Any other numbered host sees only their own conf
$files[] = $host . '.conf';
} else {
// Unknown host — show all for dev/debug
foreach (glob(CONF_DIR . '/*.conf') as $f) {
$files[] = basename($f);
}
}
return $files;
}
// Parse conf into key=>value map for $VAR substitution in docs
function vv_conf_vars(): array {
$vars = [];
$files = ['master.conf'];
$host = vv_detect_host();
if (preg_match('/^host\d+$/', $host)) $files[] = $host . '.conf';
foreach ($files as $f) {
$raw = vv_read_conf_raw($f);
// Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
foreach ($m[1] as $i => $key) {
$vars[$key] = trim($m[2][$i]);
}
}
return $vars;
}