feat: fix watchtower manual run stuck states in both client and server
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 18:25:27 +02:00
parent 76b7a96673
commit b3c1fbc9bd
3 changed files with 35 additions and 4 deletions

View File

@@ -90,6 +90,6 @@
</section> </section>
</main> </main>
<script src="/admin.js?v=15" defer></script> <script src="/admin.js?v=16" defer></script>
</body> </body>
</html> </html>

View File

@@ -646,7 +646,7 @@ async function pollWatchtowerRun(runId, attempt = 0) {
lastManualWatchtowerRun = payload; lastManualWatchtowerRun = payload;
renderWatchtower(latestWatchtower); renderWatchtower(latestWatchtower);
if (payload.running && attempt < 36) { if (payload.running && attempt < 60) {
opsRefreshTimer = window.setTimeout(() => pollWatchtowerRun(runId, attempt + 1), 5000); opsRefreshTimer = window.setTimeout(() => pollWatchtowerRun(runId, attempt + 1), 5000);
return; return;
} }
@@ -668,6 +668,24 @@ async function refreshOps(options = {}) {
} }
} }
if (lastManualWatchtowerRun && lastManualWatchtowerRun.running) {
try {
const runId = lastManualWatchtowerRun.id;
const response = await fetch(`/api/watchtower/runs/${encodeURIComponent(runId)}`, {
cache: 'no-store',
headers: {
Authorization: `Bearer ${tokenSet?.id_token}`
}
});
if (response.ok) {
const payload = await response.json().catch(() => ({}));
lastManualWatchtowerRun = payload;
}
} catch (e) {
console.warn('Failed to refresh manual watchtower run status:', e);
}
}
try { try {
const response = await fetch('/api/status', { cache: 'no-store' }); const response = await fetch('/api/status', { cache: 'no-store' });
if (!response.ok) throw new Error(`HTTP ${response.status}`); if (!response.ok) throw new Error(`HTTP ${response.status}`);

View File

@@ -461,12 +461,25 @@ async function getWatchtowerRun(runId) {
} }
if (manualWatchtowerRuns.has(id)) { if (manualWatchtowerRuns.has(id)) {
return manualWatchtowerRuns.get(id); const cached = manualWatchtowerRuns.get(id);
if (!cached.running) {
return cached;
}
} }
try { try {
return await readWatchtowerRunContainer(id); const livePayload = await readWatchtowerRunContainer(id);
manualWatchtowerRuns.set(id, livePayload);
if (!livePayload.running) {
removeContainer(id).catch(() => {});
}
return livePayload;
} catch (error) { } catch (error) {
if (manualWatchtowerRuns.has(id)) {
return manualWatchtowerRuns.get(id);
}
error.statusCode = error.statusCode || 404; error.statusCode = error.statusCode || 404;
throw error; throw error;
} }