Skip to content

Commit

Permalink
Fix KRBN-8120: add optional field bootstrapImageName to NutanixMachine
Browse files Browse the repository at this point in the history
  • Loading branch information
yanhua121 committed Apr 8, 2024
1 parent 3171df2 commit 0f922e5
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 45 deletions.
5 changes: 5 additions & 0 deletions api/v1beta1/nutanixmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ type NutanixMachineSpec struct {
// +optional
BootstrapRef *corev1.ObjectReference `json:"bootstrapRef,omitempty"`

// bootstrapImageName is the name of the image containing additional bootstrap data.
// The image must be available from PC if configured.
// +optional
BootstrapImageName *string `json:"bootstrapImageName,omitempty"`

// List of GPU devices that need to be added to the machines.
// +kubebuilder:validation:Optional
GPUs []NutanixGPU `json:"gpus,omitempty"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,11 @@ spec:
- legacy
- uefi
type: string
bootstrapImageName:
description: |-
bootstrapImageName is the name of the image containing additional bootstrap data.
The image must be available from PC if configured.
type: string
bootstrapRef:
description: BootstrapRef is a reference to a bootstrap provider-specific
resource that holds configuration details.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,11 @@ spec:
- legacy
- uefi
type: string
bootstrapImageName:
description: |-
bootstrapImageName is the name of the image containing additional bootstrap data.
The image must be available from PC if configured.
type: string
bootstrapRef:
description: BootstrapRef is a reference to a bootstrap provider-specific
resource that holds configuration details.
Expand Down
122 changes: 77 additions & 45 deletions controllers/nutanixmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,31 +517,6 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
return nil, err
}

// Get Image UUID
imageUUID, err := GetImageUUID(ctx, nc, rctx.NutanixMachine.Spec.Image.Name, rctx.NutanixMachine.Spec.Image.UUID)
if err != nil {
errorMsg := fmt.Errorf("failed to get the image UUID to create the VM %s. %v", vmName, err)
rctx.SetFailureStatus(capierrors.CreateMachineError, errorMsg)
return nil, err
}

// Get the bootstrapData from the referenced secret
bootstrapData, err := r.getBootstrapData(rctx)
if err != nil {
log.Error(err, fmt.Sprintf("failed to get the bootstrap data to create the VM %s", vmName))
return nil, err
}
// Encode the bootstrapData by base64
bsdataEncoded := base64.StdEncoding.EncodeToString(bootstrapData)
log.V(1).Info(fmt.Sprintf("Retrieved the bootstrap data from secret %s (before encoding size: %d, encoded string size:%d)",
rctx.NutanixMachine.Spec.BootstrapRef.Name, len(bootstrapData), len(bsdataEncoded)))

// Generate metadata for the VM
vmUUID := uuid.New()
metadata := fmt.Sprintf("{\"hostname\": \"%s\", \"uuid\": \"%s\"}", rctx.Machine.Name, vmUUID)
// Encode the metadata by base64
metadataEncoded := base64.StdEncoding.EncodeToString([]byte(metadata))

vmInput := &nutanixClientV3.VMIntentInput{}
vmSpec := &nutanixClientV3.VM{Name: utils.StringPtr(vmName)}

Expand All @@ -555,19 +530,6 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
}
}

// Create Disk Spec for systemdisk to be set later in VM Spec
diskSize := rctx.NutanixMachine.Spec.SystemDiskSize
diskSizeMib := GetMibValueOfQuantity(diskSize)
systemDisk, err := CreateSystemDiskSpec(imageUUID, diskSizeMib)
if err != nil {
errorMsg := fmt.Errorf("error occurred while creating system disk spec: %v", err)
rctx.SetFailureStatus(capierrors.CreateMachineError, errorMsg)
return nil, errorMsg
}
diskList := []*nutanixClientV3.VMDisk{
systemDisk,
}

// Set Categories to VM Sepc before creating VM
categories, err := GetCategoryVMSpec(ctx, nc, r.getMachineCategoryIdentifiers(rctx))
if err != nil {
Expand Down Expand Up @@ -597,6 +559,26 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
return nil, err
}

diskList := []*nutanixClientV3.VMDisk{}
// Get Image UUID
imageUUID, err := GetImageUUID(ctx, nc, rctx.NutanixMachine.Spec.Image.Name, rctx.NutanixMachine.Spec.Image.UUID)
if err != nil {
errorMsg := fmt.Errorf("failed to get the image UUID to create the VM %s. %v", vmName, err)
rctx.SetFailureStatus(capierrors.CreateMachineError, errorMsg)
return nil, err
}

// Create Disk Spec for systemdisk to be set later in VM Spec
diskSize := rctx.NutanixMachine.Spec.SystemDiskSize
diskSizeMib := GetMibValueOfQuantity(diskSize)
systemDisk, err := CreateSystemDiskSpec(imageUUID, diskSizeMib)
if err != nil {
errorMsg := fmt.Errorf("error occurred while creating system disk spec: %v", err)
rctx.SetFailureStatus(capierrors.CreateMachineError, errorMsg)
return nil, errorMsg
}
diskList = append(diskList, systemDisk)

memorySize := rctx.NutanixMachine.Spec.MemorySize
memorySizeMib := GetMibValueOfQuantity(memorySize)
vmSpec.Resources = &nutanixClientV3.VMResources{
Expand All @@ -608,13 +590,6 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
NicList: nicList,
DiskList: diskList,
GpuList: gpuList,
GuestCustomization: &nutanixClientV3.GuestCustomization{
IsOverridable: utils.BoolPtr(true),
CloudInit: &nutanixClientV3.GuestCustomizationCloudInit{
UserData: utils.StringPtr(bsdataEncoded),
MetaData: utils.StringPtr(metadataEncoded),
},
},
}
vmSpec.ClusterReference = &nutanixClientV3.Reference{
Kind: utils.StringPtr("cluster"),
Expand All @@ -629,6 +604,63 @@ func (r *NutanixMachineReconciler) getOrCreateVM(rctx *nctx.MachineContext) (*nu
return nil, err
}

// if BootstrapImageName is configured
if rctx.NutanixMachine.Spec.BootstrapImageName != nil {
bootstrapImgName := *rctx.NutanixMachine.Spec.BootstrapImageName
imgUUID, err := GetImageUUID(rctx.Context, rctx.NutanixClient, &bootstrapImgName, nil)
if err != nil {
errMsg := fmt.Errorf("failed to get the bootstrap image with name %s. %v", bootstrapImgName, err)
rctx.SetFailureStatus(capierrors.CreateMachineError, errMsg)
return nil, err
}

bootstrapDisk := &nutanixClientV3.VMDisk{
DeviceProperties: &nutanixClientV3.VMDiskDeviceProperties{
DeviceType: utils.StringPtr("CDROM"),
DiskAddress: &nutanixClientV3.DiskAddress{
AdapterType: utils.StringPtr("IDE"),
DeviceIndex: utils.Int64Ptr(0),
},
},
DataSourceReference: &nutanixClientV3.Reference{
Kind: utils.StringPtr("image"),
UUID: &imgUUID,
},
}
diskList = append(diskList, bootstrapDisk)
vmSpec.Resources.DiskList = diskList

log.Info(fmt.Sprintf("Use the bootstrap image %s to create the VM %s.", bootstrapImgName, vmName))
} else {

// Get the bootstrapData from the referenced secret
bootstrapData, err := r.getBootstrapData(rctx)
if err != nil {
log.Error(err, fmt.Sprintf("failed to get the bootstrap data to create the VM %s", vmName))
return nil, err
}
// Encode the bootstrapData by base64
bsdataEncoded := base64.StdEncoding.EncodeToString(bootstrapData)
log.V(1).Info(fmt.Sprintf("Retrieved the bootstrap data from secret %s (before encoding size: %d, encoded string size:%d)",
rctx.NutanixMachine.Spec.BootstrapRef.Name, len(bootstrapData), len(bsdataEncoded)))

// Generate metadata for the VM
vmUUID := uuid.New()
metadata := fmt.Sprintf("{\"hostname\": \"%s\", \"uuid\": \"%s\"}", rctx.Machine.Name, vmUUID)
// Encode the metadata by base64
metadataEncoded := base64.StdEncoding.EncodeToString([]byte(metadata))

vmSpec.Resources.GuestCustomization = &nutanixClientV3.GuestCustomization{
IsOverridable: utils.BoolPtr(true),
CloudInit: &nutanixClientV3.GuestCustomizationCloudInit{
UserData: utils.StringPtr(bsdataEncoded),
MetaData: utils.StringPtr(metadataEncoded),
},
}

log.Info(fmt.Sprintf("Use the bootstrapData secret %s to create the VM %s.", rctx.NutanixMachine.Spec.BootstrapRef.Name, vmName))
}

vmInput.Spec = vmSpec
vmInput.Metadata = vmMetadata
// Create the actual VM/Machine
Expand Down

0 comments on commit 0f922e5

Please sign in to comment.