Show manual Watchtower run status
All checks were successful
Build & Push Docker Image to Gitea Registry / build-and-push (push) Successful in 12s

This commit is contained in:
Kroonk
2026-05-21 16:49:41 +02:00
parent e98130d274
commit c3ac1be083
3 changed files with 123 additions and 3 deletions

View File

@@ -27,6 +27,8 @@ const containerStatus = document.querySelector('#containerStatus');
let config = null;
let tokenSet = null;
let opsRefreshTimer = null;
let latestWatchtower = null;
let lastManualWatchtowerRun = null;
function base64UrlEncode(buffer) {
return btoa(String.fromCharCode(...new Uint8Array(buffer)))
@@ -312,6 +314,23 @@ function renderDisks(disks = []) {
}
function renderWatchtower(watchtower) {
latestWatchtower = watchtower;
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 = `
<div class="ops-line"><strong>Manueller Lauf</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>Fertig</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 ?? (run.exitCode ? 1 : 0)}</span></div>
`;
return;
}
const session = watchtower?.lastSession;
if (!session) {
const tail = watchtower?.tail?.slice(-4)?.join(' | ');
@@ -424,12 +443,20 @@ async function runWatchtowerOnce() {
const payload = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(payload.error || `HTTP ${response.status}`);
lastManualWatchtowerRun = {
id: payload.fullId || payload.id,
name: payload.name,
running: true,
startedAt: payload.startedAt,
session: null,
tail: []
};
watchtowerStatus.innerHTML = `
<div class="ops-line"><strong>Manueller Lauf</strong><span>Gestartet</span></div>
<div class="ops-line"><strong>Container</strong><span>${payload.name}</span></div>
`;
window.clearTimeout(opsRefreshTimer);
opsRefreshTimer = window.setTimeout(refreshOps, 25000);
pollWatchtowerRun(payload.fullId || payload.id);
} catch (error) {
watchtowerStatus.textContent = `Watchtower konnte nicht gestartet werden: ${error.message}`;
} finally {
@@ -440,6 +467,32 @@ async function runWatchtowerOnce() {
}
}
async function pollWatchtowerRun(runId, attempt = 0) {
try {
const cleanup = attempt > 0 ? '&cleanup=1' : '';
const response = await fetch(`/api/watchtower/runs/${encodeURIComponent(runId)}?${cleanup}`, {
cache: 'no-store',
headers: {
Authorization: `Bearer ${tokenSet.id_token}`
}
});
const payload = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(payload.error || `HTTP ${response.status}`);
lastManualWatchtowerRun = payload;
renderWatchtower(latestWatchtower);
if (payload.running && attempt < 36) {
opsRefreshTimer = window.setTimeout(() => pollWatchtowerRun(runId, attempt + 1), 5000);
return;
}
opsRefreshTimer = window.setTimeout(refreshOps, 4000);
} catch (error) {
watchtowerStatus.textContent = `Manueller Watchtower-Lauf nicht lesbar: ${error.message}`;
}
}
async function refreshOps() {
diskStatus.textContent = 'Lade...';
watchtowerStatus.textContent = 'Lade...';