Repository: metal3-io/baremetal-operator
Pull request #1074 (2022-01-20 09:02:12)

Add make targets for setting images
These make targets can be used to change the image used for BMO, Ironic,
Mariadb, keepalived and IPA downloader. This is similar to how things work in CAPM3.

The deploy target was removed. It has been broken for at least a year
since the name of the image was changed. I.e. it could apply the
manifests but the image substitution didn't work.

The idea is to unify how image replacement works in CAPM3 and BMO and solve https://github.com/metal3-io/metal3-dev-env/issues/908 by making use of these make targets in metal3-dev-env.

For reference, [this is how the image replacement works in CAPM3](https://github.com/metal3-io/cluster-api-provider-metal3/blob/2d686bf00a7d4babd8287dffc9f8bdabe07c26f2/Makefile#L370-L378).



metal3-io-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **fmuyassarov** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @fmuyassarov` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=metal3-io%2Fbaremetal-operator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/metal3-io/baremetal-operator/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["fmuyassarov"]} -->
lentzi90: /test-v1b1-integration
/test-v1b1-centos-integration
lentzi90: /test-v1b1-integration
/test-v1b1-centos-integration
kashifest: /lgtm
Xenwar: /approve
metal3-io-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/metal3-io/baremetal-operator/pull/1074#issuecomment-1028695454" title="Approved">Xenwar</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **fmuyassarov** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @fmuyassarov` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=metal3-io%2Fbaremetal-operator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/metal3-io/baremetal-operator/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["fmuyassarov"]} -->
kashifest: /test-v1b1-integration
furkatgofurov7: /test-v1b1-integration
/test-v1b1-centos-integration 
metal3-io-bot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/metal3-io/baremetal-operator/pull/1074#pullrequestreview-878385104" title="Approved">zhouhao3</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **fmuyassarov** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @fmuyassarov` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=metal3-io%2Fbaremetal-operator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/metal3-io/baremetal-operator/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["fmuyassarov"]} -->

Patch:
diff --git a/Makefile b/Makefile
index b993fa26..6ee85693 100644
--- a/Makefile
+++ b/Makefile
@@ -50,7 +50,9 @@ help:  ## Display this help
 	@echo "  DEBUG            -- debug flag, if any ($(DEBUG))"
 
 # Image URL to use all building/pushing image targets
-IMG ?= baremetal-operator:latest
+IMG_NAME ?= baremetal-operator
+IMG_TAG ?= latest
+IMG ?= $(IMG_NAME):$(IMG_TAG)
 
 ## --------------------------------------
 ## Test Targets
@@ -129,8 +131,8 @@ uninstall: $(KUSTOMIZE) manifests ## Uninstall CRDs from a cluster
 	$< build config/crd | kubectl delete -f -
 
 .PHONY: deploy
-deploy: $(KUSTOMIZE) manifests ## Deploy controller in the configured Kubernetes cluster in ~/.kube/config
-	cd config/manager && kustomize edit set image controller=${IMG}
+deploy: $(KUSTOMIZE) manifests  ## Deploy controller in the configured Kubernetes cluster in ~/.kube/config
+	make set-manifest-image-bmo MANIFEST_IMG=$(IMG_NAME) MANIFEST_TAG=$(IMG_TAG)
 	$< build config/default | kubectl apply -f -
 
 $(CONTROLLER_GEN): hack/tools/go.mod
@@ -151,6 +153,31 @@ manifests-generate: $(CONTROLLER_GEN)
 manifests-kustomize: $(KUSTOMIZE)
 	$< build config/default > config/render/capm3.yaml
 
+.PHONY: set-manifest-image-bmo
+set-manifest-image-bmo: $(KUSTOMIZE) manifests
+	$(info Updating container image for BMO to use ${MANIFEST_IMG}:${MANIFEST_TAG})
+	cd config/default && $(abspath $(KUSTOMIZE)) edit set image quay.io/metal3-io/baremetal-operator=${MANIFEST_IMG}:${MANIFEST_TAG}
+
+.PHONY: set-manifest-image-ironic
+set-manifest-image-ironic: $(KUSTOMIZE) manifests
+	$(info Updating container image for Ironic to use ${MANIFEST_IMG}:${MANIFEST_TAG})
+	cd ironic-deployment/default && $(abspath $(KUSTOMIZE)) edit set image quay.io/metal3-io/ironic=${MANIFEST_IMG}:${MANIFEST_TAG}
+
+.PHONY: set-manifest-image-mariadb
+set-manifest-image-mariadb: $(KUSTOMIZE) manifests
+	$(info Updating container image for Mariadb to use ${MANIFEST_IMG}:${MANIFEST_TAG})
+	cd ironic-deployment/default && $(abspath $(KUSTOMIZE)) edit set image quay.io/metal3-io/mariadb=${MANIFEST_IMG}:${MANIFEST_TAG}
+
+.PHONY: set-manifest-image-keepalived
+set-manifest-image-keepalived: $(KUSTOMIZE) manifests
+	$(info Updating container image for keepalived to use ${MANIFEST_IMG}:${MANIFEST_TAG})
+	cd ironic-deployment/keepalived && $(abspath $(KUSTOMIZE)) edit set image quay.io/metal3-io/keepalived=${MANIFEST_IMG}:${MANIFEST_TAG}
+
+.PHONY: set-manifest-image-ipa-downloader
+set-manifest-image-ipa-downloader: $(KUSTOMIZE) manifests
+	$(info Updating container image for IPA downloader to use ${MANIFEST_IMG}:${MANIFEST_TAG})
+	cd ironic-deployment/default && $(abspath $(KUSTOMIZE)) edit set image quay.io/metal3-io/ironic-ipa-downloader=${MANIFEST_IMG}:${MANIFEST_TAG}
+
 .PHONY: generate
 generate: $(CONTROLLER_GEN) ## Generate code
 	cd apis; $(abspath $<) object:headerFile="../hack/boilerplate.go.txt" paths="./..."
diff --git a/README.md b/README.md
index 383b3adb..67e9c191 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # Bare Metal Operator
 
