Skip to content

Commit bfea6dc

Browse files
committed
Fixed logic to handle vSphere image template w/ multiple disks
1 parent b19da15 commit bfea6dc

File tree

4 files changed

+88
-43
lines changed

4 files changed

+88
-43
lines changed

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspheremachines.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -995,12 +995,6 @@ spec:
995995
description: VSphereDisk describes additional disks for vSphere
996996
to be added to VM that are not part of the VM OVA template.
997997
properties:
998-
deviceName:
999-
description: |-
1000-
DeviceName is a name to be used to identify the disk definition. If deviceName is not specified,
1001-
the disk will still be created. The deviceName should be unique so that it can be used to clearly
1002-
identify purpose of the disk, but is not required to be unique.
1003-
type: string
1004998
sizeGiB:
1005999
description: SizeGiB is the size of the disk (in GiB).
10061000
format: int64

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspheremachinetemplates.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -865,12 +865,6 @@ spec:
865865
vSphere to be added to VM that are not part of the VM
866866
OVA template.
867867
properties:
868-
deviceName:
869-
description: |-
870-
DeviceName is a name to be used to identify the disk definition. If deviceName is not specified,
871-
the disk will still be created. The deviceName should be unique so that it can be used to clearly
872-
identify purpose of the disk, but is not required to be unique.
873-
type: string
874868
sizeGiB:
875869
description: SizeGiB is the size of the disk (in GiB).
876870
format: int64

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspherevms.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,12 +1088,6 @@ spec:
10881088
description: VSphereDisk describes additional disks for vSphere
10891089
to be added to VM that are not part of the VM OVA template.
10901090
properties:
1091-
deviceName:
1092-
description: |-
1093-
DeviceName is a name to be used to identify the disk definition. If deviceName is not specified,
1094-
the disk will still be created. The deviceName should be unique so that it can be used to clearly
1095-
identify purpose of the disk, but is not required to be unique.
1096-
type: string
10971091
sizeGiB:
10981092
description: SizeGiB is the size of the disk (in GiB).
10991093
format: int64

pkg/services/govmomi/vcenter/clone.go

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -374,18 +374,48 @@ func getDiskSpec(vmCtx *capvcontext.VMContext, devices object.VirtualDeviceList)
374374

375375
// Now if we have increased the disk size of any additional disks that were in the template, we can now add new disks
376376
// that are present in the additionalDisks list.
377-
for i, dataDisk := range vmCtx.VSphereVM.Spec.DataDisks {
377+
if len(vmCtx.VSphereVM.Spec.DataDisks) > 0 {
378+
additionalDisks, diskErr := createAdditionalDisks(vmCtx.VSphereVM.Spec.DataDisks, primaryDisk, devices)
379+
if diskErr != nil {
380+
381+
}
382+
diskSpecs = append(diskSpecs, additionalDisks...)
383+
}
384+
385+
return diskSpecs, nil
386+
}
387+
388+
func getDiskConfigSpec(disk *types.VirtualDisk, diskCloneCapacityKB int64) (types.BaseVirtualDeviceConfigSpec, error) {
389+
switch {
390+
case diskCloneCapacityKB == 0:
391+
// No disk size specified for the clone. Default to the template disk capacity.
392+
case diskCloneCapacityKB > 0 && diskCloneCapacityKB >= disk.CapacityInKB:
393+
disk.CapacityInKB = diskCloneCapacityKB
394+
case diskCloneCapacityKB > 0 && diskCloneCapacityKB < disk.CapacityInKB:
395+
return nil, errors.Errorf(
396+
"can't resize template disk down, initial capacity is larger: %dKiB > %dKiB",
397+
disk.CapacityInKB, diskCloneCapacityKB)
398+
}
399+
400+
return &types.VirtualDeviceConfigSpec{
401+
Operation: types.VirtualDeviceConfigSpecOperationEdit,
402+
Device: disk,
403+
}, nil
404+
}
405+
406+
func createAdditionalDisks(disks []infrav1.VSphereDisk, primaryDisk *types.VirtualDisk, devices object.VirtualDeviceList) ([]types.BaseVirtualDeviceConfigSpec, error) {
407+
additionalDisks := []types.BaseVirtualDeviceConfigSpec{}
408+
unit := int32(1)
409+
410+
for i, dataDisk := range disks {
378411
klog.InfoS("Adding disk", "spec", dataDisk)
379412

380-
// Need storage policy
381-
// Need scsi controller
382-
controller, err := devices.FindDiskController("scsi")
383-
if err != nil {
413+
// Get controller. Only supporting using same controller as primary disk at this time
414+
controller, ok := devices.FindByKey(primaryDisk.ControllerKey).(types.BaseVirtualController)
415+
if !ok {
384416
klog.Infof("Unable to get scsi controller")
385417
}
386418

387-
unit := int32(i + 1)
388-
389419
dev := &types.VirtualDisk{
390420
VirtualDevice: types.VirtualDevice{
391421
Key: devices.NewKey() - int32(i),
@@ -394,15 +424,18 @@ func getDiskSpec(vmCtx *capvcontext.VMContext, devices object.VirtualDeviceList)
394424
ThinProvisioned: types.NewBool(true),
395425
VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
396426
FileName: "",
397-
//Datastore: types.NewReference(datastore.Reference()),
398427
},
399428
},
400-
UnitNumber: &unit,
429+
//UnitNumber: assignUnitNumber,
401430
ControllerKey: controller.GetVirtualController().Key,
402431
},
403432
CapacityInKB: dataDisk.SizeGiB * 1024 * 1024,
404433
}
405434

435+
// Assign unit number to next slot on controller
436+
assignUnitNumber(dev, devices, additionalDisks, controller, unit)
437+
unit = *dev.UnitNumber
438+
406439
diskConfigSpec := types.VirtualDeviceConfigSpec{
407440
Device: dev,
408441
Operation: types.VirtualDeviceConfigSpecOperationAdd,
@@ -411,28 +444,58 @@ func getDiskSpec(vmCtx *capvcontext.VMContext, devices object.VirtualDeviceList)
411444

412445
klog.InfoS("Generated device", "dev", dev)
413446

414-
diskSpecs = append(diskSpecs, &diskConfigSpec)
447+
additionalDisks = append(additionalDisks, &diskConfigSpec)
415448
}
416449

417-
return diskSpecs, nil
450+
return additionalDisks, nil
418451
}
419452

