@@ -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
438501const ethCardType = "vmxnet3"
0 commit comments