-[![Ubuntu V1beta1 build status](https://jenkins.nordix.org/view/Metal3/job/metal3_main_v1b1_integration_test_ubuntu/badge/icon?subject=Ubuntu%20E2E%20V1beta1)](https://jenkins.nordix.org/view/Metal3/job/metal3_main_v1b1_integration_test_ubuntu/)
-[![CentOS V1beta1 build status](https://jenkins.nordix.org/view/Metal3/job/metal3_main_v1b1_integration_test_centos/badge/icon?subject=CentOS%20E2E%20V1beta1)](https://jenkins.nordix.org/view/Metal3/job/metal3_main_v1b1_integration_test_centos/)
+[![Ubuntu V1alpha5 build status](https://jenkins.nordix.org/view/Airship/job/airship_master_v1a5_integration_test_ubuntu/badge/icon?subject=Ubuntu%20E2E%20V1alpha5)](https://jenkins.nordix.org/view/Airship/job/airship_master_v1a5_integration_test_ubuntu/)
+[![CentOS V1alpha5 build status](https://jenkins.nordix.org/view/Airship/job/airship_master_v1a5_integration_test_centos/badge/icon?subject=CentOS%20E2E%20V1alpha5)](https://jenkins.nordix.org/view/Airship/job/airship_master_v1a5_integration_test_centos/)
 
 The Bare Metal Operator implements a Kubernetes API for managing bare metal
 hosts. It maintains an inventory of available hosts as instances of the
diff --git a/apis/metal3.io/v1alpha1/bmceventsubscription_webhook.go b/apis/metal3.io/v1alpha1/bmceventsubscription_webhook.go
index 9ddb2378..4e7cc579 100644
--- a/apis/metal3.io/v1alpha1/bmceventsubscription_webhook.go
+++ b/apis/metal3.io/v1alpha1/bmceventsubscription_webhook.go
@@ -43,22 +43,9 @@ func (s *BMCEventSubscription) ValidateCreate() error {
 }
 
 // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
-//
-// We prevent updates to the spec.  All other updates (e.g. status, finalizers) are allowed.
 func (s *BMCEventSubscription) ValidateUpdate(old runtime.Object) error {
 	bmcsubscriptionlog.Info("validate update", "name", s.Name)
-
-	bes, casted := old.(*BMCEventSubscription)
-	if !casted {
-		bmcsubscriptionlog.Error(fmt.Errorf("old object conversion error"), "validate update error")
-		return nil
-	}
-
-	if s.Spec != bes.Spec {
-		return fmt.Errorf("subscriptions cannot be updated, please recreate it")
-	}
-
-	return nil
+	return fmt.Errorf("subscriptions cannot be updated, please recreate it")
 }
 
 // ValidateDelete implements webhook.Validator so a webhook will be registered for the type
diff --git a/controllers/metal3.io/baremetalhost_controller.go b/controllers/metal3.io/baremetalhost_controller.go
index 9d5eed0e..934bf25a 100644
--- a/controllers/metal3.io/baremetalhost_controller.go
+++ b/controllers/metal3.io/baremetalhost_controller.go
@@ -951,7 +951,7 @@ func (r *BareMetalHostReconciler) actionMatchProfile(prov provisioner.Provisione
 func (r *BareMetalHostReconciler) actionPreparing(prov provisioner.Provisioner, info *reconcileInfo) actionResult {
 	info.log.Info("preparing")
 
-	bmhDirty, newStatus, err := getHostProvisioningSettings(info.host)
+	dirty, newStatus, err := getHostProvisioningSettings(info.host)
 	if err != nil {
 		return actionError{err}
 	}
@@ -962,56 +962,49 @@ func (r *BareMetalHostReconciler) actionPreparing(prov provisioner.Provisioner,
 		RootDeviceHints:  newStatus.Provisioning.RootDeviceHints.DeepCopy(),
 		FirmwareConfig:   newStatus.Provisioning.Firmware.DeepCopy(),
 	}
-	// When manual cleaning fails, we think that the existing RAID configuration
+	// When manual cleaning fails, we think that the existed RAID configuration
 	// is invalid and needs to be reconfigured.
 	if info.host.Status.ErrorType == metal3v1alpha1.PreparationError {
 		prepareData.ActualRAIDConfig = nil
-		bmhDirty = true
+		dirty = true
 	}
 
-	// The hfsDirty flag is used to push the new settings to Ironic as part of the clean steps.
-	// The HFS Status field will be updated in the HostFirmwareSettingsReconciler when it reads the settings from Ironic.
-	// After manual cleaning is complete the HFS Spec should match the Status.
-	hfsDirty, hfs, err := r.getHostFirmwareSettings(info)
-
+	// Use settings in hostFirmwareSettings if available
+	hfs, err := r.getHostFirmwareSettings(info)
 	if err != nil {
 		// wait until hostFirmwareSettings are ready
 		return actionContinue{subResourceNotReadyRetryDelay}
 	}
-	if hfsDirty {
+	if hfs != nil {
 		prepareData.ActualFirmwareSettings = hfs.Status.Settings.DeepCopy()
 		prepareData.TargetFirmwareSettings = hfs.Spec.Settings.DeepCopy()
 	}
 
-	provResult, started, err := prov.Prepare(prepareData, bmhDirty || hfsDirty,
-		info.host.Status.ErrorType == metal3v1alpha1.PreparationError)
+	provResult, started, err := prov.Prepare(prepareData, dirty)
 
 	if err != nil {
 		return actionError{errors.Wrap(err, "error preparing host")}
 	}
 
 	if provResult.ErrorMessage != "" {
-		if bmhDirty {
-			info.log.Info("handling cleaning error in controller")
-			clearHostProvisioningSettings(info.host)
-		}
+		info.log.Info("handling cleaning error in controller")
+		clearHostProvisioningSettings(info.host)
 		return recordActionFailure(info, metal3v1alpha1.PreparationError, provResult.ErrorMessage)
 	}
 
-	if bmhDirty && started {
+	if dirty && started {
 		info.log.Info("saving host provisioning settings")
 		_, err := saveHostProvisioningSettings(info.host)
 		if err != nil {
 			return actionError{errors.Wrap(err, "could not save the host provisioning settings")}
 		}
 	}
-
 	if started && clearError(info.host) {
-		bmhDirty = true
+		dirty = true
 	}
 	if provResult.Dirty {
 		result := actionContinue{provResult.RequeueAfter}
-		if bmhDirty {
+		if dirty {
 			return actionUpdate{result}
 		}
 		return result
@@ -1391,35 +1384,34 @@ func (r *BareMetalHostReconciler) createHostFirmwareSettings(info *reconcileInfo
 }
 
 // Get the stored firmware settings if there are valid changes
-func (r *BareMetalHostReconciler) getHostFirmwareSettings(info *reconcileInfo) (dirty bool, hfs *metal3v1alpha1.HostFirmwareSettings, err error) {
+func (r *BareMetalHostReconciler) getHostFirmwareSettings(info *reconcileInfo) (hfs *metal3v1alpha1.HostFirmwareSettings, err error) {
 
 	hfs = &metal3v1alpha1.HostFirmwareSettings{}
 	if err = r.Get(context.TODO(), info.request.NamespacedName, hfs); err != nil {
 
 		if !k8serrors.IsNotFound(err) {
 			// Error reading the object
-			return false, nil, errors.Wrap(err, "could not load host firmware settings")
+			return nil, errors.Wrap(err, "could not load host firmware settings")
 		}
 
 		// Could not get settings, log it but don't return error as settings may not have been available at provisioner
 		info.log.Info("could not get hostFirmwareSettings", "namespacename", info.request.NamespacedName)
-		return false, nil, nil
+		return nil, nil
 	}
 
 	// Check if there are settings in the Spec that are different than the Status
 	if meta.IsStatusConditionTrue(hfs.Status.Conditions, string(metal3v1alpha1.FirmwareSettingsChangeDetected)) {
 
 		if meta.IsStatusConditionTrue(hfs.Status.Conditions, string(metal3v1alpha1.FirmwareSettingsValid)) {
-			info.log.Info("hostFirmwareSettings indicating ChangeDetected", "namespacename", info.request.NamespacedName)
-			return true, hfs, nil
+			return hfs, nil
 		}
 
 		info.log.Info("hostFirmwareSettings not valid", "namespacename", info.request.NamespacedName)
-		return false, nil, nil
+		return nil, nil
 	}
 
 	info.log.Info("hostFirmwareSettings no updates", "namespacename", info.request.NamespacedName)
-	return false, nil, nil
+	return nil, nil
 }
 
 func (r *BareMetalHostReconciler) saveHostStatus(host *metal3v1alpha1.BareMetalHost) error {
diff --git a/controllers/metal3.io/host_state_machine.go b/controllers/metal3.io/host_state_machine.go
index 3ead90de..8f38165e 100644
--- a/controllers/metal3.io/host_state_machine.go
+++ b/controllers/metal3.io/host_state_machine.go
@@ -419,14 +419,6 @@ func (hsm *hostStateMachine) handleAvailable(info *reconcileInfo) actionResult {
 		return actionComplete{}
 	}
 
-	// Check if hostFirmwareSettings have changed
-	if dirty, _, err := hsm.Reconciler.getHostFirmwareSettings(info); err != nil {
-		return actionError{err}
-	} else if dirty {
-		hsm.NextState = metal3v1alpha1.StatePreparing
-		return actionComplete{}
-	}
-
 	// ErrorCount is cleared when appropriate inside actionManageAvailable
 	actResult := hsm.Reconciler.actionManageAvailable(hsm.Provisioner, info)
 	if _, complete := actResult.(actionComplete); complete {
diff --git a/controllers/metal3.io/hostfirmwaresettings_controller.go b/controllers/metal3.io/hostfirmwaresettings_controller.go
index 60355366..33546aeb 100644
--- a/controllers/metal3.io/hostfirmwaresettings_controller.go
+++ b/controllers/metal3.io/hostfirmwaresettings_controller.go
@@ -41,10 +41,9 @@ import (
 )
 
 const (
-	provisionerRetryDelay                = time.Second * 30
-	resourceNotAvailableRetryDelay       = time.Second * 30
-	reconcilerRequeueDelay               = time.Minute * 5
-	reconcilerRequeueDelayChangeDetected = time.Minute * 1
+	provisionerRetryDelay          = time.Second * 30
+	resourceNotAvailableRetryDelay = time.Second * 30
+	reconcilerRequeueDelay         = time.Minute * 5
 )
 
 // HostFirmwareSettingsReconciler reconciles a HostFirmwareSettings object
@@ -163,10 +162,6 @@ func (r *HostFirmwareSettingsReconciler) Reconcile(ctx context.Context, req ctrl
 	}
 
 	// requeue to run again after delay
-	if meta.IsStatusConditionTrue(info.hfs.Status.Conditions, string(metal3v1alpha1.FirmwareSettingsChangeDetected)) {
-		// If there is a difference between Spec and Status shorten the query from Ironic so that the Status is updated when cleaning completes
-		return ctrl.Result{Requeue: true, RequeueAfter: reconcilerRequeueDelayChangeDetected}, nil
-	}
 	return ctrl.Result{Requeue: true, RequeueAfter: reconcilerRequeueDelay}, nil
 }
 
diff --git a/pkg/hardwareutils/bmc/irmc.go b/pkg/hardwareutils/bmc/irmc.go
index a9c0b789..1bfa03f9 100644
--- a/pkg/hardwareutils/bmc/irmc.go
+++ b/pkg/hardwareutils/bmc/irmc.go
@@ -75,7 +75,7 @@ func (a *iRMCAccessDetails) BIOSInterface() string {
 }
 
 func (a *iRMCAccessDetails) BootInterface() string {
-	return "ipxe"
+	return "pxe"
 }
 
 func (a *iRMCAccessDetails) ManagementInterface() string {
diff --git a/pkg/provisioner/demo/demo.go b/pkg/provisioner/demo/demo.go
index b38da176..fa57a83a 100644
--- a/pkg/provisioner/demo/demo.go
+++ b/pkg/provisioner/demo/demo.go
@@ -193,7 +193,7 @@ func (p *demoProvisioner) UpdateHardwareState() (hwState provisioner.HardwareSta
 }
 
 // Prepare remove existing configuration and set new configuration
-func (p *demoProvisioner) Prepare(data provisioner.PrepareData, unprepared bool, force bool) (result provisioner.Result, started bool, err error) {
+func (p *demoProvisioner) Prepare(data provisioner.PrepareData, unprepared bool) (result provisioner.Result, started bool, err error) {
 	hostName := p.objectMeta.Name
 
 	switch hostName {
diff --git a/pkg/provisioner/fixture/fixture.go b/pkg/provisioner/fixture/fixture.go
index 2628e511..c3d0f8fc 100644
--- a/pkg/provisioner/fixture/fixture.go
+++ b/pkg/provisioner/fixture/fixture.go
@@ -191,7 +191,7 @@ func (p *fixtureProvisioner) UpdateHardwareState() (hwState provisioner.Hardware
 }
 
 // Prepare remove existing configuration and set new configuration
-func (p *fixtureProvisioner) Prepare(data provisioner.PrepareData, unprepared bool, force bool) (result provisioner.Result, started bool, err error) {
+func (p *fixtureProvisioner) Prepare(data provisioner.PrepareData, unprepared bool) (result provisioner.Result, started bool, err error) {
 	p.log.Info("preparing host")
 	started = unprepared
 	return
diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go
index 9a8ab1e5..20ec3c19 100644
--- a/pkg/provisioner/ironic/ironic.go
+++ b/pkg/provisioner/ironic/ironic.go
@@ -1257,7 +1257,7 @@ func (p *ironicProvisioner) startManualCleaning(bmcAccess bmc.AccessDetails, iro
 
 // Prepare remove existing configuration and set new configuration.
 // If `started` is true,  it means that we successfully executed `tryChangeNodeProvisionState`.
-func (p *ironicProvisioner) Prepare(data provisioner.PrepareData, unprepared bool, force bool) (result provisioner.Result, started bool, err error) {
+func (p *ironicProvisioner) Prepare(data provisioner.PrepareData, unprepared bool) (result provisioner.Result, started bool, err error) {
 	bmcAccess, err := p.bmcAccess()
 	if err != nil {
 		result, err = transientError(err)
@@ -1308,9 +1308,9 @@ func (p *ironicProvisioner) Prepare(data provisioner.PrepareData, unprepared boo
 
 	case nodes.CleanFail:
 		// When clean failed, we need to clean host provisioning settings.
-		// If force is false, it means the settings aren't cleared.
+		// If unprepared is false, means the settings aren't cleared.
 		// So we can't set the node's state to manageable, until the settings are cleared.
-		if !force {
+		if !unprepared {
 			result, err = operationFailed(ironicNode.LastError)
 			return
 		}
diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go
index c3cf9a74..e150198c 100644
--- a/pkg/provisioner/provisioner.go
+++ b/pkg/provisioner/provisioner.go
@@ -148,7 +148,7 @@ type Provisioner interface {
 	Adopt(data AdoptData, force bool) (result Result, err error)
 
 	// Prepare remove existing configuration and set new configuration
-	Prepare(data PrepareData, unprepared bool, force bool) (result Result, started bool, err error)
+	Prepare(data PrepareData, unprepared bool) (result Result, started bool, err error)
 
 	// Provision writes the image from the host spec to the host. It
 	// may be called multiple times, and should return true for its
diff --git a/tools/deploy.sh b/tools/deploy.sh
index 4f2935ab..872d89a2 100755
--- a/tools/deploy.sh
+++ b/tools/deploy.sh
@@ -2,88 +2,22 @@
 
 set -eu
 
-function usage {
-    echo "Usage : deploy.sh [-b -i -t -n -k]"
+if [ -z "${1:-}" ] || [ -z "${2:-}" ] || [ -z "${3:-}" ] || [ -z "${4:-}" ] || [ -z "${5:-}" ]; then
+    echo "Usage : deploy.sh <deploy-BMO> <deploy-Ironic> <deploy-TLS> <deploy-Basic-Auth> <deploy-Keepalived>"
     echo ""
-    echo "       -b: deploy BMO"
-    echo "       -i: deploy Ironic"
-    echo "       -t: deploy with TLS enabled"
-    echo "       -n: deploy without authentication"
-    echo "       -k: deploy with keepalived"
-}
-
-DEPLOY_BMO=false
-DEPLOY_IRONIC=false
-DEPLOY_TLS=false
-DEPLOY_BASIC_AUTH=true
-DEPLOY_KEEPALIVED=false
-
-while getopts ":hbitnk" options; do
-    case "${options}" in
-        h)
-            usage
-            exit 0
-            ;;
-        b)
-            DEPLOY_BMO=true
-            ;;
-        i)
-            DEPLOY_IRONIC=true
-            ;;
-        t)
-            DEPLOY_TLS=true
-            ;;
-        n)
-            echo "WARNING: Deploying without authentication is not recommended"
-            DEPLOY_BASIC_AUTH=false
-            ;;
-        k)
-            DEPLOY_KEEPALIVED=true
-            ;;
-        :)
-            echo "ERROR: -${OPTARG} requires an argument"
-            usage
-            exit 1
-            ;;
-        *)
-            usage
-            exit 1
-            ;;
-    esac
-done
-
-# Backward compatibility
-shift $(( OPTIND - 1 ))
-if [ $# -gt 0 ]; then
-    echo "WARNING: positional arguments are deprecated, run deploy.sh -h for information"
-fi
-
-if [ -n "${1:-}" ]; then
-    DEPLOY_BMO=$1
-fi
-
-if [ -n "${2:-}" ]; then
-    DEPLOY_IRONIC=$2
-fi
-
-if [ -n "${3:-}" ]; then
-    DEPLOY_TLS=$3
-fi
-
-if [ -n "${4:-}" ]; then
-    DEPLOY_BASIC_AUTH=$4
-fi
-
-if [ -n "${5:-}" ]; then
-    DEPLOY_KEEPALIVED=$5
-fi
-
-if [ "$DEPLOY_BMO" == "false" ] && [ "$DEPLOY_IRONIC" == "false" ]; then
-    echo "ERROR: nothing to deploy"
-    usage
+    echo "       deploy-BMO: deploy BareMetal Operator : \"true\" or \"false\""
+    echo "       deploy-Ironic: deploy Ironic : \"true\" or \"false\""
+    echo "       deploy-TLS: deploy with TLS enabled : \"true\" or \"false\""
+    echo "       deploy-Basic-Auth: deploy with Basic Auth enabled : \"true\" or \"false\""
+    echo "       deploy-Keepalived: deploy with Keepalived for ironic : \"true\" or \"false\""
     exit 1
 fi
 
+DEPLOY_BMO="${1,,}"
+DEPLOY_IRONIC="${2,,}"
+DEPLOY_TLS="${3,,}"
+DEPLOY_BASIC_AUTH="${4,,}"
+DEPLOY_KEEPALIVED="${5,,}"
 MARIADB_HOST_IP="${MARIADB_HOST_IP:-"127.0.0.1"}"
 KUBECTL_ARGS="${KUBECTL_ARGS:-""}"
 RESTART_CONTAINER_CERTIFICATE_UPDATED=${RESTART_CONTAINER_CERTIFICATE_UPDATED:-"false"}
diff --git a/tools/remove_local_ironic.sh b/tools/remove_local_ironic.sh
index dfa17015..f4914be8 100755
--- a/tools/remove_local_ironic.sh
+++ b/tools/remove_local_ironic.sh
@@ -3,8 +3,7 @@
 set -xe
 
 # This script removes local ironic containers. 
-
-CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-podman}"
+# It requires ${CONTAINER_RUNTIME} variable to be defined first
 
 for name in ironic ironic-api ironic-conductor ironic-inspector dnsmasq httpd mariadb ipa-downloader \
     ironic-endpoint-keepalived ironic-log-watch httpd-reverse-proxy ; do
diff --git a/tools/run_local_ironic.sh b/tools/run_local_ironic.sh
index 2afffe17..025b16f1 100755
--- a/tools/run_local_ironic.sh
+++ b/tools/run_local_ironic.sh
@@ -15,12 +15,7 @@ CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-podman}"
 HTTP_PORT="6180"
 PROVISIONING_IP="${PROVISIONING_IP:-"172.22.0.1"}"
 CLUSTER_PROVISIONING_IP="${CLUSTER_PROVISIONING_IP:-"172.22.0.2"}"
-# ironicendpoint is used in the CI setup
-if ip link show ironicendpoint > /dev/null; then
-    PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-ironicendpoint}"
-else
-    PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}"
-fi
+PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-"ironicendpoint"}"
 CLUSTER_DHCP_RANGE="${CLUSTER_DHCP_RANGE:-"172.22.0.10,172.22.0.100"}"
 IRONIC_KERNEL_PARAMS="${IRONIC_KERNEL_PARAMS:-"console=ttyS0"}"
 IRONIC_BOOT_ISO_SOURCE="${IRONIC_BOOT_ISO_SOURCE:-"local"}"
@@ -50,29 +45,7 @@ then
   chmod 604 "${MARIADB_KEY_FILE}"
 fi
 
-sudo mkdir -p "${IRONIC_DATA_DIR}/auth"
-
-if [ "$IRONIC_TLS_SETUP" = "true" ]; then
-    sudo mkdir -p "${IRONIC_DATA_DIR}/tls"
-
-    if [ -z "$IRONIC_CERT_FILE" ]; then
-        IRONIC_CERT_FILE="${IRONIC_DATA_DIR}/tls/ironic.crt"
-        IRONIC_KEY_FILE="${IRONIC_DATA_DIR}/tls/ironic.key"
-        IRONIC_CACERT_FILE="${IRONIC_CERT_FILE}"
-        sudo openssl req -x509 -newkey rsa:4096 -nodes -days 365 -subj "/CN=ironic" \
-            -addext "subjectAltName = IP:${CLUSTER_PROVISIONING_IP},IP:${PROVISIONING_IP}" \
-            -out "${IRONIC_CERT_FILE}" -keyout "${IRONIC_KEY_FILE}"
-    fi
-
-    if [ -z "$IRONIC_INSPECTOR_CERT_FILE" ]; then
-        IRONIC_INSPECTOR_CERT_FILE="${IRONIC_DATA_DIR}/tls/inspector.crt"
-        IRONIC_INSPECTOR_KEY_FILE="${IRONIC_DATA_DIR}/tls/inspector.key"
-        IRONIC_INSPECTOR_CACERT_FILE="${IRONIC_CERT_FILE}"
-        sudo openssl req -x509 -newkey rsa:4096 -nodes -days 365 -subj "/CN=ironic" \
-            -addext "subjectAltName = IP:${CLUSTER_PROVISIONING_IP},IP:${PROVISIONING_IP}" \
-            -out "${IRONIC_INSPECTOR_CERT_FILE}" -keyout "${IRONIC_INSPECTOR_KEY_FILE}"
-    fi
-
+if [ -n "$IRONIC_CERT_FILE" ]; then
     export IRONIC_BASE_URL="https://${CLUSTER_PROVISIONING_IP}"
     if [ -z "$IRONIC_CACERT_FILE" ]; then
         export IRONIC_CACERT_FILE=$IRONIC_CERT_FILE
@@ -88,17 +61,16 @@ IRONIC_ENDPOINT="${IRONIC_ENDPOINT:-"${IRONIC_BASE_URL}:6385/v1/"}"
 IRONIC_INSPECTOR_ENDPOINT="${IRONIC_INSPECTOR_ENDPOINT:-"${IRONIC_BASE_URL}:5050/v1/"}"
 CACHEURL="${CACHEURL:-"http://${PROVISIONING_IP}/images"}"
 IRONIC_FAST_TRACK="${IRONIC_FAST_TRACK:-"true"}"
-IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-"true"}
 INSPECTOR_REVERSE_PROXY_SETUP=${INSPECTOR_REVERSE_PROXY_SETUP:-"true"}
-IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-"false"}
 if [[ $IRONIC_TLS_SETUP == *false* ]]
 then
-     # No reverse proxy for Ironic if TLS is not used
-     IRONIC_REVERSE_PROXY_SETUP="false"
-     INSPECTOR_REVERSE_PROXY_SETUP="false"
+  INSPECTOR_REVERSE_PROXY_SETUP="false" # No Revese proxy for Ironic inspector if TLS is not used
 fi
 IRONIC_INSPECTOR_VLAN_INTERFACES=${IRONIC_INSPECTOR_VLAN_INTERFACES:-"all"}
 
+sudo mkdir -p "${IRONIC_DATA_DIR}"
+sudo mkdir -p "${IRONIC_DATA_DIR}/auth"
+
 cat << EOF | sudo tee "${IRONIC_DATA_DIR}/ironic-vars.env"
 HTTP_PORT=${HTTP_PORT}
 PROVISIONING_IP=${CLUSTER_PROVISIONING_IP}
@@ -113,16 +85,12 @@ CACHEURL=${CACHEURL}
 IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK}
 IRONIC_KERNEL_PARAMS=${IRONIC_KERNEL_PARAMS}
 IRONIC_BOOT_ISO_SOURCE=${IRONIC_BOOT_ISO_SOURCE}
-IRONIC_TLS_SETUP=${IRONIC_TLS_SETUP}
-IRONIC_INSPECTOR_TLS_SETUP=${IRONIC_TLS_SETUP}
-IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP}
 INSPECTOR_REVERSE_PROXY_SETUP=${INSPECTOR_REVERSE_PROXY_SETUP}
 IRONIC_INSPECTOR_VLAN_INTERFACES=${IRONIC_INSPECTOR_VLAN_INTERFACES}
 IPA_BASEURI=${IPA_BASEURI}
-IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB}
 EOF
 
-if [ "$IRONIC_TLS_SETUP" == "true" ] && [ -n "$IRONIC_CA_CERT_B64" ]; then
+if [ "$IRONIC_TLS_SETUP" == "true" ]; then
 # shellcheck disable=SC2086
 cat << EOF | kubectl apply -f -
 apiVersion: v1
@@ -138,9 +106,6 @@ fi
 
 sudo "${CONTAINER_RUNTIME}" pull "$IRONIC_IMAGE"
 sudo "${CONTAINER_RUNTIME}" pull "$IRONIC_KEEPALIVED_IMAGE"
-if [ "$IRONIC_USE_MARIADB" = "true" ]; then
-    sudo "${CONTAINER_RUNTIME}" pull "$MARIADB_IMAGE"
-fi
 
 CERTS_MOUNTS=""
 
@@ -183,16 +148,14 @@ if [ -n "$IRONIC_USERNAME" ]; then
         "${IRONIC_DATA_DIR}/auth/ironic-rpc-auth-config"
      BASIC_AUTH_MOUNTS="-v ${IRONIC_DATA_DIR}/auth/ironic-auth-config:/auth/ironic/auth-config"
      BASIC_AUTH_MOUNTS="${BASIC_AUTH_MOUNTS} -v ${IRONIC_DATA_DIR}/auth/ironic-rpc-auth-config:/auth/ironic-rpc/auth-config"
-     IRONIC_HTPASSWD="$(htpasswd -n -b -B "${IRONIC_USERNAME}" "${IRONIC_PASSWORD}")"
-     IRONIC_HTPASSWD="--env HTTP_BASIC_HTPASSWD=${IRONIC_HTPASSWD} --env IRONIC_HTPASSWD=${IRONIC_HTPASSWD}"
+     IRONIC_HTPASSWD="--env HTTP_BASIC_HTPASSWD=$(htpasswd -n -b -B "${IRONIC_USERNAME}" "${IRONIC_PASSWORD}")"
 fi
 IRONIC_INSPECTOR_HTPASSWD=""
 if [ -n "$IRONIC_INSPECTOR_USERNAME" ]; then
      envsubst < "${SCRIPTDIR}/ironic-deployment/basic-auth/ironic-inspector-auth-config-tpl" > \
         "${IRONIC_DATA_DIR}/auth/ironic-inspector-auth-config"
      BASIC_AUTH_MOUNTS="${BASIC_AUTH_MOUNTS} -v ${IRONIC_DATA_DIR}/auth/ironic-inspector-auth-config:/auth/ironic-inspector/auth-config"
-     IRONIC_INSPECTOR_HTPASSWD="$(htpasswd -n -b -B "${IRONIC_INSPECTOR_USERNAME}" "${IRONIC_INSPECTOR_PASSWORD}")"
-     IRONIC_INSPECTOR_HTPASSWD="--env HTTP_BASIC_HTPASSWD=${IRONIC_INSPECTOR_HTPASSWD} --env INSPECTOR_HTPASSWD=${IRONIC_INSPECTOR_HTPASSWD}"
+     IRONIC_INSPECTOR_HTPASSWD="--env HTTP_BASIC_HTPASSWD=$(htpasswd -n -b -B "${IRONIC_INSPECTOR_USERNAME}" "${IRONIC_INSPECTOR_PASSWORD}")"
 fi
 
 sudo mkdir -p "$IRONIC_DATA_DIR/html/images"
@@ -212,13 +175,8 @@ fi
 
 "$SCRIPTDIR/tools/remove_local_ironic.sh"
 
-if [ "$IRONIC_USE_MARIADB" = "true" ]; then
-    # set password for mariadb
-    mariadb_password=$(echo "$(date;hostname)"|sha256sum |cut -c-20)
-    IRONIC_MARIADB_PASSWORD="--env MARIADB_PASSWORD=$mariadb_password"
-else
-    IRONIC_MARIADB_PASSWORD=
-fi
+# set password for mariadb
+mariadb_password=$(echo "$(date;hostname)"|sha256sum |cut -c-20)
 
 POD=""
 
@@ -251,30 +209,31 @@ sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name dnsmasq \
      ${POD} --env-file "${IRONIC_DATA_DIR}/ironic-vars.env" \
      -v "$IRONIC_DATA_DIR:/shared" --entrypoint /bin/rundnsmasq "${IRONIC_IMAGE}"
 
-# See this file for env vars you can set, like IP, DHCP_RANGE, INTERFACE
-# https://github.com/metal3-io/ironic-image/blob/main/scripts/runhttpd
+# https://github.com/metal3-io/mariadb-image/blob/main/runmariadb
 # shellcheck disable=SC2086
-sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name httpd \
+sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name mariadb \
+     ${POD} ${CERTS_MOUNTS} --env-file "${IRONIC_DATA_DIR}/ironic-vars.env" \
+     -v "$IRONIC_DATA_DIR:/shared" \
+     --env "MARIADB_PASSWORD=$mariadb_password" "${MARIADB_IMAGE}"
+
+# See this file for additional env vars you may want to pass, like IP and INTERFACE
+# https://github.com/metal3-io/ironic-image/blob/main/scripts/runironic-api
+# shellcheck disable=SC2086
+sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name ironic-api \
      ${POD} ${CERTS_MOUNTS} ${BASIC_AUTH_MOUNTS} ${IRONIC_HTPASSWD} \
      --env-file "${IRONIC_DATA_DIR}/ironic-vars.env" \
-     -v "$IRONIC_DATA_DIR:/shared" --entrypoint /bin/runhttpd "${IRONIC_IMAGE}"
-
-if [ "$IRONIC_USE_MARIADB" = "true" ]; then
-    # https://github.com/metal3-io/mariadb-image/blob/main/runmariadb
-    # shellcheck disable=SC2086
-    sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name mariadb \
-         ${POD} ${CERTS_MOUNTS} --env-file "${IRONIC_DATA_DIR}/ironic-vars.env" \
-         -v "$IRONIC_DATA_DIR:/shared" \
-         --env "MARIADB_PASSWORD=$mariadb_password" "${MARIADB_IMAGE}"
-fi
+     --env "MARIADB_PASSWORD=$mariadb_password" \
+     --entrypoint /bin/runironic-api \
+     -v "$IRONIC_DATA_DIR:/shared" "${IRONIC_IMAGE}"
 
 # See this file for additional env vars you may want to pass, like IP and INTERFACE
-# https://github.com/metal3-io/ironic-image/blob/main/scripts/runironic
+# https://github.com/metal3-io/ironic-image/blob/main/scripts/runironic-conductor
 # shellcheck disable=SC2086
-sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name ironic \
+sudo "${CONTAINER_RUNTIME}" run -d --net host --privileged --name ironic-conductor \
      ${POD} ${CERTS_MOUNTS} ${BASIC_AUTH_MOUNTS} ${IRONIC_HTPASSWD} \
      --env-file "${IRONIC_DATA_DIR}/ironic-vars.env" \
-     ${IRONIC_MARIADB_PASSWORD} --entrypoint /bin/runironic \
+     --env "MARIADB_PASSWORD=$mariadb_password" \
+     --entrypoint /bin/runironic-conductor \
      -v "$IRONIC_DATA_DIR:/shared" "${IRONIC_IMAGE}"
 
 # Start ironic-endpoint-keepalived


Test patch:
diff --git a/apis/metal3.io/v1alpha1/bmceventsubscription_webhook_test.go b/apis/metal3.io/v1alpha1/bmceventsubscription_webhook_test.go
deleted file mode 100644
index 78ef7c29..00000000
--- a/apis/metal3.io/v1alpha1/bmceventsubscription_webhook_test.go
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
-Copyright 2019 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha1
-
-import (
-	"testing"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-func TestBMCEventSubscriptionUpdate(t *testing.T) {
-	tests := []struct {
-		name      string
-		bes       *BMCEventSubscription
-		old       *BMCEventSubscription
-		wantedErr string
-	}{
-		{
-			// This is valid because the spec wasn't updated.
-			name: "valid",
-			bes: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "test-namespace",
-				},
-				Spec: BMCEventSubscriptionSpec{},
-			},
-			old: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "test-namespace",
-				},
-				Spec: BMCEventSubscriptionSpec{},
-			},
-			wantedErr: "",
-		},
-		{
-			name: "invalid",
-			bes: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "test-namespace",
-				},
-				Spec: BMCEventSubscriptionSpec{},
-			},
-			old: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "test-namespace",
-				},
-				Spec: BMCEventSubscriptionSpec{Context: "abc"},
-			},
-			wantedErr: "subscriptions cannot be updated, please recreate it",
-		},
-		{
-			// Status updates are valid
-			name: "status updated",
-			bes: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "test-namespace",
-				},
-				Spec: BMCEventSubscriptionSpec{},
-				Status: BMCEventSubscriptionStatus{
-					SubscriptionID: "some-id",
-				},
-			},
-			old: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "test-namespace",
-				},
-				Spec:   BMCEventSubscriptionSpec{},
-				Status: BMCEventSubscriptionStatus{},
-			},
-			wantedErr: "",
-		},
-		{
-			// Finalizer updates are valid
-			name: "finalizers updated",
-			bes: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:       "test",
-					Namespace:  "test-namespace",
-					Finalizers: []string{BMCEventSubscriptionFinalizer},
-				},
-				Spec:   BMCEventSubscriptionSpec{},
-				Status: BMCEventSubscriptionStatus{},
-			},
-			old: &BMCEventSubscription{
-				TypeMeta: metav1.TypeMeta{
-					Kind:       "BMCEventSubscription",
-					APIVersion: "metal3.io/v1alpha1",
-				},
-				ObjectMeta: metav1.ObjectMeta{
-					Name:       "test",
-					Namespace:  "test-namespace",
-					Finalizers: []string{},
-				},
-				Spec:   BMCEventSubscriptionSpec{},
-				Status: BMCEventSubscriptionStatus{},
-			},
-			wantedErr: "",
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if err := tt.bes.ValidateUpdate(tt.old); !errorContains(err, tt.wantedErr) {
-				t.Errorf("BMCEventSubscription.ValidateUpdate() error = %v, wantErr %v", err, tt.wantedErr)
-			}
-		})
-	}
-}
diff --git a/controllers/metal3.io/baremetalhost_controller_test.go b/controllers/metal3.io/baremetalhost_controller_test.go
index 33e22fc7..92d62c14 100644
--- a/controllers/metal3.io/baremetalhost_controller_test.go
+++ b/controllers/metal3.io/baremetalhost_controller_test.go
@@ -17,7 +17,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/apimachinery/pkg/util/intstr"
 
 	promutil "github.com/prometheus/client_golang/prometheus/testutil"
 	ctrl "sigs.k8s.io/controller-runtime"
