feat (health): voeg helper socket check toe, drie visuele states
Backend (/api/health):
- Importeer HELPER_SOCKET uit common.py
- Voeg helper-check toe: connect() op /run/podman-helper.sock, timeout=2s
- ok blijft true als alleen de helper ontbreekt (waarschuwing, geen fout)
- Nieuwe response key: "helper": {"ok": bool}
Frontend (pingApi / setApiState):
- pingApi() roept nu /api/health aan i.p.v. /pods-dashboard
- setApiState(state, msg) accepteert 'ok' / 'warn' / 'error'
- Gele dot met --warn kleur als helper.ok=false maar core OK
- refreshActive() delegeert statusupdate aan pingApi()
- Detailbericht bij fout: toont welk component (podman/systemd) faalt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
from common import (
|
from common import (
|
||||||
|
HELPER_SOCKET,
|
||||||
_helper_call,
|
_helper_call,
|
||||||
_podman_get_json as _common_podman_get_json,
|
_podman_get_json as _common_podman_get_json,
|
||||||
_systemctl as _common_systemctl,
|
_systemctl as _common_systemctl,
|
||||||
@@ -40,11 +42,21 @@ def init_system_router(session, podman_api_base: str, workloads_dir: str) -> API
|
|||||||
except Exception:
|
except Exception:
|
||||||
systemd_reachable = False
|
systemd_reachable = False
|
||||||
|
|
||||||
|
helper_ok = False
|
||||||
|
try:
|
||||||
|
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
|
||||||
|
s.settimeout(2)
|
||||||
|
s.connect(HELPER_SOCKET)
|
||||||
|
helper_ok = True
|
||||||
|
except Exception:
|
||||||
|
helper_ok = False
|
||||||
|
|
||||||
ok = podman_ok and systemd_reachable
|
ok = podman_ok and systemd_reachable
|
||||||
return {
|
return {
|
||||||
"ok": ok,
|
"ok": ok,
|
||||||
"podman": {"ok": podman_ok},
|
"podman": {"ok": podman_ok},
|
||||||
"systemd_user": {"reachable": systemd_reachable},
|
"systemd_user": {"reachable": systemd_reachable},
|
||||||
|
"helper": {"ok": helper_ok},
|
||||||
}
|
}
|
||||||
|
|
||||||
@router.get("/test-hybrid")
|
@router.get("/test-hybrid")
|
||||||
|
|||||||
+19
-10
@@ -624,21 +624,30 @@
|
|||||||
// ---- Health / Ping ----
|
// ---- Health / Ping ----
|
||||||
async function pingApi() {
|
async function pingApi() {
|
||||||
try {
|
try {
|
||||||
// simpele ping: pods ophalen
|
const h = await api('/health', 'GET');
|
||||||
await api('/pods-dashboard', 'GET');
|
const helperOk = h?.helper?.ok === true;
|
||||||
setApiState(true, 'API: OK');
|
if (!h?.ok) {
|
||||||
|
const detail = !h?.podman?.ok ? 'podman' : !h?.systemd_user?.reachable ? 'systemd' : 'onbekend';
|
||||||
|
setApiState('error', `API: fout (${detail})`);
|
||||||
|
} else if (!helperOk) {
|
||||||
|
setApiState('warn', 'API: OK | ⚠️ helper');
|
||||||
|
} else {
|
||||||
|
setApiState('ok', 'API: OK');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setApiState(false, 'API: fout (' + e.message + ')');
|
setApiState('error', 'API: fout (' + e.message + ')');
|
||||||
showModal('API fout', e.stack || e.message);
|
showModal('API fout', e.stack || e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function setApiState(ok, msg) {
|
function setApiState(state, msg) {
|
||||||
const dot = document.getElementById('apiDot');
|
const dot = document.getElementById('apiDot');
|
||||||
dot.style.background = ok ? 'var(--ok)' : 'var(--bad)';
|
const ok = state === 'ok';
|
||||||
dot.style.boxShadow = ok ? '0 0 0 6px rgba(45,212,191,.15)' : '0 0 0 6px rgba(251,113,133,.15)';
|
const warn = state === 'warn';
|
||||||
|
dot.style.background = ok ? 'var(--ok)' : warn ? 'var(--warn, #f59e0b)' : 'var(--bad)';
|
||||||
|
dot.style.boxShadow = ok ? '0 0 0 6px rgba(45,212,191,.15)' : warn ? '0 0 0 6px rgba(245,158,11,.15)' : '0 0 0 6px rgba(251,113,133,.15)';
|
||||||
document.getElementById('statusLine').textContent = msg;
|
document.getElementById('statusLine').textContent = msg;
|
||||||
const apiStat = document.getElementById('dashboardApiState');
|
const apiStat = document.getElementById('dashboardApiState');
|
||||||
if (apiStat) apiStat.textContent = ok ? 'OK' : 'Fout';
|
if (apiStat) apiStat.textContent = ok ? 'OK' : warn ? 'Waarschuwing' : 'Fout';
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentClockText() {
|
function currentClockText() {
|
||||||
@@ -672,10 +681,10 @@
|
|||||||
const nCount = Array.isArray(networks?.networks) ? networks.networks.length : 0;
|
const nCount = Array.isArray(networks?.networks) ? networks.networks.length : 0;
|
||||||
updateNavCount('countNavNetworks', nCount);
|
updateNavCount('countNavNetworks', nCount);
|
||||||
}
|
}
|
||||||
setApiState(true, 'API: OK');
|
|
||||||
setLastRefreshNow();
|
setLastRefreshNow();
|
||||||
|
pingApi();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setApiState(false, 'API: fout (' + e.message + ')');
|
setApiState('error', 'API: fout (' + e.message + ')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user