@@ -374,18 +374,50 @@ 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+ klog .Errorf ("Unable to add additional disks: %v" , diskErr )
381+ return nil , diskErr
382+ }
383+ diskSpecs = append (diskSpecs , additionalDisks ... )
384+ }
385+
386+ return diskSpecs , nil
387+ }
388+
389+ func getDiskConfigSpec (disk * types.VirtualDisk , diskCloneCapacityKB int64 ) (types.BaseVirtualDeviceConfigSpec , error ) {
390+ switch {
391+ case diskCloneCapacityKB == 0 :
392+ // No disk size specified for the clone. Default to the template disk capacity.
393+ case diskCloneCapacityKB > 0 && diskCloneCapacityKB >= disk .CapacityInKB :
394+ disk .CapacityInKB = diskCloneCapacityKB
395+ case diskCloneCapacityKB > 0 && diskCloneCapacityKB < disk .CapacityInKB :
396+ return nil , errors .Errorf (
397+ "can't resize template disk down, initial capacity is larger: %dKiB > %dKiB" ,
398+ disk .CapacityInKB , diskCloneCapacityKB )
399+ }
400+
401+ return & types.VirtualDeviceConfigSpec {
402+ Operation : types .VirtualDeviceConfigSpecOperationEdit ,
403+ Device : disk ,
404+ }, nil
405+ }
406+
407+ func createAdditionalDisks (disks []infrav1.VSphereDisk , primaryDisk * types.VirtualDisk , devices object.VirtualDeviceList ) ([]types.BaseVirtualDeviceConfigSpec , error ) {
408+ additionalDisks := []types.BaseVirtualDeviceConfigSpec {}
409+ unit := int32 (1 )
410+
411+ for i , dataDisk := range disks {
378412 klog .InfoS ("Adding disk" , "spec" , dataDisk )
379413
380- // Need storage policy
381- // Need scsi controller
382- controller , err := devices .FindDiskController ("scsi" )
383- if err != nil {
414+ // Get controller. Only supporting using same controller as primary disk at this time
415+ controller , ok := devices .FindByKey (primaryDisk .ControllerKey ).(types.BaseVirtualController ) // TODO: Do this
416+ if ! ok {
384417 klog .Infof ("Unable to get scsi controller" )
418+ return nil , errors .Errorf ("unable to find controller with key=%v" , primaryDisk .ControllerKey )
385419 }
386420
387- unit := int32 (i + 1 )
388-
389421 dev := & types.VirtualDisk {
390422 VirtualDevice : types.VirtualDevice {
391423 Key : devices .NewKey () - int32 (i ),
@@ -394,15 +426,17 @@ func getDiskSpec(vmCtx *capvcontext.VMContext, devices object.VirtualDeviceList)
394426 ThinProvisioned : types .NewBool (true ),
395427 VirtualDeviceFileBackingInfo : types.VirtualDeviceFileBackingInfo {
396428 FileName : "" ,
397- //Datastore: types.NewReference(datastore.Reference()),
398429 },
399430 },
400- UnitNumber : & unit ,
401431 ControllerKey : controller .GetVirtualController ().Key ,
402432 },
403433 CapacityInKB : dataDisk .SizeGiB * 1024 * 1024 ,
404434 }
405435
436+ // Assign unit number to next slot on controller
437+ assignUnitNumber (dev , devices , additionalDisks , controller , unit )
438+ unit = * dev .UnitNumber
439+
406440 diskConfigSpec := types.VirtualDeviceConfigSpec {
407441 Device : dev ,
408442 Operation : types .VirtualDeviceConfigSpecOperationAdd ,
@@ -411,28 +445,59 @@ func getDiskSpec(vmCtx *capvcontext.VMContext, devices object.VirtualDeviceList)
411445
412446 klog .InfoS ("Generated device" , "dev" , dev )
413447
414- diskSpecs = append (diskSpecs , & diskConfigSpec )
448+ additionalDisks = append (additionalDisks , & diskConfigSpec )
415449 }
416450
417- return diskSpecs , nil
451+ return additionalDisks , nil
418452}
419453
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 )
454+ // assignController assigns a device to a controller.
455+ func assignUnitNumber ( device types. BaseVirtualDevice , existingDevices object. VirtualDeviceList , newDevices []types. BaseVirtualDeviceConfigSpec , controller types. BaseVirtualController , offset int32 ) {
456+ vd := device . GetVirtualDevice ()
457+ vd . ControllerKey = controller . GetVirtualController (). Key
458+ vd . UnitNumber = & offset
459+
460+ units := make ([] bool , 30 )
461+
462+ for i := 0 ; i < int ( offset ); i ++ {
463+ units [ i ] = true
430464 }
431465
432- return & types.VirtualDeviceConfigSpec {
433- Operation : types .VirtualDeviceConfigSpecOperationEdit ,
434- Device : disk ,
435- }, nil
466+ sc , ok := controller .(types.BaseVirtualSCSIController )
467+ if ok {
468+ // The SCSI controller sits on its own bus
469+ klog .Infof ("Marking SCSI Controller's unit number: %d" , sc .GetVirtualSCSIController ().ScsiCtlrUnitNumber )
470+ units [sc .GetVirtualSCSIController ().ScsiCtlrUnitNumber ] = true
471+ }
472+
473+ key := controller .GetVirtualController ().Key
474+
475+ // Check all existing devices
476+ for _ , device := range existingDevices {
477+ d := device .GetVirtualDevice ()
478+
479+ if d .ControllerKey == key && d .UnitNumber != nil {
480+ units [int (* d .UnitNumber )] = true
481+ }
482+ }
483+
484+ // Check new devices
485+ for _ , device := range newDevices {
486+ d := device .GetVirtualDeviceConfigSpec ().Device .GetVirtualDevice ()
487+
488+ if d .ControllerKey == key && d .UnitNumber != nil {
489+ units [int (* d .UnitNumber )] = true
490+ }
491+ }
492+
493+ // Assign first unused unit number
494+ for unit , used := range units {
495+ if ! used {
496+ unit32 := int32 (unit )
497+ vd .UnitNumber = & unit32
498+ break
499+ }
500+ }
436501}
437502
438503const ethCardType = "vmxnet3"
0 commit comments