Add Stop Podman to Settings, alongside Start/Restart
Lint / ShellCheck (push) Successful in 11s
Lint / Validate .plg XML (push) Successful in 10s
Lint / EditorConfig (push) Successful in 5s

Rounds out the Podman Service card to the full start/stop/restart trio.
Stop and Restart both get a confirm() first — both actually stop every
running container (with its own configured grace period) before touching
the API service itself, not just the service process; worth surfacing
that explicitly rather than letting it be a surprise.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 23:01:26 +00:00
co-authored by Claude Sonnet 5
parent 5fb7376b64
commit 9557f8c8f8
3 changed files with 23 additions and 4 deletions
+3 -1
View File
@@ -238,15 +238,17 @@ function podman_asset_version(string $relPath): string
<div class="podman-grid"> <div class="podman-grid">
<div class="podman-card"> <div class="podman-card">
<div class="podman-card-head"> <div class="podman-card-head">
<div><h2>Podman Service</h2><div class="sub">Start, restart, or check the podman.sock backend — no terminal needed.</div></div> <div><h2>Podman Service</h2><div class="sub">Start, stop, restart, or check the podman.sock backend — no terminal needed.</div></div>
</div> </div>
<div class="podman-card-pad"> <div class="podman-card-pad">
<div class="podman-service-row"> <div class="podman-service-row">
<span class="podman-chip podman-chip-neutral" id="settings-service-chip"><span class="d"></span>Checking…</span> <span class="podman-chip podman-chip-neutral" id="settings-service-chip"><span class="d"></span>Checking…</span>
<button class="podman-btn" id="settings-service-status-btn">Refresh Status</button> <button class="podman-btn" id="settings-service-status-btn">Refresh Status</button>
<button class="podman-btn podman-btn-primary" id="settings-service-start-btn">&#9654; Start Podman</button> <button class="podman-btn podman-btn-primary" id="settings-service-start-btn">&#9654; Start Podman</button>
<button class="podman-btn podman-btn-ghost podman-btn-danger" id="settings-service-stop-btn">&#9632; Stop Podman</button>
<button class="podman-btn" id="settings-service-restart-btn">&#8635; Restart Podman</button> <button class="podman-btn" id="settings-service-restart-btn">&#8635; Restart Podman</button>
</div> </div>
<div class="hint">Stop/Restart first stop all running containers (each gets its own configured grace period) — not just the API service.</div>
<div class="podman-log-pane" id="settings-service-log" style="display:none;"></div> <div class="podman-log-pane" id="settings-service-log" style="display:none;"></div>
</div> </div>
</div> </div>
+5
View File
@@ -18,6 +18,7 @@
* autostart_save POST {"names": ["postgres", "nextcloud", ...]} * autostart_save POST {"names": ["postgres", "nextcloud", ...]}
* service_status GET -> {"running": bool, "output": "..."} * service_status GET -> {"running": bool, "output": "..."}
* service_start POST -> {"running": bool, "output": "..."} * service_start POST -> {"running": bool, "output": "..."}
* service_stop POST -> {"running": bool, "output": "..."}
* service_restart POST -> {"running": bool, "output": "..."} * service_restart POST -> {"running": bool, "output": "..."}
*/ */
@@ -58,6 +59,10 @@ switch ($action) {
podman_json_response(rc_podman('start', 120)); podman_json_response(rc_podman('start', 120));
break; break;
case 'service_stop':
podman_json_response(rc_podman('stop', 120));
break;
case 'service_restart': case 'service_restart':
podman_json_response(rc_podman('restart', 120)); podman_json_response(rc_podman('restart', 120));
break; break;
+15 -3
View File
@@ -72,8 +72,13 @@
} }
} }
function serviceButtons() {
return ['settings-service-status-btn', 'settings-service-start-btn', 'settings-service-stop-btn', 'settings-service-restart-btn']
.map(function (id) { return P.el(id); });
}
function refreshServiceStatus() { function refreshServiceStatus() {
const buttons = [P.el('settings-service-status-btn'), P.el('settings-service-start-btn'), P.el('settings-service-restart-btn')]; const buttons = serviceButtons();
buttons.forEach(function (b) { b.disabled = true; }); buttons.forEach(function (b) { b.disabled = true; });
return P.get('settings', 'service_status').then(renderServiceResult).catch(function (err) { return P.get('settings', 'service_status').then(renderServiceResult).catch(function (err) {
P.el('settings-service-chip').className = 'podman-chip podman-chip-bad'; P.el('settings-service-chip').className = 'podman-chip podman-chip-bad';
@@ -86,7 +91,7 @@
} }
function runServiceAction(action) { function runServiceAction(action) {
const buttons = [P.el('settings-service-status-btn'), P.el('settings-service-start-btn'), P.el('settings-service-restart-btn')]; const buttons = serviceButtons();
buttons.forEach(function (b) { b.disabled = true; }); buttons.forEach(function (b) { b.disabled = true; });
P.el('settings-service-log').style.display = ''; P.el('settings-service-log').style.display = '';
P.el('settings-service-log').textContent = 'Working…'; P.el('settings-service-log').textContent = 'Working…';
@@ -205,7 +210,14 @@
P.el('settings-service-status-btn').addEventListener('click', refreshServiceStatus); P.el('settings-service-status-btn').addEventListener('click', refreshServiceStatus);
P.el('settings-service-start-btn').addEventListener('click', function () { runServiceAction('service_start'); }); P.el('settings-service-start-btn').addEventListener('click', function () { runServiceAction('service_start'); });
P.el('settings-service-restart-btn').addEventListener('click', function () { runServiceAction('service_restart'); }); P.el('settings-service-stop-btn').addEventListener('click', function () {
if (!confirm('Stop podman? All running containers will be stopped first (each with its own configured grace period).')) return;
runServiceAction('service_stop');
});
P.el('settings-service-restart-btn').addEventListener('click', function () {
if (!confirm('Restart podman? All running containers will be stopped and podman.sock will be unavailable until it comes back up.')) return;
runServiceAction('service_restart');
});
P.el('settings-format-disk-btn').addEventListener('click', openFormatDiskModal); P.el('settings-format-disk-btn').addEventListener('click', openFormatDiskModal);
refreshServiceStatus(); refreshServiceStatus();