Make a container action tell the truth about what happened
The response was discarded, so a refused stop looked like a completed one, and the payload the card redraws from is cached for 300s with no invalidation — the container carried on showing as running until the once-a-minute writer caught up. Stop now confirms; start still does not.
This commit is contained in:
@@ -27,8 +27,15 @@
|
||||
// the page reported healthy unconditionally (fixed 2026-08-02). If this panel looks
|
||||
// suspiciously green, verify the paths before believing it.
|
||||
//
|
||||
// Container actions are confirmed and routed through the action endpoint, which validates
|
||||
// against real inventory.
|
||||
// Stopping a container is confirmed; starting one is not, and the endpoint validates every
|
||||
// action against real inventory regardless. Failures are surfaced rather than swallowed — the
|
||||
// response used to be discarded, which made a refused stop indistinguishable from a completed
|
||||
// one.
|
||||
//
|
||||
// An action that changes container state clears the monitor cache.
|
||||
// api/docker_action.php and the pull worker both drop it, so the next poll collects
|
||||
// instead of re-reading a payload written before the action. Without that the card
|
||||
// contradicted the button for up to a minute.
|
||||
//
|
||||
// All remote and container-supplied strings render escaped.
|
||||
// Through vvEscHtml()/vvEscAttr() from Varaverk.page — media titles and usernames from
|
||||
@@ -2249,13 +2256,27 @@ function vvDockerAction(action, name, webui) {
|
||||
encodeURIComponent('/boot/config/plugins/dockerMan/templates-user/my-' + name + '.xml') + '&update=true';
|
||||
return;
|
||||
}
|
||||
// Stopping is confirmed; starting is not. The asymmetry is the point — start is recoverable by
|
||||
// clicking the other button, stop takes a service away from whoever is using it, and these
|
||||
// buttons sit inside a dense grid where the row under the cursor is easy to misjudge.
|
||||
if (action === 'stop' && !confirm('Stop ' + name + '?')) return;
|
||||
|
||||
const fd = new URLSearchParams();
|
||||
fd.set('action', action);
|
||||
fd.set('name', name);
|
||||
fetch('/plugins/varaverk/api/docker_action.php', { method: 'POST', body: fd })
|
||||
.then(r => r.json())
|
||||
.then(() => { vvDfActive = null; setTimeout(vvPollMonitor, 1500); })
|
||||
.catch(() => {});
|
||||
.then(d => {
|
||||
// The endpoint reports refusals as ok:false with a reason — container not found, a non-zero
|
||||
// docker exit. Discarding that made a failed stop look exactly like a successful one, since
|
||||
// the card it would have changed is redrawn from a payload either way.
|
||||
if (!d || !d.ok) alert('Container ' + action + ' failed: ' + ((d && (d.error || d.output)) || 'unknown error'));
|
||||
vvDfActive = null;
|
||||
// The endpoint drops the monitor cache on success, so this poll collects fresh rather than
|
||||
// re-reading the payload that was written before the action happened.
|
||||
setTimeout(vvPollMonitor, 1500);
|
||||
})
|
||||
.catch(() => alert('Container ' + action + ' failed: request error'));
|
||||
}
|
||||
|
||||
function vvRenderDockerFolders(data) {
|
||||
|
||||
Reference in New Issue
Block a user