Setup wizard: full first-run flow for HOST1 and HOST2
Varaverk.page: also shows wizard when local host.conf is missing
(handles master.conf pushed by HOST1 before HOST2 installs plugin).
pages/setup.php: three wizard flows
- Standard: blank master.conf, fill hostnames, redirect to scheduler
- Host2/state file: state file detected, pull master.conf from HOST1 via SSH
- Conf-only: master.conf already filled (was pushed), just create local host.conf
api/setup.php:
- save action: writes master.conf + host.conf, creates varaverk_setup.db state file,
redirects to ?tab=scheduler&vv_setup=master.conf
- pull action: resolves HOST1 Tailscale IP, queries HOST1 SCRIPTS_DIR, SCPs
master.conf, creates local host.conf, redirects to ?tab=scheduler&vv_setup=hostN.conf
include/config.php: vv_setup_state_read/write/push helpers.
vv_push_setup_state() pushes varaverk_setup.db to /boot/config/ on all known
remotes — no plugin-readiness probe needed (flash is always accessible).
api/rawconf.php: calls vv_push_setup_state() alongside master.conf push.
pages/scheduler.php: setup mode via ?vv_setup=<conf> URL param.
Auto-opens the specified conf file on page load (DOMContentLoaded).
vvSaveRawConf: in setup mode, skips confirm dialog and forces sequence:
master.conf save → auto-open hostN.conf
hostN.conf save → redirect to Monitor (setup complete)
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__) . '/include/scheduler.php';
|
||||
|
||||
// Setup mode — auto-open a conf file and force the editing sequence
|
||||
$vv_setup_conf = preg_match('/^[\w.]+\.conf$/', $_GET['vv_setup'] ?? '')
|
||||
? $_GET['vv_setup'] : '';
|
||||
$_vv_my_host = vv_detect_host();
|
||||
$_vv_local_host_conf = ($_vv_my_host !== 'unknown') ? $_vv_my_host . '.conf' : 'host1.conf';
|
||||
|
||||
$tree = vv_job_tree();
|
||||
$customs = vv_custom_scripts();
|
||||
$tools = vv_tools_scripts();
|
||||
@@ -941,6 +948,17 @@ let vvSelectedRow = null;
|
||||
let vvCurrentSiId = null;
|
||||
let vvCurrentSiHdr = null;
|
||||
|
||||
// Setup mode — injected by PHP when navigating from the first-run wizard
|
||||
let vvSetupConf = <?= json_encode($vv_setup_conf) ?>;
|
||||
const vvLocalHostConf = <?= json_encode($_vv_local_host_conf) ?>;
|
||||
|
||||
if (vvSetupConf) {
|
||||
// Auto-open the setup conf file once the page is ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setTimeout(() => vvLoadRawConf(vvSetupConf), 150);
|
||||
});
|
||||
}
|
||||
|
||||
function vvEscHtml(s) {
|
||||
return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||||
}
|
||||
@@ -2585,7 +2603,7 @@ function vvShowRawConfMode(title) {
|
||||
|
||||
function vvSaveRawConf() {
|
||||
if (!vvRawConfFile) return;
|
||||
if (!confirm('Save changes to "' + vvRawConfFile + '"?')) return;
|
||||
if (!vvSetupConf && !confirm('Save changes to "' + vvRawConfFile + '"?')) return;
|
||||
const content = document.getElementById('vv-editor-body').value;
|
||||
const btn = document.getElementById('vv-save-rawconf-btn');
|
||||
btn.disabled = true;
|
||||
@@ -2598,15 +2616,32 @@ function vvSaveRawConf() {
|
||||
alert('Save failed: ' + (d.error ?? 'Unknown error'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup mode: forced editing sequence
|
||||
if (vvSetupConf) {
|
||||
if (vvRawConfFile === 'master.conf') {
|
||||
// master.conf saved → open host conf next
|
||||
btn.textContent = '✓ Saved — opening ' + vvLocalHostConf + '…';
|
||||
vvSetupConf = vvLocalHostConf;
|
||||
history.replaceState(null, '', location.pathname + '?tab=scheduler&vv_setup=' + encodeURIComponent(vvLocalHostConf));
|
||||
setTimeout(() => vvLoadRawConf(vvLocalHostConf), 400);
|
||||
} else {
|
||||
// Host conf saved → setup complete
|
||||
btn.textContent = '✓ Setup complete — loading plugin…';
|
||||
vvSetupConf = '';
|
||||
setTimeout(() => { window.location.href = location.pathname + '?tab=monitor'; }, 800);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Normal save: show push status
|
||||
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;
|
||||
btn.textContent = '✓ Saved · synced to ' + push.map(p => p.host).join(', ');
|
||||
} else {
|
||||
const failed = push.filter(p => !p.ok).map(p => p.host).join(', ');
|
||||
btn.textContent = '✓ Saved · push failed: ' + failed;
|
||||
btn.textContent = '✓ Saved · push failed: ' + push.filter(p => !p.ok).map(p => p.host).join(', ');
|
||||
}
|
||||
setTimeout(() => { btn.textContent = 'Save Conf'; }, 3500);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user