Issue 1: finaler Agent-Job-Status
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
This commit is contained in:
@@ -31,13 +31,15 @@ export function Operations() {
|
||||
</div>
|
||||
{error ? <div className="rounded-md border border-red-900 bg-red-950/50 px-4 py-3 text-sm text-red-200">{error}</div> : null}
|
||||
<Table
|
||||
columns={['Time', 'Type', 'Node', 'VM', 'Status', 'Agent Job']}
|
||||
columns={['Time', 'Type', 'Node', 'VM', 'Status', 'Duration', 'Snapshot', 'Agent Job']}
|
||||
rows={history.map((row) => [
|
||||
formatTime(row.startedAt),
|
||||
row.type,
|
||||
row.nodeName,
|
||||
row.vmName,
|
||||
row.error || row.status,
|
||||
formatDuration(row.durationMs),
|
||||
row.snapshotId || '-',
|
||||
row.agentJobId || '-',
|
||||
])}
|
||||
title="Job History"
|
||||
@@ -86,3 +88,10 @@ function formatTime(value) {
|
||||
if (!value) return '-';
|
||||
return new Intl.DateTimeFormat(undefined, { dateStyle: 'short', timeStyle: 'medium' }).format(new Date(value));
|
||||
}
|
||||
|
||||
function formatDuration(value) {
|
||||
if (!value) return '-';
|
||||
const seconds = Math.round(Number(value) / 1000);
|
||||
if (seconds < 60) return `${seconds}s`;
|
||||
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user