Add per-backup status dot (green/yellow/red/unknown) to the UI
backup-k8s-apps.sh now tracks step-level failures (manifests, secret,
db_dump, pvc_data) into an ERRORS array during the per-app loop, and
writes a .meta.json sidecar alongside each archive once all 3 storage
tiers are known - apps included, final size, the error list, and
per-tier ok/failed/skipped status. Sidecar is mirrored to VM/R2 the
same best-effort way the .sha256 sidecar already is, and cleaned up
by both local and R2 retention pruning plus manual delete.
modules/backups.py reads these sidecars (never decompresses the
archive) to compute a status per backup at list-render time:
- red: any recorded error, or any tier status starting with "failed"
- yellow: no errors, but size deviates >40% from the rolling average
of the last 5 backups sharing the same app-combination (apps_key)
- green: no errors, size within range (or first backup of its
app-combination - nothing to compare against yet)
- unknown: no sidecar at all (legacy myapps-backup-* archives, or
any k8s backup made before this shipped) - no backfill attempted,
old runs never recorded step-level failures to reconstruct from
/backups route now passes get_local_backups_with_status()/
get_vm_backups_with_status() instead of the plain filename lists
(get_local_backups()/get_vm_backups() themselves are untouched -
/restore and /api/backups still use the plain versions, they don't
need the dot). Template renders a colored dot next to each entry with
a tooltip showing apps/size.
Verified: real n8n backup produces a correct sidecar synced to all 3
tiers; JSON-writer argv parsing and the red/yellow/green/unknown
decision logic each checked against synthetic cases; full Jinja render
checked against real local + VM data pulled from the live pod.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017avLHFqkiti3g62Anq9sVA
This commit is contained in:
@@ -17,6 +17,7 @@ from modules.auth import login_required
|
||||
from modules.backups import (
|
||||
get_containers, get_all_root_containers,
|
||||
get_local_backups, get_vm_backups,
|
||||
get_local_backups_with_status, get_vm_backups_with_status,
|
||||
get_all_stats, get_system_info,
|
||||
get_rootless_user_containers_remote,
|
||||
container_action, get_container_status,
|
||||
@@ -169,8 +170,8 @@ def cluster_page():
|
||||
def backups_page():
|
||||
return render_template(
|
||||
'pages/backups.html',
|
||||
backups=get_local_backups(),
|
||||
vm_backups=get_vm_backups(),
|
||||
backups=get_local_backups_with_status(),
|
||||
vm_backups=get_vm_backups_with_status(),
|
||||
main_server=MAIN_SERVER_IP,
|
||||
active_page='backups',
|
||||
page_title='Backup Management',
|
||||
|
||||
Reference in New Issue
Block a user