Skip to content

Commit 3dfb89a

Browse files
authored
Fix a case when deleting element when looping (vmware-tanzu#1385)
When deleting stale entries in volume status, store the indexes first, then deletes them in a way without shifting indexes before deleting next one.
1 parent 5874b7e commit 3dfb89a

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

pkg/providers/vsphere/vmlifecycle/update_status.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,17 +1317,29 @@ func updateVolumeStatus(vmCtx pkgctx.VirtualMachineContext) {
13171317
existingDisksInStatus[vol.DiskUUID] = i
13181318
}
13191319
}
1320+
// Collect indices to delete first.
1321+
indicesToDelete := []int{}
13201322
for _, di := range info.Disks {
13211323
if volSpec, ok := info.Volumes[di.Target.String()]; ok {
13221324
if diskIndex, ok := existingDisksInStatus[di.UUID]; ok {
13231325
if volSpec.Name != vm.Status.Volumes[diskIndex].Name {
1324-
vmCtx.VM.Status.Volumes = slices.Delete(
1325-
vmCtx.VM.Status.Volumes, diskIndex, diskIndex+1)
1326+
indicesToDelete = append(indicesToDelete, diskIndex)
13261327
delete(existingDisksInStatus, di.UUID)
13271328
}
13281329
}
13291330
}
13301331
}
1332+
// Delete in reverse order so that we don't shift indices before deleting
1333+
// next one.
1334+
slices.Sort(indicesToDelete)
1335+
for i := len(indicesToDelete) - 1; i >= 0; i-- {
1336+
vm.Status.Volumes = slices.Delete(
1337+
vm.Status.Volumes,
1338+
indicesToDelete[i],
1339+
indicesToDelete[i]+1,
1340+
)
1341+
}
1342+
// Update existingDisksInStatus with new indexes.
13311343
for i := range vm.Status.Volumes {
13321344
if vol := vm.Status.Volumes[i]; vol.DiskUUID != "" {
13331345
existingDisksInStatus[vol.DiskUUID] = i

pkg/providers/vsphere/vmlifecycle/update_status_test.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,7 +1742,7 @@ var _ = Describe("UpdateStatus", func() {
17421742
})
17431743
})
17441744

1745-
When("vm.status.volumes has a stale (not in spec) classic disk", func() {
1745+
When("vm.status.volumes has two stale (not in spec) classic disks", func() {
17461746
BeforeEach(func() {
17471747
vmCtx.VM.Spec.Volumes = []vmopv1.VirtualMachineVolume{
17481748
{
@@ -1754,17 +1754,38 @@ var _ = Describe("UpdateStatus", func() {
17541754
ControllerBusNumber: ptr.To[int32](0),
17551755
UnitNumber: ptr.To[int32](3),
17561756
},
1757+
{
1758+
Name: pkgutil.GeneratePVCName("disk", "104"),
1759+
VirtualMachineVolumeSource: vmopv1.VirtualMachineVolumeSource{
1760+
PersistentVolumeClaim: &vmopv1.PersistentVolumeClaimVolumeSource{},
1761+
},
1762+
ControllerType: vmopv1.VirtualControllerTypeSCSI,
1763+
ControllerBusNumber: ptr.To[int32](0),
1764+
UnitNumber: ptr.To[int32](4),
1765+
},
17571766
}
17581767
vmCtx.VM.Status.Volumes = []vmopv1.VirtualMachineVolumeStatus{
17591768
{
1760-
Name: "my-old-name",
1769+
Name: "my-old-name-1",
17611770
DiskUUID: "100",
17621771
Type: vmopv1.VolumeTypeClassic,
17631772
Attached: true,
17641773
Limit: kubeutil.BytesToResource(10 * oneGiBInBytes),
17651774
Requested: kubeutil.BytesToResource(10 * oneGiBInBytes),
17661775
},
1776+
{
1777+
Name: "my-old-name-2",
1778+
DiskUUID: "104",
1779+
Type: vmopv1.VolumeTypeClassic,
1780+
Attached: true,
1781+
Limit: kubeutil.BytesToResource(10 * oneGiBInBytes),
1782+
Requested: kubeutil.BytesToResource(10 * oneGiBInBytes),
1783+
},
17671784
}
1785+
// Update disk with uuid 104 with same controller info in spec.
1786+
vd := vmCtx.MoVM.Config.Hardware.Device[5].(*vimtypes.VirtualDisk)
1787+
vd.ControllerKey = 200
1788+
vd.UnitNumber = ptr.To[int32](4)
17681789
})
17691790
Specify("status.volumes no longer includes the stale classic disk", func() {
17701791
Expect(vmCtx.VM.Status.Volumes).To(Equal([]vmopv1.VirtualMachineVolumeStatus{

0 commit comments

Comments
 (0)