diff --git a/admin.html b/admin.html index d87d764..bfa89a5 100644 --- a/admin.html +++ b/admin.html @@ -6,7 +6,7 @@ MischLabs Admin - +
@@ -81,6 +81,6 @@ - + diff --git a/admin.js b/admin.js index 2fc17d3..f69808f 100644 --- a/admin.js +++ b/admin.js @@ -315,38 +315,35 @@ function renderDisks(disks = []) { function renderWatchtower(watchtower) { latestWatchtower = watchtower; + const officialSession = watchtower?.lastSession; + const officialHtml = officialSession + ? ` +
Offizieller Lauf${officialSession.finishedAt ? new Date(officialSession.finishedAt).toLocaleString('de-DE') : '--'}
+
Geprueft${officialSession.scanned ?? '--'}
+
Aktualisiert${officialSession.updated ?? '--'}
+
Fehler${officialSession.failed ?? '--'}
+ ` + : `
Offizieller Lauf${watchtower?.tail?.slice(-2)?.join(' | ') || 'Noch nicht gefunden'}
`; + if (lastManualWatchtowerRun) { const run = lastManualWatchtowerRun; const session = run.session; const finished = run.finishedAt ? new Date(run.finishedAt).toLocaleString('de-DE') : 'laeuft noch'; const state = run.running ? 'Laeuft' : `Beendet (${run.exitCode ?? '--'})`; watchtowerStatus.innerHTML = ` -
Manueller Lauf${state}
+ ${officialHtml} +
+
Manuell${state}
Gestartet${run.startedAt ? new Date(run.startedAt).toLocaleString('de-DE') : '--'}
Fertig${finished}
-
Geprueft${session?.scanned ?? '--'}
-
Aktualisiert${session?.updated ?? '--'}
-
Fehler${session?.failed ?? (run.exitCode ? 1 : 0)}
+
Manuell geprueft${session?.scanned ?? '--'}
+
Manuell aktualisiert${session?.updated ?? '--'}
+
Manuelle Fehler${session?.failed ?? (run.exitCode ? 1 : 0)}
`; return; } - const session = watchtower?.lastSession; - if (!session) { - const tail = watchtower?.tail?.slice(-4)?.join(' | '); - watchtowerStatus.textContent = tail - ? `Kein Lauf geparst. Letzte Logs: ${tail}` - : 'Kein Watchtower-Lauf gefunden.'; - return; - } - - const finished = session.finishedAt ? new Date(session.finishedAt).toLocaleString('de-DE') : '--'; - watchtowerStatus.innerHTML = ` -
Letzter Lauf${finished}
-
Geprueft${session.scanned ?? '--'}
-
Aktualisiert${session.updated ?? '--'}
-
Fehler${session.failed ?? '--'}
- `; + watchtowerStatus.innerHTML = officialHtml; } function renderContainers(containers) { @@ -377,7 +374,7 @@ function renderContainers(containers) {
${container.name} ${container.status} -
diff --git a/server.js b/server.js index e5ad192..47f4172 100644 --- a/server.js +++ b/server.js @@ -205,6 +205,15 @@ function canRestartContainer(container) { return container.state === 'running' || container.State === 'running'; } +function restartBlockReason(container) { + const name = normalizeContainerName(container.name || container.Names?.[0]); + if (!name) return 'Kein Containername.'; + if (RESTART_BLOCKLIST.has(name)) return 'Geschuetzter Systemdienst.'; + if (name.endsWith('_db') || name.includes('-db')) return 'Datenbank-Container.'; + if (container.state !== 'running' && container.State !== 'running') return 'Container laeuft nicht.'; + return null; +} + function dockerLogs(container, tail = 160) { return new Promise((resolve, reject) => { const endpoint = `/containers/${encodeURIComponent(container)}/logs?stdout=1&stderr=1&tail=${tail}`; @@ -252,6 +261,7 @@ async function getContainers() { status: container.Status, state: container.State, restartable: canRestartContainer(container), + restartBlockReason: restartBlockReason(container), ports: (container.Ports || []).map((port) => ({ privatePort: port.PrivatePort, publicPort: port.PublicPort, @@ -400,6 +410,8 @@ async function readWatchtowerRunContainer(runId) { session: parsed, tail: Array.isArray(logs) ? logs.slice(-20) : logs }; + + return payload; } async function monitorWatchtowerRun(runId) { diff --git a/style.css b/style.css index 5e33454..2a75c22 100644 --- a/style.css +++ b/style.css @@ -573,6 +573,12 @@ main { color: #fde68a; } +.ops-divider { + height: 1px; + margin: 2px 0; + background: var(--border); +} + .usage-bar { height: 7px; overflow: hidden;