Management pollt jetzt offene Agent-Jobs und aktualisiert job_history mit: - finalem success / failed - Fehlertext - aktuellem/finalem Step - finishedAt - durationMs - Snapshot-ID aus den Agent-Logs, wenn ein Backup erfolgreich war Die Operations-Seite zeigt jetzt Dauer und Snapshot-ID. Issue 2: erweiterte Agent-Healthchecks /api/health am Agent prüft jetzt strukturiert: - fehlende Env-Konfiguration - Commands: incus, zfs, zpool, restic, udevadm, dd - ZFS Pool Existenz - ZFS Pool Capacity/Freespace via zpool list - /dev/zvol Zugriff - Restic Repository Zugriff
44 lines
1.2 KiB
JavaScript
44 lines
1.2 KiB
JavaScript
import { agentRequest } from './agentClient.js';
|
|
import { listOpenJobHistory, updateJobHistory } from './store.js';
|
|
|
|
let timer = null;
|
|
|
|
export function startJobPoller() {
|
|
if (timer) return;
|
|
timer = setInterval(pollJobs, 5000);
|
|
timer.unref?.();
|
|
pollJobs();
|
|
}
|
|
|
|
async function pollJobs() {
|
|
const jobs = listOpenJobHistory();
|
|
await Promise.all(jobs.map(async (history) => {
|
|
try {
|
|
const job = await agentRequest({
|
|
id: history.node_id,
|
|
baseUrl: history.base_url,
|
|
token: history.token,
|
|
}, `/jobs/${encodeURIComponent(history.agent_job_id)}`, { timeout: 10000 });
|
|
|
|
updateJobHistory(history.id, {
|
|
status: job.status,
|
|
error: job.error,
|
|
currentStep: job.currentStep,
|
|
snapshotId: findSnapshotId(job),
|
|
finishedAt: job.finishedAt,
|
|
});
|
|
} catch (error) {
|
|
updateJobHistory(history.id, {
|
|
status: 'failed',
|
|
error: error.message,
|
|
finishedAt: new Date().toISOString(),
|
|
});
|
|
}
|
|
}));
|
|
}
|
|
|
|
function findSnapshotId(job) {
|
|
const line = [...(job.logs || [])].reverse().find((entry) => /^snapshot [a-f0-9]+ saved$/i.test(entry));
|
|
return line ? line.split(' ')[1] : null;
|
|
}
|