Files
Varaverk/Plugin/unraid/api/rsync.php
T
Gmer4Lfe f7fa75fdfb Fix dead/incorrect vars in Plugin/ found during full codebase audit
- WEBGUI_PHP_WAIT was referenced by webgui_watchdog.sh but never defined
  in master.conf, always silently falling back to a hardcoded default
- arrs.php/confform.php still pointed at Media/ for arr cleanup/discovery
  scripts moved to Arrs_Stack/ in b4bc926 — broke the Arrs page's stats
  and the per-script settings editor for those scripts
- docker_folders.php read directly from the optional folder.view3 plugin's
  file instead of Varaverk's own docker_folders.json (the primary store
  since the Docker tab got its own config) — left the Monitor page's
  Docker Folders widget empty on any host without folder.view3 installed
- vv_wd_remote_data() read remote watchdog state files from hardcoded
  /tmp or /boot/config paths instead of the remote's actual STATE_DIR
  (which resolves dynamically and can differ under flash mode) — remote
  node's Watchdog panel was always empty; same wrong path also used for
  two local reads (system_watchdog_oom.db, watchdog_appdata_growth.db)
- rsync.php referenced a {HOST}_MONTHLY_SYNC_SHARES conf var that never
  existed (monthly_maintenance.sh has no rsync section) — nulled out to
  match the existing pattern used for the fallback window
- vv_arr_node_names() did a pointless identity array_map
- vv_dk_webui() had its own duplicate local-IP resolution instead of
  using vv_local_ip(), despite config.php's comment claiming that exact
  duplication was already consolidated
2026-07-04 23:00:26 -04:00

114 lines
4.5 KiB
PHP

<?php
header('Content-Type: application/json');
require_once dirname(__DIR__) . '/include/config.php';
require_once dirname(__DIR__) . '/include/monitor.php';
// ── Live sync log ─────────────────────────────────────────────────────────────
$action = $_GET['action'] ?? '';
if ($action === 'rsync_log') {
$lockDir = '/tmp/unraid_locks';
$lines = [];
$profile = null;
$live = false;
$elapsed = 0;
// Active sync — read live log
foreach (glob("$lockDir/rsync_*.lock") ?: [] as $lf) {
$content = trim(@file_get_contents($lf) ?: '');
[$pid, $locked_name] = array_pad(explode(':', $content, 2), 2, '');
if (!$pid || !file_exists("/proc/$pid")) continue;
$profile = preg_replace('/^rsync_/', '', $locked_name ?: basename($lf, '.lock'));
$elapsed = time() - (int)filemtime($lf);
$liveLog = "$lockDir/rsync_{$profile}.log";
$raw = file_exists($liveLog) ? (file($liveLog, FILE_IGNORE_NEW_LINES) ?: []) : [];
$live = true;
$lines = $raw;
break;
}
// No active sync — use most recent last.log
if (!$live) {
$lastLogs = glob("$lockDir/rsync_*.last.log") ?: [];
if ($lastLogs) {
usort($lastLogs, fn($a, $b) => filemtime($b) <=> filemtime($a));
$lastLog = $lastLogs[0];
$profile = preg_replace('/^rsync_(.+)\.last\.log$/', '$1', basename($lastLog));
$lines = file($lastLog, FILE_IGNORE_NEW_LINES) ?: [];
}
}
// Strip ANSI escape codes, keep last 200 lines
$lines = array_map(fn($l) => preg_replace('/\x1b\[[0-9;]*[mGKHF]/', '', $l), $lines);
$lines = array_slice($lines, -200);
echo json_encode(['ok' => true, 'live' => $live, 'profile' => $profile, 'elapsed' => $elapsed, 'lines' => array_values($lines)]);
exit;
}
$base = vv_rsync_status();
$vars = vv_conf_vars();
$base['windows']['fallback'] = ($vars['FALLBACK_RSYNC_ENABLED'] ?? 'true') !== 'false';
$base['windows']['monthly'] = ($vars['MONTHLY_RSYNC_ENABLED'] ?? 'true') !== 'false';
// Bandwidth history — last 30 days
$bwLog = DATA_DIR . '/bandwidth_history.db';
$warnGb = (float)($vars['BANDWIDTH_WARN_GB'] ?? 50);
$cutoff = date('Y-m-d', strtotime('-30 days'));
$history = [];
if (file_exists($bwLog)) {
foreach (file($bwLog, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $line) {
$p = explode('|', $line);
if (count($p) < 5) continue;
if ($p[0] < $cutoff) continue;
$history[] = [
'date' => $p[0],
'time' => $p[1],
'profile' => $p[2],
'duration' => (int)$p[3],
'status' => trim($p[4]),
'bytes' => isset($p[5]) ? (int)$p[5] : 0,
];
}
}
// Per-window orch arrays (scripts + sync shares)
$masterRaw = vv_read_conf_raw('master.conf');
$myId = strtoupper(vv_detect_host());
$hostRaw = vv_read_conf_raw(vv_detect_host() . '.conf');
$winArrayDefs = [
'critical' => ['CRITICAL_MAINTENANCE_SCRIPTS', "{$myId}_CRITICAL_SYNC_SHARES"],
'intermediate' => ['INTERMEDIATE_MAINTENANCE_SCRIPTS', "{$myId}_INTERMEDIATE_SYNC_SHARES"],
'daily' => ['DAILY_MAINTENANCE_SCRIPTS', "{$myId}_DAILY_SYNC_SHARES"],
'weekly' => ['WEEKLY_MAINTENANCE_SCRIPTS', "{$myId}_WEEKLY_SYNC_SHARES"],
// monthly_maintenance.sh has no rsync section (ZFS scrub/SMART tests only) — no shares var exists.
'monthly' => ['MONTHLY_MAINTENANCE_SCRIPTS', null],
'fallback' => [null, null],
];
$winArrays = [];
foreach ($winArrayDefs as $win => [$sv, $shv]) {
$winArrays[$win] = [
'scripts' => $sv ? vv_parse_bash_array($masterRaw, $sv) : [],
'shares' => $shv ? vv_parse_bash_array($hostRaw, $shv) : [],
];
}
echo json_encode([
'enabled' => $base['enabled'],
'windows' => $base['windows'],
'active' => $base['active'],
'last_sync' => $base['last_sync'],
'bw_history' => $history,
'bw_warn_gb' => $warnGb,
'win_arrays' => $winArrays,
'settings' => [
'bw_limit' => (int)($vars['BW_LIMIT'] ?? 0),
'retry_count' => (int)($vars['RETRY_COUNT'] ?? 3),
'sleep' => (int)($vars['SLEEP'] ?? 300),
'bw_warn_gb' => (float)($vars['BANDWIDTH_WARN_GB'] ?? 50),
],
'ts' => time(),
]);