Fix Proxmox workload refresh coherence

This commit is contained in:
rcourtman
2026-07-24 10:08:28 +01:00
parent cdb5797468
commit ac0fb263c2
32 changed files with 964 additions and 68 deletions
@@ -27,6 +27,14 @@ Monitoring owns source freshness cadence for Proxmox, PBS, and PMG resources:
the stale threshold is derived from the configured polling interval with a
minimum floor, so API-facing resource status must not degrade merely because a
healthy source is between normal poll cycles.
Proxmox guest enumeration is a generation boundary. VM and LXC collection and
enrichment must finish before one `State.UpdateGuestsForInstance` publication,
so readers never observe a VM-only or LXC-only intermediate snapshot. A failed
online cluster member retains only that member's last coherent guests and their
source-native `{instance}:{node}:{vmid}` IDs; a successful empty member
enumeration is authoritative and removes genuinely deleted guests. Collection
failure remains visible through source freshness/error state and must not be
converted into an authoritative empty inventory.
Host-agent report liveness is server-observed, not agent-clock-observed:
`ApplyHostReport` must stamp `Host.LastSeen`, agent-sourced Ceph cluster
freshness, and host-agent cluster sensor freshness from Pulse receipt time, so
@@ -213,6 +221,7 @@ node-local Agent evidence.
36. `internal/dockeragent/docker_client.go`
37. `pkg/agents/docker/report.go`
38. `internal/models/models.go`
38a. `internal/models/proxmox_guest_state.go`
39. `internal/models/models_frontend.go`
40. `internal/models/converters.go`
41. `internal/models/deepcopy.go`
@@ -854,6 +854,19 @@ shell clickable behind another overlay.
## Current State
### Workload refreshes retain one coherent paged generation
The workload polling cache accepts a REST refresh only when every advertised
page succeeds. A failed later page leaves the prior array and its stable row
identities in place, ends loading, and exposes the refresh error; it must not
publish a partial list, clear rows as a loading transition, or silently hide
the error. Proxmox workload filtering consumes the source-authored
`proxmox.runtimeStatus` before aggregate health so an availability-only
freshness update cannot collapse a Running view. A later complete response may
still remove an authoritatively deleted guest. These rules preserve sort,
selection, drawer, and virtualized viewport state without adding another
resource scan, websocket subscription, or browser-local source of truth.
### Canonical mutation-plane dependency
Router wiring now exposes only typed action planning for model-originated
@@ -5186,6 +5186,7 @@
"internal/models/deepcopy.go",
"internal/models/models.go",
"internal/models/models_frontend.go",
"internal/models/proxmox_guest_state.go",
"internal/proxmoxidentity/backup_identity.go",
"pkg/agents/docker/report.go",
"pkg/agents/host/report.go",
@@ -5398,6 +5399,7 @@
"internal/models/deepcopy.go",
"internal/models/models.go",
"internal/models/models_frontend.go",
"internal/models/proxmox_guest_state.go",
"pkg/agents/docker/report.go"
],
"allow_same_subsystem_tests": false,
@@ -1917,6 +1917,17 @@ that Safe auto-fix or Autopilot remediation is verified.
## Current State
### Proxmox runtime continuity is not protection evidence
The additive `ProxmoxData.RuntimeStatus` field preserves VM/LXC power-state
presentation while a platform snapshot is stale or refreshing. Storage and
recovery consumers must not interpret `running`, `stopped`, a retained guest
row, or an availability facet as backup freshness, protection coverage,
restore-chain verification, or recoverability. Authoritative guest deletion
may remove the inventory row and its canonical history identity, while
Recovery Assurance remains governed solely by its own backup and verification
evidence.
### Storage history remount state is bounded
Storage summary history no longer treats every node/range combination visited
@@ -43,6 +43,18 @@ comparable fallback because LXC observes the shared kernel and QEMU accounting
is independently scoped. Agent CPU may fill the field only when the platform
has no CPU observation. Agent-only fields that the platform does not provide
remain eligible per metric.
Proxmox guest power state is likewise source-authored semantic state, separate
from aggregate resource health. `ProxmoxData.RuntimeStatus` retains the last
coherent `running`/`stopped` observation while `Resource.Status` and
`SourceStatus` continue to report stale, warning, offline, availability, and
error evidence honestly. Availability checks may add facets and influence
aggregate health after Proxmox becomes stale, but they must not overwrite or
erase the Proxmox runtime state used by workload power filters. Full monitor
registry generations and incremental agent/availability mutations serialize
at the adapter boundary; a mutation that arrives during a rebuild must apply to
the newly published registry rather than a superseded pointer. Authoritative
snapshot omissions still remove resources and emit the normal canonical
history change.
Physical-disk resources own cross-source disk identity. When Proxmox inventory
and host-agent SMART telemetry describe the same device, the merged resource
must retain Proxmox node/instance source payloads while carrying SMART