Plugin lives in Plugin/ — invisible to User Script Plugin. dev_install.sh symlinks into /usr/local/emhttp/plugins/varaverk/ for development. Pages: Monitor (5s poll), Scheduler (orchs + Advanced children, toggle + cron), Config (raw editor, host-aware file access), Docs (markdown + live $VAR substitution). API endpoints: monitor.php (JSON), scheduler.php (writes schedule.json + cron.d), config.php (writes conf files with host permission check). Includes: config.php (parser, host detection, var map), scheduler.php (job tree, cron.d rebuild), monitor.php (docker, GPU, resources, fallback, transcode), docs.php (file tree, var substitution, Parsedown renderer).
122 lines
4.2 KiB
PHP
122 lines
4.2 KiB
PHP
<?php
|
|
// Monitor helpers — docker, GPU, resources, transcode sessions, fallback state.
|
|
|
|
function vv_docker_containers(): array {
|
|
$out = shell_exec('docker ps --format \'{"name":"{{.Names}}","status":"{{.Status}}","image":"{{.Image}}"}\' 2>/dev/null');
|
|
$containers = [];
|
|
foreach (explode("\n", trim($out ?? '')) as $line) {
|
|
if (!$line) continue;
|
|
$c = json_decode($line, true);
|
|
if ($c) $containers[] = $c;
|
|
}
|
|
return $containers;
|
|
}
|
|
|
|
function vv_docker_stopped(): array {
|
|
$out = shell_exec('docker ps -a --filter "status=exited" --filter "status=created" --format \'{"name":"{{.Names}}","status":"{{.Status}}"}\' 2>/dev/null');
|
|
$containers = [];
|
|
foreach (explode("\n", trim($out ?? '')) as $line) {
|
|
if (!$line) continue;
|
|
$c = json_decode($line, true);
|
|
if ($c) $containers[] = $c;
|
|
}
|
|
return $containers;
|
|
}
|
|
|
|
function vv_gpu_stats(): array {
|
|
$out = shell_exec('nvidia-smi --query-gpu=name,memory.used,memory.total,utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null');
|
|
if (!$out) return ['available' => false];
|
|
|
|
$parts = array_map('trim', explode(',', $out));
|
|
return [
|
|
'available' => true,
|
|
'name' => $parts[0] ?? '',
|
|
'memory_used' => (int)($parts[1] ?? 0),
|
|
'memory_total' => (int)($parts[2] ?? 0),
|
|
'utilization' => (int)($parts[3] ?? 0),
|
|
'temperature' => (int)($parts[4] ?? 0),
|
|
];
|
|
}
|
|
|
|
function vv_gpu_processes(): array {
|
|
$out = shell_exec('nvidia-smi --query-compute-apps=pid,used_gpu_memory,name --format=csv,noheader,nounits 2>/dev/null');
|
|
$procs = [];
|
|
foreach (explode("\n", trim($out ?? '')) as $line) {
|
|
if (!$line) continue;
|
|
$parts = array_map('trim', explode(',', $line));
|
|
$procs[] = [
|
|
'pid' => $parts[0] ?? '',
|
|
'memory_mb' => $parts[1] ?? '',
|
|
'name' => $parts[2] ?? '',
|
|
];
|
|
}
|
|
return $procs;
|
|
}
|
|
|
|
function vv_system_resources(): array {
|
|
// RAM
|
|
$mem = [];
|
|
foreach (file('/proc/meminfo') ?: [] as $line) {
|
|
if (preg_match('/^(MemTotal|MemAvailable):\s+(\d+)/', $line, $m))
|
|
$mem[$m[1]] = (int)$m[2];
|
|
}
|
|
|
|
// CPU (1-second sample)
|
|
$cpu = (int)trim(shell_exec("top -bn1 | grep 'Cpu(s)' | awk '{print $2}' | cut -d. -f1") ?: '0');
|
|
|
|
// Disk — ramdisk + cache
|
|
$ramdisk = vv_df('/mnt/ramdisk_transcodes');
|
|
$cache = vv_df('/mnt/cache');
|
|
|
|
return [
|
|
'ram_total_mb' => (int)(($mem['MemTotal'] ?? 0) / 1024),
|
|
'ram_free_mb' => (int)(($mem['MemAvailable'] ?? 0) / 1024),
|
|
'cpu_percent' => $cpu,
|
|
'ramdisk' => $ramdisk,
|
|
'cache' => $cache,
|
|
];
|
|
}
|
|
|
|
function vv_df(string $path): array {
|
|
$out = shell_exec("df -BM --output=size,used,avail '$path' 2>/dev/null | tail -1");
|
|
if (!$out) return ['available' => false, 'path' => $path];
|
|
$parts = preg_split('/\s+/', trim($out));
|
|
return [
|
|
'available' => true,
|
|
'path' => $path,
|
|
'size_mb' => (int)$parts[0],
|
|
'used_mb' => (int)$parts[1],
|
|
'free_mb' => (int)$parts[2],
|
|
];
|
|
}
|
|
|
|
function vv_fallback_state(): array {
|
|
// State file written by fallback.sh
|
|
$stateFile = '/tmp/fallback_state.db';
|
|
if (!file_exists($stateFile)) return ['state' => 'UNKNOWN'];
|
|
$raw = [];
|
|
foreach (file($stateFile) ?: [] as $line) {
|
|
[$k, $v] = array_pad(explode('=', trim($line), 2), 2, '');
|
|
$raw[trim($k)] = trim($v);
|
|
}
|
|
return [
|
|
'state' => $raw['state'] ?? 'UNKNOWN',
|
|
'failover_start' => $raw['failover_start'] ?? '0',
|
|
'tier2_started' => $raw['tier2_started'] ?? 'false',
|
|
'tier3_started' => $raw['tier3_started'] ?? 'false',
|
|
'tier4_started' => $raw['tier4_started'] ?? 'false',
|
|
];
|
|
}
|
|
|
|
function vv_transcode_sessions(): array {
|
|
// Read from transcode state file written by transcode_manager.sh
|
|
$stateFile = '/tmp/transcode_state.db';
|
|
if (!file_exists($stateFile)) return [];
|
|
$raw = [];
|
|
foreach (file($stateFile) ?: [] as $line) {
|
|
[$k, $v] = array_pad(explode('=', trim($line), 2), 2, '');
|
|
$raw[trim($k)] = trim($v);
|
|
}
|
|
return $raw;
|
|
}
|