From b47845ecb88dcbc7015f47b7ae1a8808b49a0153 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 30 Sep 2025 21:57:05 +0000 Subject: [PATCH] fix: add instance field to backup/snapshot structs for duplicate node names addresses #476 added Instance field to StorageBackup and GuestSnapshot structs in both backend and frontend to properly handle nodes with duplicate hostnames. updated backup and snapshot counting logic to use instance ID instead of hostname, consistent with the VM/container/storage count fixes. this completes the fix for #476 - all counts and groupings now use unique instance IDs instead of hostnames. --- .../src/components/shared/UnifiedNodeSelector.tsx | 6 +++--- frontend-modern/src/types/api.ts | 2 ++ internal/models/models.go | 2 ++ internal/monitoring/monitor.go | 3 +++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx b/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx index b50d7c0b7..bd084cf84 100644 --- a/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx +++ b/frontend-modern/src/components/shared/UnifiedNodeSelector.tsx @@ -47,7 +47,7 @@ export const UnifiedNodeSelector: Component = (props) const backupCounts = createMemo(() => { const counts: Record = {}; - // Count PVE backups and snapshots by node + // Count PVE backups and snapshots by node instance ID (not hostname) const nodes = props.nodes || state.nodes; if (nodes) { nodes.forEach((node) => { @@ -56,13 +56,13 @@ export const UnifiedNodeSelector: Component = (props) // Count storage backups (excluding PBS backups which are counted separately) if (state.pveBackups?.storageBackups) { count += state.pveBackups.storageBackups.filter( - (b) => b.node === node.name && !b.isPBS, + (b) => b.instance === node.id && !b.isPBS, ).length; } // Count snapshots if (state.pveBackups?.guestSnapshots) { - count += state.pveBackups.guestSnapshots.filter((s) => s.node === node.name).length; + count += state.pveBackups.guestSnapshots.filter((s) => s.instance === node.id).length; } counts[node.name] = count; diff --git a/frontend-modern/src/types/api.ts b/frontend-modern/src/types/api.ts index 8eb687b3c..956a80ce5 100644 --- a/frontend-modern/src/types/api.ts +++ b/frontend-modern/src/types/api.ts @@ -318,6 +318,7 @@ export interface StorageBackup { id: string; storage: string; node: string; + instance: string; type: string; vmid: number; time: string; @@ -343,6 +344,7 @@ export interface GuestSnapshot { id: string; name: string; node: string; + instance: string; type: string; vmid: number; time: string; diff --git a/internal/models/models.go b/internal/models/models.go index 2cb0e4454..1418f6d54 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -374,6 +374,7 @@ type StorageBackup struct { ID string `json:"id"` Storage string `json:"storage"` Node string `json:"node"` + Instance string `json:"instance"` // Unique instance identifier (for nodes with duplicate names) Type string `json:"type"` VMID int `json:"vmid"` Time time.Time `json:"time"` @@ -393,6 +394,7 @@ type GuestSnapshot struct { ID string `json:"id"` Name string `json:"name"` Node string `json:"node"` + Instance string `json:"instance"` // Unique instance identifier (for nodes with duplicate names) Type string `json:"type"` VMID int `json:"vmid"` Time time.Time `json:"time"` diff --git a/internal/monitoring/monitor.go b/internal/monitoring/monitor.go index 6e1e140c7..e53739733 100644 --- a/internal/monitoring/monitor.go +++ b/internal/monitoring/monitor.go @@ -3247,6 +3247,7 @@ func (m *Monitor) pollStorageBackupsWithNodes(ctx context.Context, instanceName ID: fmt.Sprintf("%s-%s", instanceName, content.Volid), Storage: storage.Storage, Node: backupNode, + Instance: instanceName, Type: backupType, VMID: content.VMID, Time: time.Unix(content.CTime, 0), @@ -3316,6 +3317,7 @@ func (m *Monitor) pollGuestSnapshots(ctx context.Context, instanceName string, c ID: fmt.Sprintf("%s-%s-%d-%s", instanceName, vm.Node, vm.VMID, snap.Name), Name: snap.Name, Node: vm.Node, + Instance: instanceName, Type: "qemu", VMID: vm.VMID, Time: time.Unix(snap.SnapTime, 0), @@ -3358,6 +3360,7 @@ func (m *Monitor) pollGuestSnapshots(ctx context.Context, instanceName string, c ID: fmt.Sprintf("%s-%s-%d-%s", instanceName, ct.Node, ct.VMID, snap.Name), Name: snap.Name, Node: ct.Node, + Instance: instanceName, Type: "lxc", VMID: ct.VMID, Time: time.Unix(snap.SnapTime, 0),