Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apis/metal3.io/v1alpha1/baremetalhost_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,11 @@ type BareMetalHostSpec struct {
// without hardware profiles.
HardwareProfile string `json:"hardwareProfile,omitempty"`

// The value of the kernel commandline argument list that will be passed
// to the preprovisioning agent's kernel during boot.
// +optional
PreprovisioningExtraKernelParams string `json:"preprovisioningExtraKernelParams,omitempty"`

// Provide guidance about how to choose the device for the image
// being provisioned. The default is currently to use /dev/sda as
// the root device.
Expand Down
5 changes: 5 additions & 0 deletions config/base/crds/bases/metal3.io_baremetalhosts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ spec:
state (e.g. provisioned), its power state will be forced to match
this value.
type: boolean
preprovisioningExtraKernelParams:
description: |-
The value of the kernel commandline argument list that will be passed
to the preprovisioning agent's kernel during boot.
type: string
preprovisioningNetworkDataName:
description: |-
PreprovisioningNetworkDataName is the name of the Secret in the
Expand Down
5 changes: 5 additions & 0 deletions config/render/capm3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ spec:
state (e.g. provisioned), its power state will be forced to match
this value.
type: boolean
preprovisioningExtraKernelParams:
description: |-
The value of the kernel commandline argument list that will be passed
to the preprovisioning agent's kernel during boot.
type: string
preprovisioningNetworkDataName:
description: |-
PreprovisioningNetworkDataName is the name of the Secret in the
Expand Down
88 changes: 77 additions & 11 deletions internal/controller/metal3.io/baremetalhost_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const (
clarifySoftPoweroffFailure = "Continuing with hard poweroff after soft poweroff fails. More details: "
hardwareDataFinalizer = metal3api.BareMetalHostFinalizer + "/hardwareData"
NotReady = "Not ready"
defaultPPImgFormat = "DEFAULT_BMH_PPI_IMG"
)

// BareMetalHostReconciler reconciles a BareMetalHost object.
Expand All @@ -84,6 +85,54 @@ func (info *reconcileInfo) publishEvent(reason, message string) {
info.events = append(info.events, info.host.NewEvent(reason, message))
}

// return the PreprovisioningExtraKernelParams from the reconciliation info.
func (r *BareMetalHostReconciler) retrievePreprovisioningExtraKernelParamsSpec(ctx context.Context, info *reconcileInfo, prov provisioner.Provisioner) string {
if info == nil || info.host == nil {
return ""
}
kernelExtraPreprovParams := info.host.Spec.PreprovisioningExtraKernelParams

// This is a multi purpose check, this both checks whether BMO is running
// with the default PPI provider and PPI CR reconciler and it also checks
// whether the provisioner in use has support for PPI or not.
preprovImgFormats, err := prov.PreprovisioningImageFormats(ctx)
if err != nil {
return kernelExtraPreprovParams
}
preprovImg, err := r.getPreprovImage(ctx, info, preprovImgFormats)
if err != nil {
return kernelExtraPreprovParams
}
// If the execution reaches this point it means there is a PPI in the
// namespace with acceptable image format but it is managed by an external
// controller-manager.
// From this point onward there are 3 separate cases, if the image format
// is initrd then BMH and PPI kernel params are combined. In case
// the PPI is in ISO format then the BMH extra kernel params will be
// ignored and a warning will be logged to inform the user that in the
// specific use case only PPI kernel params matter. In any other scenarios
// the preprovisioningExtraKernelParams are taken only from BMH spec.
if preprovImg != nil {
format := preprovImg.Format
trimmedParams := strings.TrimSpace(kernelExtraPreprovParams)
switch format {
case metal3api.ImageFormatISO:
if trimmedParams != "" {
info.log.Info("Warning: PPI is in ISO format, BMH preprovisioningExtraKernelParams are ignored in favor of PPI extra kernel parameters!")
}
// Kernel params are already injected to the ISO.
kernelExtraPreprovParams = ""
case metal3api.ImageFormatInitRD:
kernelExtraPreprovParams += " " + preprovImg.GeneratedImage.ExtraKernelParams
info.log.Info("BMH and external PPI (preprovisioning)ExtraKernelParams got combined!")
default:
// This scenario covers when the image format is internally set to defaultPPIImgFormat.
info.log.Info("PPI is generated by BMO or has unknown image format, preprovisioningExtraKernelParams are taken only from BMH spec.")
}
}
return kernelExtraPreprovParams
}

// +kubebuilder:rbac:groups=metal3.io,resources=baremetalhosts,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal3.io,resources=baremetalhosts/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=metal3.io,resources=baremetalhosts/finalizers,verbs=update
Expand Down Expand Up @@ -776,6 +825,15 @@ func (r *BareMetalHostReconciler) getPreprovImage(ctx context.Context, info *rec
return nil, fmt.Errorf("failed to retrieve pre-provisioning image data: %w", err)
}

// Check who reconciles the given PPI, if it is not this BMO then it is
// and externally managed PPI.
isExternal := false
ctrlOwnerRef := metav1.GetControllerOf(&preprovImage)
if ctrlOwnerRef == nil || ctrlOwnerRef.Name != info.host.Name || ctrlOwnerRef.UID != info.host.UID {
info.log.Info("Using externally managed PreprovisioningImage")
isExternal = true
}

// If the PreprovisioningImage is being deleted, treat it as unavailable
if !preprovImage.DeletionTimestamp.IsZero() {
info.log.Info("PreprovisioningImage is being deleted, waiting for new one")
Expand Down Expand Up @@ -807,13 +865,20 @@ func (r *BareMetalHostReconciler) getPreprovImage(ctx context.Context, info *rec
return nil, err
}

PPIFormat := preprovImage.Status.Format
if !isExternal {
// PPI was generated by the default PPI provider thus it has to be
// handled separately from regular formats.
PPIFormat = defaultPPImgFormat
}

image := provisioner.PreprovisioningImage{
GeneratedImage: imageprovider.GeneratedImage{
ImageURL: preprovImage.Status.ImageUrl,
KernelURL: preprovImage.Status.KernelUrl,
ExtraKernelParams: preprovImage.Status.ExtraKernelParams,
},
Format: preprovImage.Status.Format,
Format: PPIFormat,
}
info.log.Info("using PreprovisioningImage", "Image", image)
return &image, nil
Expand Down Expand Up @@ -876,16 +941,17 @@ func (r *BareMetalHostReconciler) registerHost(ctx context.Context, prov provisi
provResult, provID, err := prov.Register(
ctx,
provisioner.ManagementAccessData{
BootMode: info.host.Status.Provisioning.BootMode,
AutomatedCleaningMode: info.host.Spec.AutomatedCleaningMode,
State: info.host.Status.Provisioning.State,
OperationalStatus: info.host.Status.OperationalStatus,
CurrentImage: getCurrentImage(info.host),
PreprovisioningImage: preprovImg,
PreprovisioningNetworkData: preprovisioningNetworkData,
HasCustomDeploy: hasCustomDeploy(info.host),
DisablePowerOff: info.host.Spec.DisablePowerOff,
CPUArchitecture: getHostArchitecture(info.host),
BootMode: info.host.Status.Provisioning.BootMode,
AutomatedCleaningMode: info.host.Spec.AutomatedCleaningMode,
State: info.host.Status.Provisioning.State,
OperationalStatus: info.host.Status.OperationalStatus,
CurrentImage: getCurrentImage(info.host),
PreprovisioningImage: preprovImg,
PreprovisioningNetworkData: preprovisioningNetworkData,
PreprovisioningExtraKernelParams: r.retrievePreprovisioningExtraKernelParamsSpec(ctx, info, prov),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have preprovImg up on line 923 that we could pass in here. That way we can skip the getPreprovImage call in retrievePreprovisioningExtraKernelParamsSpec.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that makes sense, I will check how big of a change that would be .

HasCustomDeploy: hasCustomDeploy(info.host),
DisablePowerOff: info.host.Spec.DisablePowerOff,
CPUArchitecture: getHostArchitecture(info.host),
},
credsChanged,
info.host.Status.ErrorType == metal3api.RegistrationError)
Expand Down
Loading
Loading