Gestoppte VM zeigt weiter Update-Banner — Node-Aggregation gated nicht auf VM-Status #30

Closed
opened 2026-06-01 21:16:38 +00:00 by chinux · 0 comments
Owner

Symptom

Eine VM ist auf dem Node nicht mehr aktiv (gestoppt/disabled), das System zeigt aber weiterhin ein „Updates verfügbar"-Banner für diese VM an.

Root Cause

server/routers/admin_router.py:184-185 aggregiert die Node-Update-Zähler:

d["updates_pending"]  = sum(1 for s in vm_scans.values() if s.get("agent_available") and s.get("updates", {}).get("available", 0) > 0)
d["updates_security"] = sum(1 for s in vm_scans.values() if s.get("agent_available") and s.get("updates", {}).get("security",  0) > 0)

Gezählt wird über vm_scans nur nach agent_available + gecachtem updates.available > 0der aktuelle VM-Status wird nicht geprüft. Eine gestoppte VM scannt nicht mehr, behält aber ihren letzten Scan (agent_available: true, updates.available: N) → zählt weiter.

Das Banner kommt aus frontend/src/routes/(app)/+layout.svelte loadAlerts (Z. 38-41), das n.updates_security / n.updates_pending rendert. Der Fehler liegt also in der Backend-Aggregation, nicht im Banner selbst.

Fix

In admin_router.py direkt vor Z. 184 die Menge der laufenden VMs/CTs bilden und die Zähler darauf gaten (der VM-Status liegt in d["vms"]/d["cts"] als status):

running = { str(v.get("vmid")) for v in d["vms"] if v.get("status") == "running" }
running |= { str(c.get("vmid")) for c in d["cts"] if c.get("status") == "running" }
d["updates_pending"]  = sum(1 for vmid, s in vm_scans.items()
                            if str(vmid) in running and s.get("agent_available")
                            and s.get("updates", {}).get("available", 0) > 0)
d["updates_security"] = sum(1 for vmid, s in vm_scans.items()
                            if str(vmid) in running and s.get("agent_available")
                            and s.get("updates", {}).get("security", 0) > 0)

(Display-time-Gating, kein Datenverlust — startet die VM wieder, zählt sie sofort wieder mit.)

Gleicher Wurzelgrund, optional mit anpassen

Das per-VM-Update-Feld im Detail-Endpoint (admin_router.py:971, "updates": s.get("updates", {}).get("available", 0)) zeigt für gestoppte VMs ebenfalls den veralteten Cache. Für Konsistenz dort den Wert auf 0/None setzen bzw. ein stale: true mitgeben, wenn die VM nicht läuft — damit auch in Listen/Tabs kein veralteter Stand erscheint. (Kann separat, aber gleiche Ursache.)

Akzeptanz

  • Gestoppte/disabled VM trägt nicht mehr zum Node-Update-Banner bei.
  • Läuft die VM wieder, erscheint der Stand sofort wieder.
  • Laufende VMs mit Updates: unverändert.

Branch

fix/updates-banner-stopped-vm

## Symptom Eine VM ist auf dem Node nicht mehr aktiv (gestoppt/disabled), das System zeigt aber weiterhin ein „Updates verfügbar"-Banner für diese VM an. ## Root Cause `server/routers/admin_router.py:184-185` aggregiert die Node-Update-Zähler: ```python d["updates_pending"] = sum(1 for s in vm_scans.values() if s.get("agent_available") and s.get("updates", {}).get("available", 0) > 0) d["updates_security"] = sum(1 for s in vm_scans.values() if s.get("agent_available") and s.get("updates", {}).get("security", 0) > 0) ``` Gezählt wird über `vm_scans` nur nach `agent_available` + gecachtem `updates.available > 0` — **der aktuelle VM-Status wird nicht geprüft**. Eine gestoppte VM scannt nicht mehr, behält aber ihren letzten Scan (`agent_available: true`, `updates.available: N`) → zählt weiter. Das Banner kommt aus `frontend/src/routes/(app)/+layout.svelte` `loadAlerts` (Z. 38-41), das `n.updates_security` / `n.updates_pending` rendert. Der Fehler liegt also in der Backend-Aggregation, nicht im Banner selbst. ## Fix In `admin_router.py` direkt vor Z. 184 die Menge der laufenden VMs/CTs bilden und die Zähler darauf gaten (der VM-Status liegt in `d["vms"]`/`d["cts"]` als `status`): ```python running = { str(v.get("vmid")) for v in d["vms"] if v.get("status") == "running" } running |= { str(c.get("vmid")) for c in d["cts"] if c.get("status") == "running" } d["updates_pending"] = sum(1 for vmid, s in vm_scans.items() if str(vmid) in running and s.get("agent_available") and s.get("updates", {}).get("available", 0) > 0) d["updates_security"] = sum(1 for vmid, s in vm_scans.items() if str(vmid) in running and s.get("agent_available") and s.get("updates", {}).get("security", 0) > 0) ``` (Display-time-Gating, kein Datenverlust — startet die VM wieder, zählt sie sofort wieder mit.) ## Gleicher Wurzelgrund, optional mit anpassen Das per-VM-Update-Feld im Detail-Endpoint (`admin_router.py:971`, `"updates": s.get("updates", {}).get("available", 0)`) zeigt für gestoppte VMs ebenfalls den veralteten Cache. Für Konsistenz dort den Wert auf `0`/`None` setzen bzw. ein `stale: true` mitgeben, wenn die VM nicht läuft — damit auch in Listen/Tabs kein veralteter Stand erscheint. (Kann separat, aber gleiche Ursache.) ## Akzeptanz - Gestoppte/disabled VM trägt **nicht** mehr zum Node-Update-Banner bei. - Läuft die VM wieder, erscheint der Stand sofort wieder. - Laufende VMs mit Updates: unverändert. ## Branch `fix/updates-banner-stopped-vm`
chinux changed title from Disabeld VM's always Show Updates Cache error to Gestoppte VM zeigt weiter Update-Banner — Node-Aggregation gated nicht auf VM-Status 2026-06-01 21:21:25 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
chinux/theProx#30
No description provided.