420-
func getDiskConfigSpec(disk *types.VirtualDisk, diskCloneCapacityKB int64) (types.BaseVirtualDeviceConfigSpec, error) {
421-
switch {
422-
case diskCloneCapacityKB == 0:
423-
// No disk size specified for the clone. Default to the template disk capacity.
424-
case diskCloneCapacityKB > 0 && diskCloneCapacityKB >= disk.CapacityInKB:
425-
disk.CapacityInKB = diskCloneCapacityKB
426-
case diskCloneCapacityKB > 0 && diskCloneCapacityKB < disk.CapacityInKB:
427-
return nil, errors.Errorf(
428-
"can't resize template disk down, initial capacity is larger: %dKiB > %dKiB",
429-
disk.CapacityInKB, diskCloneCapacityKB)
453+
// assignController assigns a device to a controller.
454+
func assignUnitNumber(device types.BaseVirtualDevice, existingDevices object.VirtualDeviceList, newDevices []types.BaseVirtualDeviceConfigSpec, controller types.BaseVirtualController, offset int32) {
455+
vd := device.GetVirtualDevice()
456+
vd.ControllerKey = controller.GetVirtualController().Key
457+
vd.UnitNumber = &offset
458+
459+
units := make([]bool, 30)
460+
461+
for i := 0; i < int(offset); i++ {
462+
units[i] = true
430463
}
431464

432-
return &types.VirtualDeviceConfigSpec{
433-
Operation: types.VirtualDeviceConfigSpecOperationEdit,
434-
Device: disk,
435-
}, nil
465+
switch sc := controller.(type) {
466+
case types.BaseVirtualSCSIController:
467+
// The SCSI controller sits on its own bus
468+
klog.Infof("Marking SCSI Controller's unit number: %d", sc.GetVirtualSCSIController().ScsiCtlrUnitNumber)
469+
units[sc.GetVirtualSCSIController().ScsiCtlrUnitNumber] = true
470+
}
471+
472+
key := controller.GetVirtualController().Key
473+
474+
// Check all existing devices
475+
for _, device := range existingDevices {
476+
d := device.GetVirtualDevice()
477+
478+
if d.ControllerKey == key && d.UnitNumber != nil {
479+
units[int(*d.UnitNumber)] = true
480+
}
481+
}
482+
483+
// Check new devices
484+
for _, device := range newDevices {
485+
d := device.GetVirtualDeviceConfigSpec().Device.GetVirtualDevice()
486+
487+
if d.ControllerKey == key && d.UnitNumber != nil {
488+
units[int(*d.UnitNumber)] = true
489+
}
490+
}
491+
492+
for unit, used := range units {
493+
if !used {
494+
unit32 := int32(unit)
495+
vd.UnitNumber = &unit32
496+
break
497+
}
498+
}
436499
}
437500

438501
const ethCardType = "vmxnet3"

0 commit comments

Comments
 (0)