Fix backup indicator being reset when VMs/Containers are re-polled

UpdateVMsForInstance and UpdateContainersForInstance were replacing
guest data without preserving the LastBackup field that was populated
by SyncGuestBackupTimes. This caused backup indicators to always show
"no backup found" since the LastBackup would be wiped every time
guests were polled (which happens more frequently than backup polling).

Now both functions preserve LastBackup from existing data when the
incoming guest data has a zero value.

Related to #762
This commit is contained in:
rcourtman 2025-12-02 00:11:33 +00:00
parent 9baf99d32a
commit 8597eca010
2 changed files with 49 additions and 2 deletions

View file

@ -616,6 +616,31 @@ func TestGetLockoutInfo(t *testing.T) {
t.Error("expected lockedUntil to be set")
}
})
t.Run("expired lockout returns zeros", func(t *testing.T) {
resetFailedLogins()
identifier := "expired-lockout-user"
// Directly set an expired lockout entry
failedMu.Lock()
failedLogins[identifier] = &FailedLogin{
Count: maxFailedAttempts,
LastAttempt: time.Now().Add(-time.Hour),
LockedUntil: time.Now().Add(-time.Minute), // Expired
}
failedMu.Unlock()
attempts, lockedUntil, isLocked := GetLockoutInfo(identifier)
if attempts != 0 {
t.Errorf("attempts = %d, want 0 for expired lockout", attempts)
}
if !lockedUntil.IsZero() {
t.Errorf("lockedUntil = %v, want zero time for expired lockout", lockedUntil)
}
if isLocked {
t.Error("expected isLocked = false for expired lockout")
}
})
}
func TestResetLockout(t *testing.T) {

View file

@ -1083,6 +1083,14 @@ func (s *State) UpdateVMsForInstance(instanceName string, vms []VM) {
s.mu.Lock()
defer s.mu.Unlock()
// Build a lookup of existing VMs for this instance to preserve LastBackup
existingByVMID := make(map[int]VM)
for _, vm := range s.VMs {
if vm.Instance == instanceName {
existingByVMID[vm.VMID] = vm
}
}
// Create a map of existing VMs, excluding those from this instance
vmMap := make(map[string]VM)
for _, vm := range s.VMs {
@ -1091,8 +1099,11 @@ func (s *State) UpdateVMsForInstance(instanceName string, vms []VM) {
}
}
// Add or update VMs from this instance
// Add or update VMs from this instance, preserving LastBackup from existing data
for _, vm := range vms {
if existing, ok := existingByVMID[vm.VMID]; ok && vm.LastBackup.IsZero() {
vm.LastBackup = existing.LastBackup
}
vmMap[vm.ID] = vm
}
@ -1169,6 +1180,14 @@ func (s *State) UpdateContainersForInstance(instanceName string, containers []Co
s.mu.Lock()
defer s.mu.Unlock()
// Build a lookup of existing containers for this instance to preserve LastBackup
existingByVMID := make(map[int]Container)
for _, ct := range s.Containers {
if ct.Instance == instanceName {
existingByVMID[ct.VMID] = ct
}
}
// Create a map of existing containers, excluding those from this instance
containerMap := make(map[string]Container)
for _, container := range s.Containers {
@ -1177,8 +1196,11 @@ func (s *State) UpdateContainersForInstance(instanceName string, containers []Co
}
}
// Add or update containers from this instance
// Add or update containers from this instance, preserving LastBackup from existing data
for _, container := range containers {
if existing, ok := existingByVMID[container.VMID]; ok && container.LastBackup.IsZero() {
container.LastBackup = existing.LastBackup
}
containerMap[container.ID] = container
}