Fix NODE column in backups to show actual guest node

Related to discussion #577

When backups are stored on shared storage accessible from multiple nodes,
the backup polling code was incorrectly assigning the backup to whichever
node it was discovered on during the scan, rather than the node where the
VM/container actually resides.

This fix:
- Builds a lookup map of VMID -> actual node at the start of backup polling
- Uses this map to assign the correct node for guest backups (VMID > 0)
- Preserves existing behavior for host backups (VMID == 0)
- Falls back to the queried node if the guest is not found in the map

This ensures the NODE column accurately reflects which node hosts each
guest, matching the information displayed on the main page.
This commit is contained in:
rcourtman 2025-11-05 19:38:32 +00:00
parent b1488620b1
commit 9670afe0cb

View file

@ -7735,6 +7735,20 @@ func (m *Monitor) pollStorageBackupsWithNodes(ctx context.Context, instanceName
contentFailures := 0 // Number of failed storage content fetches
storageQueryErrors := 0 // Number of nodes where storage list could not be queried
// Build guest lookup map to find actual node for each VMID
snapshot := m.state.GetSnapshot()
guestNodeMap := make(map[int]string) // VMID -> actual node name
for _, vm := range snapshot.VMs {
if vm.Instance == instanceName {
guestNodeMap[vm.VMID] = vm.Node
}
}
for _, ct := range snapshot.Containers {
if ct.Instance == instanceName {
guestNodeMap[int(ct.VMID)] = ct.Node
}
}
// For each node, get storage and check content
for _, node := range nodes {
if nodeEffectiveStatus[node.Node] != "online" {
@ -7828,8 +7842,15 @@ func (m *Monitor) pollStorageBackupsWithNodes(ctx context.Context, instanceName
backupType = "qemu"
}
// Always use the actual node name
// Determine the correct node: for guest backups (VMID > 0), use the actual guest's node
// For host backups (VMID == 0), use the node where the backup was found
backupNode := node.Node
if content.VMID > 0 {
if actualNode, found := guestNodeMap[content.VMID]; found {
backupNode = actualNode
}
// If not found in map, fall back to queried node (shouldn't happen normally)
}
isPBSStorage := strings.HasPrefix(storage.Storage, "pbs-") || storage.Type == "pbs"
// Check verification status for PBS backups