From da0c303f227e7902a9bbd7a3b0eb5449c3a483d9 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sat, 30 May 2026 14:21:02 -0400 Subject: [PATCH] Push master.conf to all partners immediately on raw-editor save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vv_push_master_conf() in config.php: finds all remote HOST* entries, resolves Tailscale IPs, SCPs master.conf to each. rawconf.php calls it after a successful write when file=master.conf. Scheduler save button shows sync status: "✓ Saved · synced to HOST2" or "✓ Saved · push failed: HOST2" on error. Also fix path bug in partnership_transfer.sh — was SCPing to appdata root instead of Configurations/. --- Partnership/partnership_transfer.sh | 4 +-- Plugin/unraid/api/rawconf.php | 4 ++- Plugin/unraid/include/config.php | 41 +++++++++++++++++++++++++++++ Plugin/unraid/pages/scheduler.php | 17 +++++++++--- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Partnership/partnership_transfer.sh b/Partnership/partnership_transfer.sh index 5ebb4a9..bc6727d 100755 --- a/Partnership/partnership_transfer.sh +++ b/Partnership/partnership_transfer.sh @@ -294,8 +294,8 @@ if [[ "$DRY_RUN" == false ]]; then scp -i "$SSH_KEY" \ -o ConnectTimeout="$SSH_TIMEOUT" \ -o StrictHostKeyChecking=no \ - "$SCRIPTS_ROOT/master.conf" \ - "root@${MIRROR_IP}:/mnt/user/appdata/Varaverk/master.conf" 2>/dev/null && \ + "$SCRIPTS_ROOT/Configurations/master.conf" \ + "root@${MIRROR_IP}:/mnt/user/appdata/Varaverk/Configurations/master.conf" 2>/dev/null && \ log "master.conf pushed to $NEW_OWNER ✅" || \ error "Failed to push master.conf to $NEW_OWNER — set PARTNERSHIP_OWNER_HOST=\"$NEW_OWNER_ID\" manually" else diff --git a/Plugin/unraid/api/rawconf.php b/Plugin/unraid/api/rawconf.php index 067ea07..5671f9d 100644 --- a/Plugin/unraid/api/rawconf.php +++ b/Plugin/unraid/api/rawconf.php @@ -22,7 +22,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { echo json_encode(['ok' => false, 'error' => 'Not allowed']); exit; } - echo json_encode(['ok' => vv_write_conf_raw($file, $content)]); + $written = vv_write_conf_raw($file, $content); + $push = ($written && $file === 'master.conf') ? vv_push_master_conf() : []; + echo json_encode(['ok' => $written, 'push' => $push]); exit; } diff --git a/Plugin/unraid/include/config.php b/Plugin/unraid/include/config.php index 9b639f1..f27f526 100644 --- a/Plugin/unraid/include/config.php +++ b/Plugin/unraid/include/config.php @@ -10,6 +10,47 @@ define('CONF_DIR', SCRIPTS_DIR . '/Configurations'); define('LOG_DIR', '/var/log/varaverk'); unset($_vv_cfg); +// Push master.conf to all remote hosts via scp after a local save. +// Returns one result entry per remote found in master.conf. +// Silently returns [] on non-owner hosts (no SSH key, no remote access). +function vv_push_master_conf(): array { + $myHostId = vv_detect_host(); + $vars = vv_conf_vars(); + $sshKey = $vars[strtoupper($myHostId) . '_SSH_KEY'] ?? ''; + if (!$sshKey || !file_exists($sshKey)) return []; + + $localPath = CONF_DIR . '/master.conf'; + $master = vv_read_conf_raw('master.conf'); + preg_match_all('/^\s*(HOST\d+)(?:_NAME)?\s*=\s*["\']?(\S+?)["\']?\s*$/m', $master, $m); + + $results = []; + $seen = []; + foreach ($m[1] as $i => $hostKey) { + $hostId = strtolower($hostKey); + if ($hostId === $myHostId || isset($seen[$hostId])) continue; + $seen[$hostId] = true; + + $hostname = trim($m[2][$i]); + $ip = vv_resolve_tailscale_ip($hostname); + if (!$ip) { + $results[] = ['host' => $hostKey, 'ok' => false, 'error' => 'Tailscale IP not found']; + continue; + } + + $dest = escapeshellarg('root@' . $ip . ':' . CONF_DIR . '/master.conf'); + $cmd = 'scp -i ' . escapeshellarg($sshKey) + . ' -o ConnectTimeout=10 -o StrictHostKeyChecking=no' + . ' ' . escapeshellarg($localPath) . ' ' . $dest . ' 2>&1'; + exec($cmd, $out, $rc); + $results[] = [ + 'host' => $hostKey, + 'ok' => $rc === 0, + 'error' => $rc !== 0 ? implode('; ', $out) : '', + ]; + } + return $results; +} + function vv_get_hostname(): string { return trim(shell_exec('hostname -s') ?: ''); } diff --git a/Plugin/unraid/pages/scheduler.php b/Plugin/unraid/pages/scheduler.php index f9d3aa1..52ce1e6 100644 --- a/Plugin/unraid/pages/scheduler.php +++ b/Plugin/unraid/pages/scheduler.php @@ -2593,13 +2593,22 @@ function vvSaveRawConf() { vvPost('/plugins/varaverk/api/rawconf.php', {file: vvRawConfFile, content}) .then(d => { btn.disabled = false; - if (d.ok) { - btn.textContent = '✓ Saved'; - setTimeout(() => { btn.textContent = 'Save Conf'; }, 2500); - } else { + if (!d.ok) { btn.textContent = 'Save Conf'; alert('Save failed: ' + (d.error ?? 'Unknown error')); + return; } + const push = d.push ?? []; + if (push.length === 0) { + btn.textContent = '✓ Saved'; + } else if (push.every(p => p.ok)) { + const hosts = push.map(p => p.host).join(', '); + btn.textContent = '✓ Saved · synced to ' + hosts; + } else { + const failed = push.filter(p => !p.ok).map(p => p.host).join(', '); + btn.textContent = '✓ Saved · push failed: ' + failed; + } + setTimeout(() => { btn.textContent = 'Save Conf'; }, 3500); }) .catch(() => { btn.disabled = false; btn.textContent = 'Save Conf'; }); }