From 819c22e5f38f4bc1b412962bcf28e1255a8a3271 Mon Sep 17 00:00:00 2001 From: Iury Gregory Melo Ferreira Date: Mon, 8 Apr 2024 00:10:17 -0300 Subject: [PATCH] Fixes in HFC This commit is to address some feedback from #1559. - Automatically create the HFC for the BMH - GetFirmwareComponents now takes into consideration that an empty list was returned and will only throw an error if the FirmwareInterface is different from `redfish`. --- .../metal3.io/baremetalhost_controller.go | 43 +++++++++++++++++++ pkg/provisioner/ironic/ironic.go | 6 +-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/controllers/metal3.io/baremetalhost_controller.go b/controllers/metal3.io/baremetalhost_controller.go index 8dd6d9e4cc..357bc23de4 100644 --- a/controllers/metal3.io/baremetalhost_controller.go +++ b/controllers/metal3.io/baremetalhost_controller.go @@ -883,6 +883,19 @@ func (r *BareMetalHostReconciler) registerHost(prov provisioner.Provisioner, inf } } + // Create the hfc resource with same host name/namespace if it doesn't exist and the host supports it + if info.host.Name != "" { + // Maybe we should only create the HFC in case the the FirmwareInterface is redfish + if !info.host.DeletionTimestamp.IsZero() { + info.log.Info(fmt.Sprintf("will not attempt to create new hostFirmwareComponents in %s", info.host.Namespace)) + } else { + if err = r.createHostFirmwareComponents(info); err != nil { + info.log.Info("failed creating hostfirmwarecomponents") + return actionError{errors.Wrap(err, "failed creating hostFirmwareComponents")} + } + } + } + // Reaching this point means the credentials are valid and worked, // so clear any previous error and record the success in the // status block. @@ -1498,6 +1511,36 @@ func saveHostProvisioningSettings(host *metal3api.BareMetalHost, info *reconcile return } +func (r *BareMetalHostReconciler) createHostFirmwareComponents(info *reconcileInfo) error { + // Check if HostFirmwareComponents already exists + hfc := &metal3api.HostFirmwareComponents{} + if err := r.Get(info.ctx, info.request.NamespacedName, hfc); err != nil { + if k8serrors.IsNotFound(err) { + // A resource doesn't exist, create one + hfc.ObjectMeta = metav1.ObjectMeta{ + Name: info.host.Name, + Namespace: info.host.Namespace} + hfc.Status.Updates = []metal3api.FirmwareUpdate{} + hfc.Status.Components = []metal3api.FirmwareComponentStatus{} + hfc.Spec.Updates = []metal3api.FirmwareUpdate{} + + // Set bmh as owner, this makes sure the resource is deleted when bmh is deleted + if err = controllerutil.SetControllerReference(info.host, hfc, r.Scheme()); err != nil { + return errors.Wrap(err, "could not set bmh as controller") + } + if err = r.Create(info.ctx, hfc); err != nil { + return errors.Wrap(err, "failure creating hostFirmwareComponents resource") + } + + info.log.Info("created new hostFirmwareComponents resource") + } else { + // Error reading the object + return errors.Wrap(err, "could not load hostFirmwareComponents resource") + } + } + return nil +} + func (r *BareMetalHostReconciler) createHostFirmwareSettings(info *reconcileInfo) error { // Check if HostFirmwareSettings already exists hfs := &metal3api.HostFirmwareSettings{} diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go index a9e6c793bf..bb9c6dff8f 100644 --- a/pkg/provisioner/ironic/ironic.go +++ b/pkg/provisioner/ironic/ironic.go @@ -1165,10 +1165,10 @@ func (p *ironicProvisioner) GetFirmwareComponents() ([]metal3api.FirmwareCompone // Get the components from Ironic via Gophercloud componentList, componentListErr := nodes.ListFirmware(p.ctx, p.client, ironicNode.UUID).Extract() - if componentListErr != nil { + if componentListErr != nil || len(componentList) == 0 { bmcAccess, _ := p.bmcAccess() - if bmcAccess.FirmwareInterface() == "no-firmware" { - return nil, fmt.Errorf("node %s is using firmware interface %s: %w", ironicNode.UUID, bmcAccess.FirmwareInterface(), componentListErr) + if bmcAccess.FirmwareInterface() != "redfish" { + return nil, fmt.Errorf("Driver does not support firmware updates") } return nil, fmt.Errorf("could not get firmware components for node %s: %w", ironicNode.UUID, componentListErr)