Fix admin ops status refresh
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 12s
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 12s
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
<title>MischLabs Admin</title>
|
<title>MischLabs Admin</title>
|
||||||
<meta name="description" content="MischLabs dashboard administration.">
|
<meta name="description" content="MischLabs dashboard administration.">
|
||||||
<meta name="theme-color" content="#0f172a">
|
<meta name="theme-color" content="#0f172a">
|
||||||
<link rel="stylesheet" href="/style.css?v=15">
|
<link rel="stylesheet" href="/style.css?v=16">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="shell hero admin-hero">
|
<header class="shell hero admin-hero">
|
||||||
@@ -81,6 +81,6 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="/admin.js?v=8" defer></script>
|
<script src="/admin.js?v=9" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
39
admin.js
39
admin.js
@@ -315,38 +315,35 @@ function renderDisks(disks = []) {
|
|||||||
|
|
||||||
function renderWatchtower(watchtower) {
|
function renderWatchtower(watchtower) {
|
||||||
latestWatchtower = watchtower;
|
latestWatchtower = watchtower;
|
||||||
|
const officialSession = watchtower?.lastSession;
|
||||||
|
const officialHtml = officialSession
|
||||||
|
? `
|
||||||
|
<div class="ops-line"><strong>Offizieller Lauf</strong><span>${officialSession.finishedAt ? new Date(officialSession.finishedAt).toLocaleString('de-DE') : '--'}</span></div>
|
||||||
|
<div class="ops-line"><strong>Geprueft</strong><span>${officialSession.scanned ?? '--'}</span></div>
|
||||||
|
<div class="ops-line"><strong>Aktualisiert</strong><span>${officialSession.updated ?? '--'}</span></div>
|
||||||
|
<div class="ops-line"><strong>Fehler</strong><span>${officialSession.failed ?? '--'}</span></div>
|
||||||
|
`
|
||||||
|
: `<div class="ops-line"><strong>Offizieller Lauf</strong><span>${watchtower?.tail?.slice(-2)?.join(' | ') || 'Noch nicht gefunden'}</span></div>`;
|
||||||
|
|
||||||
if (lastManualWatchtowerRun) {
|
if (lastManualWatchtowerRun) {
|
||||||
const run = lastManualWatchtowerRun;
|
const run = lastManualWatchtowerRun;
|
||||||
const session = run.session;
|
const session = run.session;
|
||||||
const finished = run.finishedAt ? new Date(run.finishedAt).toLocaleString('de-DE') : 'laeuft noch';
|
const finished = run.finishedAt ? new Date(run.finishedAt).toLocaleString('de-DE') : 'laeuft noch';
|
||||||
const state = run.running ? 'Laeuft' : `Beendet (${run.exitCode ?? '--'})`;
|
const state = run.running ? 'Laeuft' : `Beendet (${run.exitCode ?? '--'})`;
|
||||||
watchtowerStatus.innerHTML = `
|
watchtowerStatus.innerHTML = `
|
||||||
<div class="ops-line"><strong>Manueller Lauf</strong><span>${state}</span></div>
|
${officialHtml}
|
||||||
|
<div class="ops-divider"></div>
|
||||||
|
<div class="ops-line"><strong>Manuell</strong><span>${state}</span></div>
|
||||||
<div class="ops-line"><strong>Gestartet</strong><span>${run.startedAt ? new Date(run.startedAt).toLocaleString('de-DE') : '--'}</span></div>
|
<div class="ops-line"><strong>Gestartet</strong><span>${run.startedAt ? new Date(run.startedAt).toLocaleString('de-DE') : '--'}</span></div>
|
||||||
<div class="ops-line"><strong>Fertig</strong><span>${finished}</span></div>
|
<div class="ops-line"><strong>Fertig</strong><span>${finished}</span></div>
|
||||||
<div class="ops-line"><strong>Geprueft</strong><span>${session?.scanned ?? '--'}</span></div>
|
<div class="ops-line"><strong>Manuell geprueft</strong><span>${session?.scanned ?? '--'}</span></div>
|
||||||
<div class="ops-line"><strong>Aktualisiert</strong><span>${session?.updated ?? '--'}</span></div>
|
<div class="ops-line"><strong>Manuell aktualisiert</strong><span>${session?.updated ?? '--'}</span></div>
|
||||||
<div class="ops-line"><strong>Fehler</strong><span>${session?.failed ?? (run.exitCode ? 1 : 0)}</span></div>
|
<div class="ops-line"><strong>Manuelle Fehler</strong><span>${session?.failed ?? (run.exitCode ? 1 : 0)}</span></div>
|
||||||
`;
|
`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const session = watchtower?.lastSession;
|
watchtowerStatus.innerHTML = officialHtml;
|
||||||
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 = `
|
|
||||||
<div class="ops-line"><strong>Letzter Lauf</strong><span>${finished}</span></div>
|
|
||||||
<div class="ops-line"><strong>Geprueft</strong><span>${session.scanned ?? '--'}</span></div>
|
|
||||||
<div class="ops-line"><strong>Aktualisiert</strong><span>${session.updated ?? '--'}</span></div>
|
|
||||||
<div class="ops-line"><strong>Fehler</strong><span>${session.failed ?? '--'}</span></div>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderContainers(containers) {
|
function renderContainers(containers) {
|
||||||
@@ -377,7 +374,7 @@ function renderContainers(containers) {
|
|||||||
<div class="ops-line container-line" data-container="${container.name}">
|
<div class="ops-line container-line" data-container="${container.name}">
|
||||||
<strong>${container.name}</strong>
|
<strong>${container.name}</strong>
|
||||||
<span>${container.status}</span>
|
<span>${container.status}</span>
|
||||||
<button class="ghost-button mini restart-container" type="button" ${container.restartable ? '' : 'disabled'}>
|
<button class="ghost-button mini restart-container" type="button" title="${container.restartable ? 'Container neu starten' : (container.restartBlockReason || 'Neustart gesperrt')}" ${container.restartable ? '' : 'disabled'}>
|
||||||
Neustarten
|
Neustarten
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
12
server.js
12
server.js
@@ -205,6 +205,15 @@ function canRestartContainer(container) {
|
|||||||
return container.state === 'running' || container.State === 'running';
|
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) {
|
function dockerLogs(container, tail = 160) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const endpoint = `/containers/${encodeURIComponent(container)}/logs?stdout=1&stderr=1&tail=${tail}`;
|
const endpoint = `/containers/${encodeURIComponent(container)}/logs?stdout=1&stderr=1&tail=${tail}`;
|
||||||
@@ -252,6 +261,7 @@ async function getContainers() {
|
|||||||
status: container.Status,
|
status: container.Status,
|
||||||
state: container.State,
|
state: container.State,
|
||||||
restartable: canRestartContainer(container),
|
restartable: canRestartContainer(container),
|
||||||
|
restartBlockReason: restartBlockReason(container),
|
||||||
ports: (container.Ports || []).map((port) => ({
|
ports: (container.Ports || []).map((port) => ({
|
||||||
privatePort: port.PrivatePort,
|
privatePort: port.PrivatePort,
|
||||||
publicPort: port.PublicPort,
|
publicPort: port.PublicPort,
|
||||||
@@ -400,6 +410,8 @@ async function readWatchtowerRunContainer(runId) {
|
|||||||
session: parsed,
|
session: parsed,
|
||||||
tail: Array.isArray(logs) ? logs.slice(-20) : logs
|
tail: Array.isArray(logs) ? logs.slice(-20) : logs
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function monitorWatchtowerRun(runId) {
|
async function monitorWatchtowerRun(runId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user