@@ -79,31 +78,6 @@ func newHost(name string, spec *metal3v1alpha1.BareMetalHostSpec) *metal3v1alpha
 	}
 }
 
-func newHostFirmwareSettings(host *metal3v1alpha1.BareMetalHost, conditions []metav1.Condition) *metal3v1alpha1.HostFirmwareSettings {
-	hfs := &metal3v1alpha1.HostFirmwareSettings{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      host.Name,
-			Namespace: host.Namespace,
-		},
-		Spec: metal3v1alpha1.HostFirmwareSettingsSpec{
-			Settings: metal3v1alpha1.DesiredSettingsMap{
-				"ProcVirtualization": intstr.FromString("Disabled"),
-				"SecureBoot":         intstr.FromString("Enabled"),
-			},
-		},
-		Status: metal3v1alpha1.HostFirmwareSettingsStatus{
-			Settings: metal3v1alpha1.SettingsMap{
-				"ProcVirtualization": "Disabled",
-				"SecureBoot":         "Enabled",
-			},
-		},
-	}
-
-	hfs.Status.Conditions = conditions
-
-	return hfs
-}
-
 func newDefaultNamedHost(name string, t *testing.T) *metal3v1alpha1.BareMetalHost {
 	spec := &metal3v1alpha1.BareMetalHostSpec{
 		BMC: metal3v1alpha1.BMCDetails{
@@ -2548,115 +2522,3 @@ func TestPreprovImageAvailable(t *testing.T) {
 		})
 	}
 }
