/dev/null") ?: ''); if (!$part) return 'unknown'; $disk = trim(shell_exec("lsblk -no pkname " . escapeshellarg($part) . " 2>/dev/null") ?: ''); if (!$disk) return 'unknown'; return strtolower(trim(shell_exec("lsblk -dno TRAN /dev/" . escapeshellarg($disk) . " 2>/dev/null") ?: 'unknown')); } // ── Current mode status ─────────────────────────────────────────────────────── if ($action === 'status') { $transport = vv_storage_detect_transport(); $detected = ($transport === 'usb') ? 'flash' : 'internal'; $currentDir = SCRIPTS_DIR; $internalDir = '/boot/config/plugins/varaverk'; $flashDir = '/mnt/user/appdata/Varaverk'; $currentMode = ($currentDir === $internalDir) ? 'internal' : ($currentDir === $flashDir ? 'flash' : 'custom'); $myHost = vv_detect_host(); $vars = vv_conf_vars(); $confKey = strtoupper($myHost) . '_STORAGE_MODE_INTERNAL'; $confVal = $vars[$confKey] ?? null; // Boot device name for display $bootPart = trim(shell_exec("findmnt -n -o SOURCE /boot 2>/dev/null") ?: ''); $bootDisk = $bootPart ? trim(shell_exec("lsblk -no pkname " . escapeshellarg($bootPart) . " 2>/dev/null") ?: '') : ''; echo json_encode([ 'ok' => true, 'current_mode' => $currentMode, 'current_dir' => $currentDir, 'internal_dir' => $internalDir, 'flash_dir' => $flashDir, 'transport' => $transport, 'detected' => $detected, 'boot_disk' => $bootDisk ? '/dev/' . $bootDisk : 'unknown', 'conf_key' => $confKey, 'conf_val' => $confVal, 'array_started'=> is_dir('/mnt/user') && count(scandir('/mnt/user')) > 2, ]); exit; } // ── Run migration ───────────────────────────────────────────────────────────── if ($action === 'migrate' && $_SERVER['REQUEST_METHOD'] === 'POST') { $to = trim($_POST['to'] ?? ''); if (!in_array($to, ['internal', 'flash'], true)) { echo json_encode(['ok' => false, 'error' => 'Invalid target: must be internal or flash']); exit; } $script = dirname(__DIR__) . '/Tools/storage_migrate.sh'; if (!file_exists($script)) { echo json_encode(['ok' => false, 'error' => 'storage_migrate.sh not found']); exit; } set_time_limit(300); $output = []; $exit = 0; exec('bash ' . escapeshellarg($script) . ' --to=' . escapeshellarg($to) . ' 2>&1', $output, $exit); echo json_encode([ 'ok' => $exit === 0, 'exit' => $exit, 'output' => implode("\n", $output), ]); exit; } // ── Auto-detect and write to conf ───────────────────────────────────────────── if ($action === 'detect' && $_SERVER['REQUEST_METHOD'] === 'POST') { $transport = vv_storage_detect_transport(); $detected = ($transport === 'usb') ? 'false' : 'true'; $myHost = vv_detect_host(); $confKey = strtoupper($myHost) . '_STORAGE_MODE_INTERNAL'; $confFile = $myHost . '.conf'; $results = vv_conf_write_changes([[ 'file' => $confFile, 'key' => $confKey, 'value' => $detected, 'type' => 'scalar', ]]); $ok = !in_array(false, $results, true); echo json_encode(['ok' => $ok, 'detected' => $detected, 'transport' => $transport]); exit; } // ── Unraid API key status ───────────────────────────────────────────────────── // Keys live in host*.conf (private, not master.conf): // host1.conf: HOST1_UNRAID_API_KEY (own) + HOST2_UNRAID_API_KEY (HOST1's access to HOST2) // host2.conf: HOST2_UNRAID_API_KEY (own) + HOST1_UNRAID_API_KEY (HOST2's access to HOST1) if ($action === 'api_status') { require_once dirname(__DIR__) . '/include/unraid_api.php'; $localStatus = vv_api_get_status(); $vars = vv_conf_vars(); $myHost = vv_detect_host(); $myId = strtoupper($myHost); $hosts = []; foreach ($vars as $k => $v) { if (!preg_match('/^HOST(\d+)$/', $k, $m) || !$v) continue; $id = 'HOST' . $m[1]; $keyVar = $id . '_UNRAID_API_KEY'; $key = $vars[$keyVar] ?? ''; $isLocal = ($id === $myId); // For local: key is Varaverk_HOST1 registered on own machine // For remote: key is Varaverk_HOST1 registered on HOST2's machine (stored in host1.conf) $hosts[] = [ 'host_id' => $id, 'hostname' => $v, 'is_local' => $isLocal, 'key_var' => $keyVar, 'key_name' => 'Varaverk_' . ($isLocal ? $myId : $myId), // Varaverk_HOST1 on that registry 'key_present' => !empty($key), 'key_preview' => $key ? substr($key, 0, 8) . '...' . substr($key, -4) : null, 'api_ok' => $isLocal ? (!$localStatus['key_missing'] && $localStatus['available']) : !empty($key), ]; } usort($hosts, fn($a, $b) => strcmp($a['host_id'], $b['host_id'])); echo json_encode([ 'ok' => true, 'my_id' => $myId, 'hosts' => $hosts, 'fallbacks' => $localStatus['fallbacks'], ]); exit; } // ── Setup/renew API keys (local + all partners via SSH) ─────────────────────── if ($action === 'setup_apikeys' && $_SERVER['REQUEST_METHOD'] === 'POST') { $script = SCRIPTS_DIR . '/Plugin/unraid/System_Essentials/unraid_api_key_renew.sh'; if (!file_exists($script)) { echo json_encode(['ok' => false, 'error' => 'unraid_api_key_renew.sh not found']); exit; } $allHosts = ($_POST['all_hosts'] ?? '0') === '1'; $flags = $allHosts ? ' --all-hosts' : ''; set_time_limit(60); $output = []; $exit = 0; exec('bash ' . escapeshellarg($script) . $flags . ' 2>&1', $output, $exit); echo json_encode(['ok' => $exit === 0, 'exit' => $exit, 'output' => implode("\n", $output)]); exit; } echo json_encode(['ok' => false, 'error' => 'Unknown action']);