Push master.conf to all partners immediately on raw-editor save
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/.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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') ?: '');
|
||||
}
|
||||
|
||||
@@ -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'; });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user