-
-// TestHostFirwmareSettings verifies that a change to the HFS
-// can be detected as it will be used to set state to Preparing
-func TestHostFirmwareSettings(t *testing.T) {
-
-	testCases := []struct {
-		Scenario   string
-		Conditions []metav1.Condition
-		Dirty      bool
-	}{
-		{
-			Scenario: "spec and status the same",
-			Conditions: []metav1.Condition{
-				{Type: "Valid", Status: "True", Reason: "Success"},
-			},
-			Dirty: false,
-		},
-		{
-			Scenario: "spec changed",
-			Conditions: []metav1.Condition{
-				{Type: "ChangeDetected", Status: "True", Reason: "Success"},
-				{Type: "Valid", Status: "True", Reason: "Success"},
-			},
-			Dirty: true,
-		},
-		{
-			Scenario: "spec invalid",
-			Conditions: []metav1.Condition{
-				{Type: "ChangeDetected", Status: "True", Reason: "Success"},
-				{Type: "Valid", Status: "False", Reason: "Success"},
-			},
-			Dirty: false,
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.Scenario, func(t *testing.T) {
-			host := newDefaultHost(t)
-			r := newTestReconciler(host)
-			i := makeReconcileInfo(host)
-			i.request = newRequest(host)
-
-			hfs := newHostFirmwareSettings(host, tc.Conditions)
-			r.Create(goctx.TODO(), hfs)
-
-			dirty, _, err := r.getHostFirmwareSettings(i)
-			if err != nil {
-				t.Fatal(err)
-			}
-			assert.Equal(t, tc.Dirty, dirty, "dirty flag did not match")
-		})
-	}
-
-}
-
-func TestBMHTransitionToPreparing(t *testing.T) {
-	var True = true
-	var False = false
-	host := newDefaultHost(t)
-	host.Spec.Online = true
-	host.Spec.ExternallyProvisioned = false
-	host.Spec.ConsumerRef = &corev1.ObjectReference{}
-	r := newTestReconciler(host)
-
-	waitForProvisioningState(t, r, host, metal3v1alpha1.StateAvailable)
-
-	// use different values between spec and status to force cleaning
-	host.Status.Provisioning.Firmware = &metal3v1alpha1.FirmwareConfig{
-		VirtualizationEnabled:             &True,
-		SimultaneousMultithreadingEnabled: &False,
-	}
-	host.Spec.Firmware = &metal3v1alpha1.FirmwareConfig{
-		VirtualizationEnabled:             &False,
-		SimultaneousMultithreadingEnabled: &True,
-	}
-
-	err := r.Update(goctx.TODO(), host)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	waitForProvisioningState(t, r, host, metal3v1alpha1.StatePreparing)
-}
-
-func TestHFSTransitionToPreparing(t *testing.T) {
-	host := newDefaultHost(t)
-	host.Spec.Online = true
-	host.Spec.ConsumerRef = &corev1.ObjectReference{}
-	host.Spec.ExternallyProvisioned = false
-	r := newTestReconciler(host)
-
-	waitForProvisioningState(t, r, host, metal3v1alpha1.StateAvailable)
-
-	// Update HFS so host will go through cleaning
-	hfs := &metal3v1alpha1.HostFirmwareSettings{}
-	key := client.ObjectKey{
-		Namespace: host.ObjectMeta.Namespace, Name: host.ObjectMeta.Name}
-	if err := r.Get(goctx.TODO(), key, hfs); err != nil {
-		t.Fatal(err)
-	}
-
-	hfs.Status = metal3v1alpha1.HostFirmwareSettingsStatus{
-		Conditions: []metav1.Condition{
-			{Type: "ChangeDetected", Status: "True", Reason: "Success"},
-			{Type: "Valid", Status: "True", Reason: "Success"},
-		},
-	}
-
-	r.Update(goctx.TODO(), hfs)
-
-	waitForProvisioningState(t, r, host, metal3v1alpha1.StatePreparing)
-}
diff --git a/controllers/metal3.io/host_state_machine_test.go b/controllers/metal3.io/host_state_machine_test.go
index 0b93f10a..fde1bd08 100644
--- a/controllers/metal3.io/host_state_machine_test.go
+++ b/controllers/metal3.io/host_state_machine_test.go
@@ -1262,7 +1262,7 @@ func (m *mockProvisioner) UpdateHardwareState() (hwState provisioner.HardwareSta
 	return
 }
 
