@@ -34,6 +34,7 @@ import (
3434 apitypes "k8s.io/apimachinery/pkg/types"
3535 kerrors "k8s.io/apimachinery/pkg/util/errors"
3636 coreinformers "k8s.io/client-go/informers/core/v1"
37+ "k8s.io/utils/ptr"
3738 capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3839 capierrors "sigs.k8s.io/cluster-api/errors"
3940 capiutil "sigs.k8s.io/cluster-api/util"
@@ -55,6 +56,9 @@ import (
5556
5657const (
5758 projectKind = "project"
59+
60+ deviceTypeCDROM = "CDROM"
61+ adapterTypeIDE = "IDE"
5862)
5963
6064var (
@@ -517,31 +521,6 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
517521 return nil , err
518522 }
519523
520- // Get Image UUID
521- imageUUID , err := GetImageUUID (ctx , nc , rctx .NutanixMachine .Spec .Image .Name , rctx .NutanixMachine .Spec .Image .UUID )
522- if err != nil {
523- errorMsg := fmt .Errorf ("failed to get the image UUID to create the VM %s. %v" , vmName , err )
524- rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
525- return nil , err
526- }
527-
528- // Get the bootstrapData from the referenced secret
529- bootstrapData , err := r .getBootstrapData (rctx )
530- if err != nil {
531- log .Error (err , fmt .Sprintf ("failed to get the bootstrap data to create the VM %s" , vmName ))
532- return nil , err
533- }
534- // Encode the bootstrapData by base64
535- bsdataEncoded := base64 .StdEncoding .EncodeToString (bootstrapData )
536- log .V (1 ).Info (fmt .Sprintf ("Retrieved the bootstrap data from secret %s (before encoding size: %d, encoded string size:%d)" ,
537- rctx .NutanixMachine .Spec .BootstrapRef .Name , len (bootstrapData ), len (bsdataEncoded )))
538-
539- // Generate metadata for the VM
540- vmUUID := uuid .New ()
541- metadata := fmt .Sprintf ("{\" hostname\" : \" %s\" , \" uuid\" : \" %s\" }" , rctx .Machine .Name , vmUUID )
542- // Encode the metadata by base64
543- metadataEncoded := base64 .StdEncoding .EncodeToString ([]byte (metadata ))
544-
545524 vmInput := & nutanixClientV3.VMIntentInput {}
546525 vmSpec := & nutanixClientV3.VM {Name : utils .StringPtr (vmName )}
547526
@@ -555,19 +534,6 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
555534 }
556535 }
557536
558- // Create Disk Spec for systemdisk to be set later in VM Spec
559- diskSize := rctx .NutanixMachine .Spec .SystemDiskSize
560- diskSizeMib := GetMibValueOfQuantity (diskSize )
561- systemDisk , err := CreateSystemDiskSpec (imageUUID , diskSizeMib )
562- if err != nil {
563- errorMsg := fmt .Errorf ("error occurred while creating system disk spec: %v" , err )
564- rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
565- return nil , errorMsg
566- }
567- diskList := []* nutanixClientV3.VMDisk {
568- systemDisk ,
569- }
570-
571537 // Set Categories to VM Sepc before creating VM
572538 categories , err := GetCategoryVMSpec (ctx , nc , r .getMachineCategoryIdentifiers (rctx ))
573539 if err != nil {
@@ -597,8 +563,14 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
597563 return nil , err
598564 }
599565
600- memorySize := rctx .NutanixMachine .Spec .MemorySize
601- memorySizeMib := GetMibValueOfQuantity (memorySize )
566+ diskList , err := getDiskList (rctx )
567+ if err != nil {
568+ errorMsg := fmt .Errorf ("failed to get the disk list to create the VM %s. %v" , vmName , err )
569+ rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
570+ return nil , err
571+ }
572+
573+ memorySizeMib := GetMibValueOfQuantity (rctx .NutanixMachine .Spec .MemorySize )
602574 vmSpec .Resources = & nutanixClientV3.VMResources {
603575 PowerState : utils .StringPtr ("ON" ),
604576 HardwareClockTimezone : utils .StringPtr ("UTC" ),
@@ -608,19 +580,18 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
608580 NicList : nicList ,
609581 DiskList : diskList ,
610582 GpuList : gpuList ,
611- GuestCustomization : & nutanixClientV3.GuestCustomization {
612- IsOverridable : utils .BoolPtr (true ),
613- CloudInit : & nutanixClientV3.GuestCustomizationCloudInit {
614- UserData : utils .StringPtr (bsdataEncoded ),
615- MetaData : utils .StringPtr (metadataEncoded ),
616- },
617- },
618583 }
619584 vmSpec .ClusterReference = & nutanixClientV3.Reference {
620585 Kind : utils .StringPtr ("cluster" ),
621586 UUID : utils .StringPtr (peUUID ),
622587 }
623588
589+ if err := r .addGuestCustomizationToVM (rctx , vmSpec ); err != nil {
590+ errorMsg := fmt .Errorf ("error occurred while adding guest customization to vm spec: %v" , err )
591+ rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
592+ return nil , err
593+ }
594+
624595 // Set BootType in VM Spec before creating VM
625596 err = r .addBootTypeToVM (rctx , vmSpec )
626597 if err != nil {
@@ -684,6 +655,100 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
684655 return vm , nil
685656}
686657
658+ func (r * NutanixMachineReconciler ) addGuestCustomizationToVM (rctx * nctx.MachineContext , vmSpec * nutanixClientV3.VM ) error {
659+ // Get the bootstrapData
660+ bootstrapRef := rctx .NutanixMachine .Spec .BootstrapRef
661+ if bootstrapRef .Kind == infrav1 .NutanixMachineBootstrapRefKindSecret {
662+ bootstrapData , err := r .getBootstrapData (rctx )
663+ if err != nil {
664+ return err
665+ }
666+
667+ // Encode the bootstrapData by base64
668+ bsdataEncoded := base64 .StdEncoding .EncodeToString (bootstrapData )
669+ metadata := fmt .Sprintf ("{\" hostname\" : \" %s\" , \" uuid\" : \" %s\" }" , rctx .Machine .Name , uuid .New ())
670+ metadataEncoded := base64 .StdEncoding .EncodeToString ([]byte (metadata ))
671+
672+ vmSpec .Resources .GuestCustomization = & nutanixClientV3.GuestCustomization {
673+ IsOverridable : utils .BoolPtr (true ),
674+ CloudInit : & nutanixClientV3.GuestCustomizationCloudInit {
675+ UserData : utils .StringPtr (bsdataEncoded ),
676+ MetaData : utils .StringPtr (metadataEncoded ),
677+ },
678+ }
679+ }
680+
681+ return nil
682+ }
683+
684+ func getDiskList (rctx * nctx.MachineContext ) ([]* nutanixClientV3.VMDisk , error ) {
685+ diskList := make ([]* nutanixClientV3.VMDisk , 0 )
686+
687+ systemDisk , err := getSystemDisk (rctx )
688+ if err != nil {
689+ return nil , err
690+ }
691+ diskList = append (diskList , systemDisk )
692+
693+ bootstrapRef := rctx .NutanixMachine .Spec .BootstrapRef
694+ if bootstrapRef .Kind == infrav1 .NutanixMachineBootstrapRefKindImage {
695+ bootstrapDisk , err := getBootstrapDisk (rctx )
696+ if err != nil {
697+ return nil , err
698+ }
699+
700+ diskList = append (diskList , bootstrapDisk )
701+ }
702+
703+ return diskList , nil
704+ }
705+
706+ func getSystemDisk (rctx * nctx.MachineContext ) (* nutanixClientV3.VMDisk , error ) {
707+ nodeOSImageName := rctx .NutanixMachine .Spec .Image .Name
708+ nodeOSImageUUID , err := GetImageUUID (rctx .Context , rctx .NutanixClient , nodeOSImageName , rctx .NutanixMachine .Spec .Image .UUID )
709+ if err != nil {
710+ errorMsg := fmt .Errorf ("failed to get the image UUID for image named %q: %w" , * nodeOSImageName , err )
711+ rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
712+ return nil , err
713+ }
714+
715+ systemDiskSizeMib := GetMibValueOfQuantity (rctx .NutanixMachine .Spec .SystemDiskSize )
716+ systemDisk , err := CreateSystemDiskSpec (nodeOSImageUUID , systemDiskSizeMib )
717+ if err != nil {
718+ errorMsg := fmt .Errorf ("error occurred while creating system disk spec: %w" , err )
719+ rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
720+ return nil , err
721+ }
722+
723+ return systemDisk , nil
724+ }
725+
726+ func getBootstrapDisk (rctx * nctx.MachineContext ) (* nutanixClientV3.VMDisk , error ) {
727+ bootstrapImageName := rctx .NutanixMachine .Spec .BootstrapRef .Name
728+ bootstrapImageUUID , err := GetImageUUID (rctx .Context , rctx .NutanixClient , & bootstrapImageName , nil )
729+ if err != nil {
730+ errorMsg := fmt .Errorf ("failed to get the image UUID for image named %q: %w" , bootstrapImageName , err )
731+ rctx .SetFailureStatus (capierrors .CreateMachineError , errorMsg )
732+ return nil , err
733+ }
734+
735+ bootstrapDisk := & nutanixClientV3.VMDisk {
736+ DeviceProperties : & nutanixClientV3.VMDiskDeviceProperties {
737+ DeviceType : ptr .To (deviceTypeCDROM ),
738+ DiskAddress : & nutanixClientV3.DiskAddress {
739+ AdapterType : ptr .To (adapterTypeIDE ),
740+ DeviceIndex : ptr .To (int64 (0 )),
741+ },
742+ },
743+ DataSourceReference : & nutanixClientV3.Reference {
744+ Kind : ptr .To (strings .ToLower (infrav1 .NutanixMachineBootstrapRefKindImage )),
745+ UUID : ptr .To (bootstrapImageUUID ),
746+ },
747+ }
748+
749+ return bootstrapDisk , nil
750+ }
751+
687752// getBootstrapData returns the Bootstrap data from the ref secret
688753func (r * NutanixMachineReconciler ) getBootstrapData (rctx * nctx.MachineContext ) ([]byte , error ) {
689754 if rctx .NutanixMachine .Spec .BootstrapRef == nil {
0 commit comments