Show a launched job's progress, stop a refused rerun from overwriting the live record, and label deployed containers so Unraid owns them
This commit is contained in:
@@ -193,6 +193,55 @@ function _vvPtRun(id, extraArgs) {
|
||||
});
|
||||
}
|
||||
|
||||
// ── Live progress for a launched job ──────────────────────────────────────────
|
||||
// api/run.php returns {ok:true} the instant the job is *launched*, not when it finishes, and
|
||||
// onboard then runs for minutes. Nothing surfaced that, so pressing Onboard looked like pressing
|
||||
// nothing — and the natural response is to press it again, which is worse: the second run is
|
||||
// refused by the script's own lock and its failure stat overwrites the live run's record.
|
||||
//
|
||||
// Polls the job's stat for liveness and its log for the step banner run_job.sh is capturing, and
|
||||
// renders the last "━━━ Step … ━━━" line as the current activity.
|
||||
const _vvJobPoll = {};
|
||||
|
||||
function vvPtWatchJob(id, mountEl) {
|
||||
if (_vvJobPoll[id]) clearInterval(_vvJobPoll[id]);
|
||||
const enc = encodeURIComponent(id);
|
||||
|
||||
const tick = () => {
|
||||
fetch(`/plugins/varaverk/api/status.php?id=${enc}&_=${Date.now()}`)
|
||||
.then(r => r.json())
|
||||
.then(s => {
|
||||
if (!s.ok) return;
|
||||
if (s.status === 'running') {
|
||||
return fetch(`/plugins/varaverk/api/log.php?id=${enc}&_=${Date.now()}`)
|
||||
.then(r => r.json())
|
||||
.then(l => {
|
||||
const lines = (l.content || '').split('\n');
|
||||
// Last step banner wins — that is where the run currently is.
|
||||
let step = '';
|
||||
for (let i = lines.length - 1; i >= 0; i--) {
|
||||
const m = lines[i].match(/━━━\s*(?:[^\s]+\s+)?(Step [^━]+?)\s*━━━/);
|
||||
if (m) { step = m[1].trim(); break; }
|
||||
}
|
||||
mountEl.innerHTML = `<span style="color:#4a9eff;">⟳ running</span>`
|
||||
+ (step ? ` <span style="color:#666;">· ${vvEscHtml(step)}</span>` : '');
|
||||
});
|
||||
}
|
||||
clearInterval(_vvJobPoll[id]);
|
||||
delete _vvJobPoll[id];
|
||||
const col = s.status === 'ok' ? '#4caf50' : (s.status === 'warn' ? '#ff9800' : '#f44336');
|
||||
const lbl = s.status === 'ok' ? 'complete ✅'
|
||||
: (s.status === 'never_run' ? 'did not start ⚠' : `${s.status} (exit ${s.exit ?? '?'})`);
|
||||
mountEl.innerHTML = `<span style="color:${col};">${lbl}</span>`
|
||||
+ ` <a href="?tab=scheduler" class="localURL" style="color:#556;margin-left:6px;">log</a>`;
|
||||
if (_vvPtReload) _vvPtReload();
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
tick();
|
||||
_vvJobPoll[id] = setInterval(tick, 4000);
|
||||
}
|
||||
|
||||
function vvPtStartOnboard(hostId) {
|
||||
_vvOnboarding[hostId] = true;
|
||||
delete _vvDeleteKeys[hostId];
|
||||
@@ -253,10 +302,33 @@ async function vvPtOnboard(btn) {
|
||||
if (!await vvConfirm('Run full partnership_onboard.sh?\n\nRun on the MIRROR first, then on the OWNER.\n\nUse Phase 1 + Phase 2 buttons for step-by-step control.')) return;
|
||||
btn.disabled = true;
|
||||
btn.textContent = '⟳ Starting…';
|
||||
// Stays disabled while the job runs. Re-enabling after a fixed timeout invited the second
|
||||
// click that overwrites the live run's job record with its own lock refusal.
|
||||
const prog = _vvJobProgressEl(btn);
|
||||
_vvPtRun('Partnership/partnership_onboard.sh')
|
||||
.then(d => { if (!d.ok) vvAlert('Failed: ' + (d.error ?? 'Unknown error')); })
|
||||
.catch(e => vvAlert('Error: ' + e))
|
||||
.finally(() => setTimeout(() => { btn.disabled = false; btn.textContent = '▶ Onboard (Mirror)'; }, 4000));
|
||||
.then(d => {
|
||||
if (!d.ok) throw new Error(d.error ?? 'Unknown error');
|
||||
btn.textContent = '⟳ Running…';
|
||||
vvPtWatchJob('Partnership/partnership_onboard.sh', prog);
|
||||
})
|
||||
.catch(e => {
|
||||
prog.innerHTML = `<span style="color:#f44336;">failed to start — ${vvEscHtml(String(e.message || e))}</span>`;
|
||||
btn.disabled = false;
|
||||
btn.textContent = '▶ Onboard';
|
||||
});
|
||||
}
|
||||
|
||||
// One status line per button, inserted after it and reused across polls.
|
||||
function _vvJobProgressEl(btn) {
|
||||
let el = btn.parentElement.querySelector('.vv-jobprog');
|
||||
if (!el) {
|
||||
el = document.createElement('div');
|
||||
el.className = 'vv-jobprog';
|
||||
el.style.cssText = 'font-size:10px;margin-top:5px;white-space:nowrap;';
|
||||
btn.parentElement.appendChild(el);
|
||||
}
|
||||
el.innerHTML = '<span style="color:#4a9eff;">⟳ starting…</span>';
|
||||
return el;
|
||||
}
|
||||
|
||||
async function vvPtPushConf(btn, hostId) {
|
||||
|
||||
Reference in New Issue
Block a user