-func (m *mockProvisioner) Prepare(data provisioner.PrepareData, unprepared bool, force bool) (result provisioner.Result, started bool, err error) {
+func (m *mockProvisioner) Prepare(data provisioner.PrepareData, unprepared bool) (result provisioner.Result, started bool, err error) {
 	return m.getNextResultByMethod("Prepare"), m.nextResults["Prepare"].Dirty, err
 }
 
diff --git a/controllers/metal3.io/hostfirmwaresettings_test.go b/controllers/metal3.io/hostfirmwaresettings_test.go
index bd69b4a2..428c29c3 100644
--- a/controllers/metal3.io/hostfirmwaresettings_test.go
+++ b/controllers/metal3.io/hostfirmwaresettings_test.go
@@ -75,7 +75,7 @@ func (m *hsfMockProvisioner) UpdateHardwareState() (hwState provisioner.Hardware
 	return
 }
 
-func (m *hsfMockProvisioner) Prepare(data provisioner.PrepareData, unprepared bool, force bool) (result provisioner.Result, started bool, err error) {
+func (m *hsfMockProvisioner) Prepare(data provisioner.PrepareData, unprepared bool) (result provisioner.Result, started bool, err error) {
 	return
 }
 
diff --git a/pkg/hardwareutils/bmc/access_test.go b/pkg/hardwareutils/bmc/access_test.go
index 2619c2d1..9dcd84e2 100644
--- a/pkg/hardwareutils/bmc/access_test.go
+++ b/pkg/hardwareutils/bmc/access_test.go
@@ -479,7 +479,7 @@ func TestStaticDriverInfo(t *testing.T) {
 			needsMac:   true,
 			driver:     "irmc",
 			bios:       "",
-			boot:       "ipxe",
+			boot:       "pxe",
 			management: "",
 			power:      "",
 			raid:       "irmc",
diff --git a/pkg/provisioner/ironic/prepare_test.go b/pkg/provisioner/ironic/prepare_test.go
index fc9e21bb..22573288 100644
--- a/pkg/provisioner/ironic/prepare_test.go
+++ b/pkg/provisioner/ironic/prepare_test.go
@@ -207,7 +207,7 @@ func TestPrepare(t *testing.T) {
 				t.Fatalf("could not create provisioner: %s", err)
 			}
 
-			result, started, err := prov.Prepare(prepData, tc.unprepared, tc.unprepared)
+			result, started, err := prov.Prepare(prepData, tc.unprepared)
 
 			assert.Equal(t, tc.expectedStarted, started)
 			assert.Equal(t, tc.expectedDirty, result.Dirty)