Files
Varaverk/Plugin/unraid/api/rsync_win_arrays.php
T

134 lines
6.2 KiB
PHP

<?php
header('Content-Type: application/json');
require_once dirname(__DIR__) . '/include/config.php';
require_once dirname(__DIR__) . '/include/confform.php';
require_once dirname(__DIR__) . '/include/common.php';
$action = $_GET['action'] ?? $_POST['action'] ?? '';
// ── Script library — all .sh files grouped by folder ─────────────────────────
if ($action === 'list_scripts') {
$base = rtrim(SCRIPTS_DIR, '/') . '/';
$exclude = ['Plugin', '.git', 'Orchestrators', 'Custom', 'Configurations',
'Deployment', 'State_Files', 'data', 'Old_Arch_Still_Works', 'Kernel'];
$groups = [];
try {
$ri = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(SCRIPTS_DIR, RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($ri as $rf) {
if (!$rf->isFile() || strtolower($rf->getExtension()) !== 'sh') continue;
$rel = ltrim(str_replace($base, '', $rf->getPathname()), '/');
$parts = explode('/', $rel);
if (count($parts) < 2 || in_array($parts[0], $exclude)) continue;
$folder = $parts[0];
$label = str_replace('_', ' ', basename($rel, '.sh'));
$groups[$folder][] = ['id' => $rel, 'label' => $label];
}
} catch (Exception $e) {}
ksort($groups);
foreach ($groups as &$g) usort($g, fn($a, $b) => strcmp($a['id'], $b['id']));
echo json_encode(['ok' => true, 'groups' => $groups]);
exit;
}
// ── Profile names from master.conf ────────────────────────────────────────────
if ($action === 'list_profiles') {
$raw = vv_read_conf_raw('master.conf');
preg_match_all('/^\s*PROFILE_([A-Z0-9_]+)_RSYNC_OPTS\s*=/m', $raw, $m);
$profiles = array_values(array_unique(
array_map(fn($n) => strtolower(str_replace('_', '-', $n)), $m[1] ?? [])
));
echo json_encode(['ok' => true, 'profiles' => $profiles]);
exit;
}
// ── Save scripts + shares for a window ───────────────────────────────────────
if ($action === 'save' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$winKey = trim($_POST['win_key'] ?? '');
$scripts = json_decode($_POST['scripts'] ?? 'null', true);
$shares = json_decode($_POST['shares'] ?? 'null', true);
$winMap = [
'critical' => ['CRITICAL_MAINTENANCE_SCRIPTS', 'CRITICAL_SYNC_SHARES'],
'intermediate' => ['INTERMEDIATE_MAINTENANCE_SCRIPTS', 'INTERMEDIATE_SYNC_SHARES'],
'daily' => ['DAILY_MAINTENANCE_SCRIPTS', 'DAILY_SYNC_SHARES'],
'weekly' => ['WEEKLY_MAINTENANCE_SCRIPTS', 'WEEKLY_SYNC_SHARES'],
];
if (!isset($winMap[$winKey])) {
echo json_encode(['ok' => false, 'error' => 'Invalid window']); exit;
}
[$scriptsVar, $sharesBase] = $winMap[$winKey];
$myId = strtoupper(vv_detect_host());
$sharesVar = "{$myId}_{$sharesBase}";
$errors = [];
// ── Scripts → master.conf ─────────────────────────────────────────────────
if (is_array($scripts)) {
$confPath = CONF_DIR . '/master.conf';
$lines = file($confPath, FILE_KEEP_BLANK_LINES) ?: [];
$esc = preg_quote($scriptsVar, '/');
$blockStart = $blockEnd = null;
$depth = 0;
$origLines = [];
foreach ($lines as $i => $line) {
if ($blockStart === null) {
if (preg_match('/^\s*' . $esc . '\s*=\s*\(/', $line)) { $blockStart = $i; $depth = 1; }
continue;
}
$depth += substr_count($line, '(') - substr_count($line, ')');
if ($depth <= 0) { $blockEnd = $i; break; }
if (preg_match('/^\s*(?:#\s*)?"([^"]+)"/', $line, $m)) {
$path = explode(' ', trim($m[1]))[0];
if (str_ends_with($path, '.sh') && !isset($origLines[$path]))
$origLines[$path] = '"' . $m[1] . '"';
}
}
if ($blockStart !== null && $blockEnd !== null) {
$newBlock = [$lines[$blockStart]];
foreach ($scripts as $item) {
$id = trim((string)($item['id'] ?? ''));
$enabled = !isset($item['enabled']) || (bool)$item['enabled'];
if (!$id || str_contains($id, '..') || !preg_match('/^[A-Za-z0-9_.\-\/]+\.sh$/', $id)) continue;
$entry = $origLines[$id] ?? '"' . $id . '"';
$prefix = $enabled ? ' ' : ' #';
$newBlock[] = $prefix . $entry . "\n";
}
$newBlock[] = $lines[$blockEnd];
array_splice($lines, $blockStart, $blockEnd - $blockStart + 1, $newBlock);
if (file_put_contents($confPath, implode('', $lines)) === false) $errors[] = 'scripts write failed';
} else {
$errors[] = "Array $scriptsVar not found in master.conf";
}
}
// ── Shares → host*.conf ───────────────────────────────────────────────────
if (is_array($shares)) {
$confFile = strtolower($myId) . '.conf';
$inner = '';
foreach ($shares as $item) {
$path = trim((string)($item['path'] ?? ''));
$profile = trim((string)($item['profile'] ?? ''));
if (!$path || str_contains($path, '..') || !str_starts_with($path, '/')) continue;
$val = $profile ? "{$path}|{$profile}" : $path;
$inner .= ' "' . $val . '"' . "\n";
}
$results = vv_conf_write_changes([[
'file' => $confFile,
'key' => $sharesVar,
'value' => rtrim($inner),
'type' => 'array',
]]);
if (in_array(false, $results, true)) $errors[] = 'shares write failed';
}
echo json_encode(['ok' => empty($errors), 'errors' => $errors]);
exit;
}
echo json_encode(['ok' => false, 'error' => 'Unknown action']);