Repository: metal3-io/baremetal-operator
Pull request #1490 (2023-12-12 14:02:42)

🌱 E2e: Name artifacts based on emulator
**What this PR does / why we need it**:

The goal is to be able to run jobs with vbmc and sushy-tools in
parallel. The archives must then have unique names so that they don't
overwrite each other in jenkins.

Provisioning seems to take longer with VBMC so timeout is also
increased.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #


metal3-io-bot: Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with `/test all`
lentzi90: /metal3-bmo-e2e-test
lentzi90: /metal3-bmo-e2e-test
lentzi90: /metal3-bmo-e2e-test

Patch:
diff --git a/README.md b/README.md
index 1a277a56..cd860544 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
 # Bare Metal Operator
 
-[![CLOMonitor](https://img.shields.io/endpoint?url=https://clomonitor.io/api/projects/cncf/metal3-io/badge)](https://clomonitor.io/projects/cncf/metal3-io)
 [![Ubuntu daily main build status](https://jenkins.nordix.org/buildStatus/icon?job=metal3_daily_main_integration_test_ubuntu&subject=Ubuntu%20daily%20main)](https://jenkins.nordix.org/view/Metal3/job/metal3_daily_main_integration_test_ubuntu/)
 [![CentOS daily main build status](https://jenkins.nordix.org/buildStatus/icon?job=metal3_daily_main_integration_test_centos&subject=CentOS%20daily%20main)](https://jenkins.nordix.org/view/Metal3/job/metal3_daily_main_integration_test_centos/)
 
diff --git a/apis/go.mod b/apis/go.mod
index 89383ba6..f90eaec1 100644
--- a/apis/go.mod
+++ b/apis/go.mod
@@ -3,7 +3,7 @@ module github.com/metal3-io/baremetal-operator/apis
 go 1.20
 
 require (
-	github.com/google/uuid v1.5.0
+	github.com/google/uuid v1.4.0
 	github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.4.0
 	github.com/stretchr/testify v1.8.4
 	golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
diff --git a/apis/go.sum b/apis/go.sum
index 8eb7b555..18c45998 100644
--- a/apis/go.sum
+++ b/apis/go.sum
@@ -58,8 +58,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
 github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
-github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
-github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
+github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
diff --git a/apis/metal3.io/v1alpha1/baremetalhost_types.go b/apis/metal3.io/v1alpha1/baremetalhost_types.go
index af629b64..15189eac 100644
--- a/apis/metal3.io/v1alpha1/baremetalhost_types.go
+++ b/apis/metal3.io/v1alpha1/baremetalhost_types.go
@@ -450,7 +450,7 @@ const (
 )
 
 // ChecksumType holds the algorithm name for the checksum
-// +kubebuilder:validation:Enum=md5;sha256;sha512;auto
+// +kubebuilder:validation:Enum=md5;sha256;sha512
 type ChecksumType string
 
 const (
@@ -462,9 +462,6 @@ const (
 
 	// SHA512 checksum type
 	SHA512 ChecksumType = "sha512"
-
-	// Automatically detect
-	AutoChecksum ChecksumType = "auto"
 )
 
 // Image holds the details of an image either to provisioned or that
@@ -476,9 +473,8 @@ type Image struct {
 	// Checksum is the checksum for the image.
 	Checksum string `json:"checksum,omitempty"`
 
-	// ChecksumType is the checksum algorithm for the image, e.g md5, sha256 or sha512.
-	// The special value "auto" can be used to detect the algorithm from the checksum.
-	// If missing, MD5 is used. If in doubt, use "auto".
+	// ChecksumType is the checksum algorithm for the image.
+	// e.g md5, sha256, sha512
 	ChecksumType ChecksumType `json:"checksumType,omitempty"`
 
 	// DiskFormat contains the format of the image (raw, qcow2, ...).
@@ -1100,8 +1096,6 @@ func (image *Image) GetChecksum() (checksum, checksumType string, ok bool) {
 		checksumType = string(MD5)
 	case MD5, SHA256, SHA512:
 		checksumType = string(image.ChecksumType)
-	case AutoChecksum:
-		// No type, let Ironic detect
 	default:
 		return
 	}
diff --git a/cmd/make-bm-worker/main.go b/cmd/make-bm-worker/main.go
index 5eac99d8..5394d89b 100644
--- a/cmd/make-bm-worker/main.go
+++ b/cmd/make-bm-worker/main.go
@@ -62,9 +62,9 @@ func main() {
 	}
 
 	switch *imageChecksumType {
-	case "", "md5", "sha256", "sha512", "auto":
+	case "", "md5", "sha256", "sha512":
 	default:
-		fmt.Fprintf(os.Stderr, "Invalid image checksum type %q, use \"md5\", \"sha256\", \"sha512\" or \"auto\"\n", *imageChecksumType)
+		fmt.Fprintf(os.Stderr, "Invalid image checksum type %q, use \"md5\", \"sha256\" or \"sha512\"\n", *imageChecksumType)
 		os.Exit(1)
 	}
 
diff --git a/config/base/crds/bases/metal3.io_baremetalhosts.yaml b/config/base/crds/bases/metal3.io_baremetalhosts.yaml
index d2aa2121..77a57565 100644
--- a/config/base/crds/bases/metal3.io_baremetalhosts.yaml
+++ b/config/base/crds/bases/metal3.io_baremetalhosts.yaml
@@ -221,15 +221,12 @@ spec:
                     description: Checksum is the checksum for the image.
                     type: string
                   checksumType:
-                    description: ChecksumType is the checksum algorithm for the image,
-                      e.g md5, sha256 or sha512. The special value "auto" can be used
-                      to detect the algorithm from the checksum. If missing, MD5 is
-                      used. If in doubt, use "auto".
+                    description: ChecksumType is the checksum algorithm for the image.
+                      e.g md5, sha256, sha512
                     enum:
                     - md5
                     - sha256
                     - sha512
-                    - auto
                     type: string
                   format:
                     description: DiskFormat contains the format of the image (raw,
@@ -874,14 +871,11 @@ spec:
                         type: string
                       checksumType:
                         description: ChecksumType is the checksum algorithm for the
-                          image, e.g md5, sha256 or sha512. The special value "auto"
-                          can be used to detect the algorithm from the checksum. If
-                          missing, MD5 is used. If in doubt, use "auto".
+                          image. e.g md5, sha256, sha512
                         enum:
                         - md5
                         - sha256
                         - sha512
-                        - auto
                         type: string
                       format:
                         description: DiskFormat contains the format of the image (raw,
diff --git a/config/render/capm3.yaml b/config/render/capm3.yaml
index f013ce50..ba6d83f1 100644
--- a/config/render/capm3.yaml
+++ b/config/render/capm3.yaml
@@ -221,15 +221,12 @@ spec:
                     description: Checksum is the checksum for the image.
                     type: string
                   checksumType:
-                    description: ChecksumType is the checksum algorithm for the image,
-                      e.g md5, sha256 or sha512. The special value "auto" can be used
-                      to detect the algorithm from the checksum. If missing, MD5 is
-                      used. If in doubt, use "auto".
+                    description: ChecksumType is the checksum algorithm for the image.
+                      e.g md5, sha256, sha512
                     enum:
                     - md5
                     - sha256
                     - sha512
-                    - auto
                     type: string
                   format:
                     description: DiskFormat contains the format of the image (raw,
@@ -874,14 +871,11 @@ spec:
                         type: string
                       checksumType:
                         description: ChecksumType is the checksum algorithm for the
-                          image, e.g md5, sha256 or sha512. The special value "auto"
-                          can be used to detect the algorithm from the checksum. If
-                          missing, MD5 is used. If in doubt, use "auto".
+                          image. e.g md5, sha256, sha512
                         enum:
                         - md5
                         - sha256
                         - sha512
-                        - auto
                         type: string
                       format:
                         description: DiskFormat contains the format of the image (raw,
diff --git a/docs/api.md b/docs/api.md
index 1f0ed8f1..5e9432b3 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -91,8 +91,8 @@ The sub-fields are
 * *checksum* -- The actual checksum or a URL to a file containing
   the checksum for the image at *image.url*.
 * *checksumType* -- Checksum algorithms can be specified. Currently
-  only `md5`, `sha256`, `sha512` are recognized. Use `auto` to auto-detect
-  the algorithm from the value. If nothing is specified, `md5` is assumed.
+  only `md5`, `sha256`, `sha512` are recognized. If nothing is specified
+  `md5` is assumed.
 * *format* -- This is the disk format of the image. It can be one of `raw`,
   `qcow2`, `vdi`, `vmdk`, `live-iso` or be left unset.
   Setting it to raw enables raw image streaming in Ironic agent for that image.
diff --git a/go.mod b/go.mod
index d21e293e..104858c6 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.17.0
 	github.com/stretchr/testify v1.8.4
-	go.etcd.io/etcd/client/pkg/v3 v3.5.11
+	go.etcd.io/etcd/client/pkg/v3 v3.5.10
 	go.uber.org/zap v1.26.0
 	golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
 	k8s.io/api v0.27.7
@@ -43,7 +43,7 @@ require (
 	github.com/google/gnostic v0.5.7-v3refs // indirect
 	github.com/google/go-cmp v0.6.0 // indirect
 	github.com/google/gofuzz v1.1.0 // indirect
-	github.com/google/uuid v1.5.0 // indirect
+	github.com/google/uuid v1.4.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
diff --git a/go.sum b/go.sum
index b4ae355f..c470351e 100644
--- a/go.sum
+++ b/go.sum
@@ -71,8 +71,8 @@ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
 github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
 github.com/google/safetext v0.0.0-20230106111101-7156a760e523 h1:i4NsbmB9pD5+Ggp5GZKyvYY6MkjvPE8CIMlkvXFF8gA=
 github.com/google/safetext v0.0.0-20230106111101-7156a760e523/go.mod h1:mJNEy0r5YPHC7ChQffpOszlGB4L1iqjXWpIEKcFpr9s=
-github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
-github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
+github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gophercloud/gophercloud v1.5.1-0.20231117122435-08456f7fe42e h1:acHzJUXVfS+GImmi+yyM2+AOiaO94Z4KaTTFVU6Ov9U=
 github.com/gophercloud/gophercloud v1.5.1-0.20231117122435-08456f7fe42e/go.mod h1:ecnaHbFxBunc2UeAONDQbkQacv6WP1syeZ02TgAB7kA=
 github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
@@ -143,8 +143,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-go.etcd.io/etcd/client/pkg/v3 v3.5.11 h1:bT2xVspdiCj2910T0V+/KHcVKjkUrCZVtk8J2JF2z1A=
-go.etcd.io/etcd/client/pkg/v3 v3.5.11/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4=
+go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0=
+go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go
index 45b4d1b2..88ed19e0 100644
--- a/pkg/provisioner/ironic/ironic.go
+++ b/pkg/provisioner/ironic/ironic.go
@@ -965,21 +965,26 @@ func (p *ironicProvisioner) setDirectDeployUpdateOptsForNode(ironicNode *nodes.N
 		return
 	}
 
+	// FIXME: For older versions of ironic that do not have
+	// https://review.opendev.org/#/c/711816/ failing to include the
+	// 'image_checksum' causes ironic to refuse to provision the
+	// image, even if the other hash value parameters are given. We
+	// only want to do that for MD5, however, because those versions
+	// of ironic only support MD5 checksums.
+	var legacyChecksum *string
+	if checksumType == string(metal3api.MD5) {
+		legacyChecksum = &checksum
+	}
+
 	optValues := optionsData{
 		// Remove any boot_iso field
-		"boot_iso":          nil,
-		"image_source":      imageData.URL,
-		"image_disk_format": imageData.DiskFormat,
-	}
+		"boot_iso": nil,
 
-	if checksumType == "" {
-		optValues["image_checksum"] = checksum
-		optValues["image_os_hash_algo"] = nil
-		optValues["image_os_hash_value"] = nil
-	} else {
-		optValues["image_checksum"] = nil
-		optValues["image_os_hash_algo"] = checksumType
-		optValues["image_os_hash_value"] = checksum
+		"image_source":        imageData.URL,
+		"image_os_hash_algo":  checksumType,
+		"image_os_hash_value": checksum,
+		"image_checksum":      legacyChecksum,
+		"image_disk_format":   imageData.DiskFormat,
 	}
 	updater.
 		SetInstanceInfoOpts(optValues, ironicNode)
@@ -1277,24 +1282,15 @@ func (p *ironicProvisioner) ironicHasSameImage(ironicNode *nodes.Node, image met
 			"provisionState", ironicNode.ProvisionState)
 	} else {
 		checksum, checksumType, _ := image.GetChecksum()
-		if checksumType == "" {
-			sameImage = (ironicNode.InstanceInfo["image_source"] == image.URL &&
-				ironicNode.InstanceInfo["image_checksum"] == checksum &&
-				ironicNode.InstanceInfo["image_os_hash_algo"] == nil &&
-				ironicNode.InstanceInfo["image_os_hash_value"] == nil)
-		} else {
-			sameImage = (ironicNode.InstanceInfo["image_source"] == image.URL &&
-				ironicNode.InstanceInfo["image_checksum"] == nil &&
-				ironicNode.InstanceInfo["image_os_hash_algo"] == checksumType &&
-				ironicNode.InstanceInfo["image_os_hash_value"] == checksum)
-		}
+		sameImage = (ironicNode.InstanceInfo["image_source"] == image.URL &&
+			ironicNode.InstanceInfo["image_os_hash_algo"] == checksumType &&
+			ironicNode.InstanceInfo["image_os_hash_value"] == checksum)
 		p.log.Info("checking image settings",
 			"source", ironicNode.InstanceInfo["image_source"],
-			"checksumType", checksumType,
-			"checksum", checksum,
+			"image_os_hash_algo", checksumType,
+			"image_os_has_value", checksum,
 			"same", sameImage,
-			"provisionState", ironicNode.ProvisionState,
-			"iinfo", ironicNode.InstanceInfo)
+			"provisionState", ironicNode.ProvisionState)
 	}
 	return sameImage
 }


Test patch:
diff --git a/apis/metal3.io/v1alpha1/baremetalhost_types_test.go b/apis/metal3.io/v1alpha1/baremetalhost_types_test.go
index 815dccdc..5e1435a6 100644
--- a/apis/metal3.io/v1alpha1/baremetalhost_types_test.go
+++ b/apis/metal3.io/v1alpha1/baremetalhost_types_test.go
@@ -317,10 +317,9 @@ func TestCredentialStatusMatch(t *testing.T) {
 
 func TestGetImageChecksum(t *testing.T) {
 	for _, tc := range []struct {
-		Scenario     string
-		Host         BareMetalHost
-		Expected     bool
-		ExpectedType string
+		Scenario string
+		Host     BareMetalHost
+		Expected bool
 	}{
 		{
 			Scenario: "both checksum value and type specified",
@@ -336,8 +335,7 @@ func TestGetImageChecksum(t *testing.T) {
 					},
 				},
 			},
-			Expected:     true,
-			ExpectedType: "md5",
+			Expected: true,
 		},
 		{
 			Scenario: "checksum value specified but not type",
@@ -352,25 +350,7 @@ func TestGetImageChecksum(t *testing.T) {
 					},
 				},
 			},
-			Expected:     true,
-			ExpectedType: "md5",
-		},
-		{
-			Scenario: "checksum value specified, auto type",
-			Host: BareMetalHost{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "myhost",
-					Namespace: "myns",
-				},
-				Spec: BareMetalHostSpec{
-					Image: &Image{
-						Checksum:     "md5hash",
-						ChecksumType: AutoChecksum,
-					},
-				},
-			},
-			Expected:     true,
-			ExpectedType: "",
+			Expected: true,
 		},
 		{
 			Scenario: "sha256 checksum value and type specified",
@@ -386,8 +366,7 @@ func TestGetImageChecksum(t *testing.T) {
 					},
 				},
 			},
-			Expected:     true,
-			ExpectedType: "sha256",
+			Expected: true,
 		},
 		{
 			Scenario: "sha512 checksum value and type specified",
@@ -403,8 +382,7 @@ func TestGetImageChecksum(t *testing.T) {
 					},
 				},
 			},
-			Expected:     true,
-			ExpectedType: "sha512",
+			Expected: true,
 		},
 		{
 			Scenario: "checksum value not specified",
@@ -465,10 +443,9 @@ func TestGetImageChecksum(t *testing.T) {
 		},
 	} {
 		t.Run(tc.Scenario, func(t *testing.T) {
-			_, checksumType, actual := tc.Host.Spec.Image.GetChecksum()
-			assert.Equal(t, tc.Expected, actual)
-			if tc.Expected {
-				assert.Equal(t, tc.ExpectedType, checksumType)
+			_, _, actual := tc.Host.Spec.Image.GetChecksum()
+			if actual != tc.Expected {
+				t.Errorf("expected %v but got %v", tc.Expected, actual)
 			}
 		})
 	}
diff --git a/hack/ci-e2e.sh b/hack/ci-e2e.sh
index d30156fc..3f6ea919 100755
--- a/hack/ci-e2e.sh
+++ b/hack/ci-e2e.sh
@@ -2,7 +2,7 @@
 
 # -----------------------------------------------------------------------------
 # Description: This script sets up the environment and runs E2E tests for the
-#              BMO project. It uses either vbmc or sushy-tools based on 
+#              BMO project. It uses either vbmc or sushy-tools based on
 #              the BMO_E2E_EMULATOR environment variable.
 # Usage:       export BMO_E2E_EMULATOR="vbmc"  # Or "sushy-tools"
 #              ./ci-e2e.sh
@@ -21,7 +21,6 @@ BMO_E2E_EMULATOR=${BMO_E2E_EMULATOR:-"sushy-tools"}
 "${REPO_ROOT}/hack/e2e/ensure_go.sh"
 export PATH="${PATH}:/usr/local/go/bin"
 "${REPO_ROOT}/hack/e2e/ensure_minikube.sh"
-"${REPO_ROOT}/hack/e2e/ensure_htpasswd.sh"
 # CAPI test framework uses kubectl in the background
 "${REPO_ROOT}/hack/e2e/ensure_kubectl.sh"
 
@@ -116,18 +115,17 @@ IMAGE_FILE="cirros-${CIRROS_VERSION}-x86_64-disk.img"
 export IMAGE_CHECKSUM="c8fc807773e5354afe61636071771906"
 export IMAGE_URL="http://${IP_ADDRESS}/${IMAGE_FILE}"
 IMAGE_DIR="${REPO_ROOT}/test/e2e/images"
-mkdir -p "${IMAGE_DIR}"
 
 ## Download and run image server
-wget --quiet -P "${IMAGE_DIR}"/ https://artifactory.nordix.org/artifactory/metal3/images/iso/"${IMAGE_FILE}"
+mkdir -p "${IMAGE_DIR}"
+pushd "${IMAGE_DIR}"
+wget --quiet https://artifactory.nordix.org/artifactory/metal3/images/iso/"${IMAGE_FILE}"
+popd
 
 docker run --name image-server-e2e -d \
   -p 80:8080 \
   -v "${IMAGE_DIR}:/usr/share/nginx/html" nginxinc/nginx-unprivileged
 
-# Generate the key pair
-ssh-keygen -t ed25519 -f "${IMAGE_DIR}/ssh_testkey" -q -N ""
-
 # Generate credentials
 BMO_OVERLAY="${REPO_ROOT}/config/overlays/e2e"
 IRONIC_OVERLAY="${REPO_ROOT}/ironic-deployment/overlays/e2e"
@@ -165,6 +163,6 @@ sudo sh -c "cp -r /var/log/libvirt/qemu/* ${LOGS_DIR}/qemu/"
 sudo chown -R "${USER}:${USER}" "${LOGS_DIR}/qemu"
 
 # Collect all artifacts
-tar --directory test/e2e/ -czf artifacts.tar.gz _artifacts
+tar --directory test/e2e/ -czf "artifacts-e2e-${BMO_E2E_EMULATOR}.tar.gz" _artifacts
 
 exit "${test_status}"
diff --git a/hack/e2e/ensure_htpasswd.sh b/hack/e2e/ensure_htpasswd.sh
deleted file mode 100755
index f37b2599..00000000
--- a/hack/e2e/ensure_htpasswd.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-
-set -eux
-
-# Check if htpasswd is installed and install it if not
-verify_htpasswd()
-{
-    if ! [ -x "$(command -v htpasswd)" ]; then
-        echo "htpasswd could not be found, installing..."
-        sudo apt-get update
-        sudo apt-get install -y apache2-utils
-    fi
-}
-
-verify_htpasswd
diff --git a/pkg/provisioner/ironic/provision_test.go b/pkg/provisioner/ironic/provision_test.go
index a859a222..121b0d99 100644
--- a/pkg/provisioner/ironic/provision_test.go
+++ b/pkg/provisioner/ironic/provision_test.go
@@ -343,20 +343,6 @@ func TestIronicHasSameImage(t *testing.T) {
 			hostChecksum:     "thechecksum",
 			hostChecksumType: v1alpha1.MD5,
 		},
-		{
-			name:      "image same - auto checksum",
-			expected:  true,
-			liveImage: false,
-			node: nodes.Node{
-				InstanceInfo: map[string]interface{}{
-					"image_source":   "theimage",
-					"image_checksum": "thechecksum",
-				},
-			},
-			hostImage:        "theimage",
-			hostChecksum:     "thechecksum",
-			hostChecksumType: "auto",
-		},
 		{
 			name:      "image different",
 			expected:  false,
@@ -387,21 +373,6 @@ func TestIronicHasSameImage(t *testing.T) {
 			hostChecksum:     "different",
 			hostChecksumType: v1alpha1.MD5,
 		},
-		{
-			name:      "image checksum changed to auto",
-			expected:  false,
-			liveImage: false,
-			node: nodes.Node{
-				InstanceInfo: map[string]interface{}{
-					"image_source":        "theimage",
-					"image_os_hash_value": "thechecksum",
-					"image_os_hash_algo":  "md5",
-				},
-			},
-			hostImage:        "theimage",
-			hostChecksum:     "thechecksum",
-			hostChecksumType: "auto",
-		},
 		{
 			name:      "image checksum type different",
 			expected:  false,
diff --git a/pkg/provisioner/ironic/validatemanagementaccess_test.go b/pkg/provisioner/ironic/validatemanagementaccess_test.go
index 072e58b5..eb1f99e6 100644
--- a/pkg/provisioner/ironic/validatemanagementaccess_test.go
+++ b/pkg/provisioner/ironic/validatemanagementaccess_test.go
@@ -153,7 +153,6 @@ func TestValidateManagementAccessCreateWithImage(t *testing.T) {
 	host.Status.Provisioning.ID = "" // so we don't lookup by uuid
 	host.Spec.Image.URL = "theimagefoo"
 	host.Spec.Image.Checksum = "thechecksumxyz"
-	host.Spec.Image.ChecksumType = "auto"
 
 	var createdNode *nodes.Node
 
@@ -392,35 +391,14 @@ func TestValidateManagementAccessExistingSteadyStateNoUpdate(t *testing.T) {
 		},
 		{
 			Image: &metal3api.Image{
-				URL:          "theimage",
-				Checksum:     "thechecksum",
-				ChecksumType: "auto",
-			},
-			InstanceInfo: map[string]interface{}{
-				"image_source":   "theimage",
-				"image_checksum": "thechecksum",
-				"capabilities":   map[string]interface{}{},
-			},
-			DriverInfo: map[string]interface{}{
-				"force_persistent_boot_device": "Default",
-				"deploy_kernel":                "http://deploy.test/ipa.kernel",
-				"deploy_ramdisk":               "http://deploy.test/ipa.initramfs",
-				"test_address":                 "test.bmc",
-				"test_username":                "",
-				"test_password":                "******", // ironic returns a placeholder
-				"test_port":                    "42",
-			},
-		},
-		{
-			Image: &metal3api.Image{
-				URL:          "theimage",
-				Checksum:     "thechecksum",
-				ChecksumType: "sha256",
+				URL:      "theimage",
+				Checksum: "thechecksum",
 			},
 			InstanceInfo: map[string]interface{}{
 				"image_source":        "theimage",
-				"image_os_hash_algo":  "sha256",
+				"image_os_hash_algo":  "md5",
 				"image_os_hash_value": "thechecksum",
+				"image_checksum":      "thechecksum",
 				"capabilities":        map[string]interface{}{},
 			},
 			DriverInfo: map[string]interface{}{
diff --git a/test/e2e/basic_ops_test.go b/test/e2e/basic_ops_test.go
index e06a9656..a967a908 100644
--- a/test/e2e/basic_ops_test.go
+++ b/test/e2e/basic_ops_test.go
@@ -48,11 +48,7 @@ var _ = Describe("basic", func() {
 
 	It("should control power cycle of BMH though annotations", func() {
 		By("creating a secret with BMH credentials")
-		bmcCredentialsData := map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("creating a BMH")
 		bmh := metal3api.BareMetalHost{
diff --git a/test/e2e/basic_provisioning_test.go b/test/e2e/basic_provisioning_test.go
index 2f829492..be3ae82b 100644
--- a/test/e2e/basic_provisioning_test.go
+++ b/test/e2e/basic_provisioning_test.go
@@ -4,11 +4,8 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"os"
 	"time"
 
-	"golang.org/x/crypto/ssh"
-
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
@@ -20,8 +17,6 @@ import (
 	"sigs.k8s.io/cluster-api/util/patch"
 
 	metal3api "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
-
-	capm3_e2e "github.com/metal3-io/cluster-api-provider-metal3/test/e2e"
 )
 
 var _ = Describe("BMH Provisioning and Annotation Management", func() {
@@ -52,11 +47,7 @@ var _ = Describe("BMH Provisioning and Annotation Management", func() {
 
 	It("provisions a BMH, applies detached and status annotations, then deprovisions", func() {
 		By("Creating a secret with BMH credentials")
-		bmcCredentialsData := map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("Creating a BMH with inspection disabled and hardware details added")
 		bmh := metal3api.BareMetalHost{
@@ -74,9 +65,8 @@ var _ = Describe("BMH Provisioning and Annotation Management", func() {
 					Address:         bmcAddress,
 					CredentialsName: "bmc-credentials",
 				},
-				BootMode:              metal3api.Legacy,
-				BootMACAddress:        bootMacAddress,
-				AutomatedCleaningMode: "disabled",
+				BootMode:       metal3api.Legacy,
+				BootMACAddress: bootMacAddress,
 			},
 		}
 		err := clusterProxy.GetClient().Create(ctx, &bmh)
@@ -93,23 +83,12 @@ var _ = Describe("BMH Provisioning and Annotation Management", func() {
 		helper, err := patch.NewHelper(&bmh, clusterProxy.GetClient())
 		Expect(err).NotTo(HaveOccurred())
 		bmh.Spec.Image = &metal3api.Image{
-			URL:          e2eConfig.GetVariable("IMAGE_URL"),
-			Checksum:     e2eConfig.GetVariable("IMAGE_CHECKSUM"),
-			ChecksumType: metal3api.AutoChecksum,
+			URL:      e2eConfig.GetVariable("IMAGE_URL"),
+			Checksum: e2eConfig.GetVariable("IMAGE_CHECKSUM"),
 		}
 		bmh.Spec.RootDeviceHints = &metal3api.RootDeviceHints{
 			DeviceName: "/dev/vda",
 		}
-		// The ssh check is not possible in all situations (e.g. fixture) so it can be skipped
-		if e2eConfig.GetVariable("SSH_CHECK_PROVISIONED") == "true" {
-			userDataSecretName := "user-data"
-			sshPubKeyPath := e2eConfig.GetVariable("SSH_PUB_KEY")
-			createCirrosInstanceAndHostnameUserdata(ctx, clusterProxy.GetClient(), namespace.Name, userDataSecretName, sshPubKeyPath)
-			bmh.Spec.UserData = &corev1.SecretReference{
-				Name:      userDataSecretName,
-				Namespace: namespace.Name,
-			}
-		}
 		Expect(helper.Patch(ctx, &bmh)).To(Succeed())
 
 		By("Waiting for the BMH to be in provisioning state")
@@ -126,22 +105,6 @@ var _ = Describe("BMH Provisioning and Annotation Management", func() {
 			State:  metal3api.StateProvisioned,
 		}, e2eConfig.GetIntervals(specName, "wait-provisioned")...)
 
-		// The ssh check is not possible in all situations (e.g. fixture) so it can be skipped
-		if e2eConfig.GetVariable("SSH_CHECK_PROVISIONED") == "true" {
-			By("Verifying the node booting from disk")
-			keyPath := e2eConfig.GetVariable("SSH_PRIV_KEY")
-			key, err := os.ReadFile(keyPath)
-			Expect(err).NotTo(HaveOccurred(), "unable to read private key")
-
-			signer, err := ssh.ParsePrivateKey(key)
-			Expect(err).NotTo(HaveOccurred(), "unable to parse private key")
-
-			auth := ssh.PublicKeys(signer)
-			PerformSSHBootCheck(e2eConfig, "disk", auth)
-		} else {
-			capm3_e2e.Logf("WARNING: Skipping SSH check since SSH_CHECK_PROVISIONED != true")
-		}
-
 		By("Retrieving the latest BMH object")
 		err = clusterProxy.GetClient().Get(ctx, types.NamespacedName{
 			Name:      bmh.Name,
@@ -193,11 +156,7 @@ var _ = Describe("BMH Provisioning and Annotation Management", func() {
 		}, e2eConfig.GetIntervals(specName, "wait-secret-deletion")...).Should(BeTrue())
 
 		By("Creating a secret with BMH credentials")
-		bmcCredentialsData = map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("Recreating the BMH with the previously saved status in the status annotation")
 		bmh = metal3api.BareMetalHost{
@@ -214,9 +173,8 @@ var _ = Describe("BMH Provisioning and Annotation Management", func() {
 					Address:         bmcAddress,
 					CredentialsName: "bmc-credentials",
 				},
-				BootMode:              metal3api.Legacy,
-				BootMACAddress:        bootMacAddress,
-				AutomatedCleaningMode: "disabled",
+				BootMode:       metal3api.Legacy,
+				BootMACAddress: bootMacAddress,
 				Image: &metal3api.Image{
 					URL:      e2eConfig.GetVariable("IMAGE_URL"),
 					Checksum: e2eConfig.GetVariable("IMAGE_CHECKSUM"),
diff --git a/test/e2e/common.go b/test/e2e/common.go
index c559e538..4e96b6ab 100644
--- a/test/e2e/common.go
+++ b/test/e2e/common.go
@@ -154,7 +154,7 @@ func (c *Config) GetVariable(varName string) string {
 	}
 
 	value, ok := c.Variables[varName]
-	Expect(ok).To(BeTrue(), fmt.Sprintf("Configuration variable '%s' not found", varName))
+	Expect(ok).To(BeTrue())
 	return value
 }
 
@@ -281,16 +281,24 @@ func buildKustomizeManifest(source string) ([]byte, error) {
 	return resources.AsYaml()
 }
 
-func CreateSecret(ctx context.Context, client client.Client, secretNamespace, secretName string, data map[string]string) {
-	secret := corev1.Secret{
+func CreateBMHCredentialsSecret(ctx context.Context, client client.Client, secretNamespace, secretName, username, password string) error {
+	bmcCredentials := corev1.Secret{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      secretName,
 			Namespace: secretNamespace,
 		},
-		StringData: data,
+		StringData: map[string]string{
+			"username": username,
+			"password": password,
+		},
 	}
 
-	Expect(client.Create(ctx, &secret)).NotTo(HaveOccurred(), fmt.Sprintf("Failed to create secret '%s/%s'", secretNamespace, secretName))
+	err := client.Create(ctx, &bmcCredentials)
+	if err != nil {
+		return fmt.Errorf("failed to create BMC credentials secret: %w", err)
+	}
+
+	return nil
 }
 
 func executeSSHCommand(client *ssh.Client, command string) (string, error) {
@@ -342,72 +350,12 @@ func IsBootedFromDisk(client *ssh.Client) (bool, error) {
 		return false, fmt.Errorf("error executing 'df -h': %w", err)
 	}
 
-	bootedFromDisk := HasRootOnDisk(output)
-	if bootedFromDisk {
+	isDisk := HasRootOnDisk(output)
+	if isDisk {
 		capm3_e2e.Logf("System is booted from a disk.")
 	} else {
 		capm3_e2e.Logf("System is booted from a live ISO.")
 	}
 
-	return bootedFromDisk, nil
-}
-
-func EstablishSSHConnection(e2eConfig *Config, auth ssh.AuthMethod, user, address string) *ssh.Client {
-	config := &ssh.ClientConfig{
-		User:            user,
-		Auth:            []ssh.AuthMethod{auth},
-		HostKeyCallback: ssh.InsecureIgnoreHostKey(), // #nosec G106
-	}
-
-	var client *ssh.Client
-	var err error
-	Eventually(func() error {
-		client, err = ssh.Dial("tcp", address, config)
-		return err
-	}, e2eConfig.GetIntervals("default", "wait-connect-ssh")...).Should(Succeed(), "Failed to establish SSH connection")
-
-	return client
-}
-
-// createCirrosInstanceAndHostnameUserdata creates a Kubernetes secret intended for cloud-init usage.
-// This userdata is utilized during BMH's initialization and setup.
-func createCirrosInstanceAndHostnameUserdata(ctx context.Context, client client.Client, namespace string, secretName string, sshPubKeyPath string) {
-	sshPubKeyData, err := os.ReadFile(sshPubKeyPath) // #nosec G304
-	Expect(err).NotTo(HaveOccurred(), "Failed to read SSH public key file")
-
-	userDataContent := fmt.Sprintf(`#!/bin/sh
-mkdir /root/.ssh
-mkdir /home/cirros/.ssh
-chmod 700 /root/.ssh
-chmod 700 /home/cirros/.ssh
-chown cirros /home/cirros/.ssh
-echo "%s" >> /home/cirros/.ssh/authorized_keys
-echo "%s" >> /root/.ssh/authorized_keys`, sshPubKeyData, sshPubKeyData)
-
-	CreateSecret(ctx, client, namespace, secretName, map[string]string{"userData": userDataContent})
-}
-
-// PerformSSHBootCheck performs an SSH check to verify the node's boot source.
-// The `expectedBootMode` parameter should be "disk" or "memory".
-// The `auth` parameter is an ssh.AuthMethod for authentication.
-func PerformSSHBootCheck(e2eConfig *Config, expectedBootMode string, auth ssh.AuthMethod) {
-	ip := e2eConfig.GetVariable("IP_BMO_E2E_0")
-	sshPort := e2eConfig.GetVariable("SSH_PORT")
-	address := fmt.Sprintf("%s:%s", ip, sshPort)
-	user := e2eConfig.GetVariable("CIRROS_USERNAME")
-
-	client := EstablishSSHConnection(e2eConfig, auth, user, address)
-	defer func() {
-		if client != nil {
-			client.Close()
-		}
-	}()
-
-	bootedFromDisk, err := IsBootedFromDisk(client)
-	Expect(err).NotTo(HaveOccurred(), "Error in verifying boot mode")
-
-	// Compare actual boot source with expected
-	isExpectedBootMode := (expectedBootMode == "disk" && bootedFromDisk) ||
-		(expectedBootMode == "memory" && !bootedFromDisk)
-	Expect(isExpectedBootMode).To(BeTrue(), fmt.Sprintf("Expected booting from %s, but found different mode", expectedBootMode))
+	return isDisk, nil
 }
diff --git a/test/e2e/config/ironic.yaml b/test/e2e/config/ironic.yaml
index 18252c81..7314dd99 100644
--- a/test/e2e/config/ironic.yaml
+++ b/test/e2e/config/ironic.yaml
@@ -35,10 +35,6 @@ variables:
   SSH_CHECK_PROVISIONED: "true"
   IP_BMO_E2E_0: "192.168.222.122"
   SSH_PORT: "22"
-  CIRROS_USERNAME: "cirros"
-  CIRROS_PASSWORD: "gocubsgo"
-  SSH_PRIV_KEY: "./images/ssh_testkey"
-  SSH_PUB_KEY: "./images/ssh_testkey.pub"
 
 intervals:
   inspection/wait-unmanaged: ["1m", "5s"]
@@ -52,7 +48,7 @@ intervals:
   ironic/wait-deployment: ["10m", "2s"]
   default/wait-power-state: ["10m", "100ms"]
   default/wait-provisioning: ["20s", "1s"]
-  default/wait-provisioned: ["5m", "1s"]
+  default/wait-provisioned: ["10m", "1s"]
   default/wait-deprovisioning: ["1m", "10ms"]
   default/wait-deleted: ["20s", "10ms"]
   default/wait-secret-deletion: ["1m", "1s"]
diff --git a/test/e2e/external_inspection_test.go b/test/e2e/external_inspection_test.go
index 03a494a5..5de4f24b 100644
--- a/test/e2e/external_inspection_test.go
+++ b/test/e2e/external_inspection_test.go
@@ -197,12 +197,8 @@ var _ = Describe("External Inspection", func() {
 	})
 
 	It("should skip inspection and become available when a BMH has annotations with hardware details and inspection disabled", func() {
-		By("Creating a secret with BMH credentials")
-		bmcCredentialsData := map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		By("creating a secret with BMH credentials")
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("creating a BMH with inspection disabled and hardware details added")
 		bmh := metal3api.BareMetalHost{
diff --git a/test/e2e/inspection_test.go b/test/e2e/inspection_test.go
index 552aabd7..9f1a6046 100644
--- a/test/e2e/inspection_test.go
+++ b/test/e2e/inspection_test.go
@@ -92,12 +92,8 @@ var _ = Describe("Inspection", func() {
 	})
 
 	It("should inspect a newly created BMH", func() {
-		By("Creating a secret with BMH credentials")
-		bmcCredentialsData := map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		By("creating a secret with BMH credentials")
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("creating a BMH")
 		bmh := metal3api.BareMetalHost{
diff --git a/test/e2e/live_iso_test.go b/test/e2e/live_iso_test.go
index fc8bb3a2..7a02e9ac 100644
--- a/test/e2e/live_iso_test.go
+++ b/test/e2e/live_iso_test.go
@@ -4,10 +4,9 @@ import (
 	"context"
 	"fmt"
 
-	"golang.org/x/crypto/ssh"
-
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	"golang.org/x/crypto/ssh"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/utils/pointer"
@@ -50,11 +49,7 @@ var _ = Describe("Live-ISO", func() {
 
 	It("should provision a BMH with live ISO and then deprovision it", func() {
 		By("Creating a secret with BMH credentials")
-		bmcCredentialsData := map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("Creating a BMH with inspection disabled and hardware details added")
 		bmh := metal3api.BareMetalHost{
@@ -76,8 +71,12 @@ var _ = Describe("Live-ISO", func() {
 					URL:        imageURL,
 					DiskFormat: pointer.String("live-iso"),
 				},
-				BootMode:       metal3api.Legacy,
-				BootMACAddress: bootMacAddress,
+				BootMode:              metal3api.Legacy,
+				BootMACAddress:        bootMacAddress,
+				AutomatedCleaningMode: "disabled",
+				RootDeviceHints: &metal3api.RootDeviceHints{
+					DeviceName: "/dev/vda",
+				},
 			},
 		}
 		err := clusterProxy.GetClient().Create(ctx, &bmh)
@@ -100,11 +99,39 @@ var _ = Describe("Live-ISO", func() {
 		// The ssh check is not possible in all situations (e.g. fixture) so it can be skipped
 		if e2eConfig.GetVariable("SSH_CHECK_PROVISIONED") == "true" {
 			By("Verifying the node booted from live ISO image")
-			password := e2eConfig.GetVariable("CIRROS_PASSWORD")
-			auth := ssh.Password(password)
-			PerformSSHBootCheck(e2eConfig, "memory", auth)
+
+			// Set up SSH client configuration
+			config := &ssh.ClientConfig{
+				User: "cirros",
+				Auth: []ssh.AuthMethod{
+					ssh.Password("gocubsgo"),
+				},
+				HostKeyCallback: ssh.InsecureIgnoreHostKey(), // #nosec G106
+			}
+
+			ip := e2eConfig.GetVariable("IP_BMO_E2E_0")
+			sshPort := e2eConfig.GetVariable("SSH_PORT")
+			address := fmt.Sprintf("%s:%s", ip, sshPort)
+
+			// Establish an SSH connection
+			var client *ssh.Client
+			var err error
+
+			Eventually(func() error {
+				client, err = ssh.Dial("tcp", address, config)
+				return err
+			}, e2eConfig.GetIntervals(specName, "wait-connect-ssh")...).Should(Succeed(), "Failed to establish SSH connection")
+
+			defer func() {
+				if client != nil {
+					client.Close()
+				}
+			}()
+			isDisk, err := IsBootedFromDisk(client)
+			Expect(err).NotTo(HaveOccurred(), "Error in verifying boot mode")
+			Expect(isDisk).To(Equal(false), "Error booting from disk when live ISO is expected")
 		} else {
-			capm3_e2e.Logf("WARNING: Skipping SSH check since SSH_CHECK_PROVISIONED != true")
+			capm3_e2e.Logf("WARNING: Skipping ssh check since SSH_CHECK_PROVISIONED != true")
 		}
 
 		By("Triggering the deprovisioning of the BMH")
diff --git a/test/e2e/re_inspection_test.go b/test/e2e/re_inspection_test.go
index 1b1f469c..d9b64986 100644
--- a/test/e2e/re_inspection_test.go
+++ b/test/e2e/re_inspection_test.go
@@ -50,12 +50,8 @@ var _ = Describe("Re-Inspection", func() {
 	})
 
 	It("should re-inspect the annotated BMH", func() {
-		By("Creating a secret with BMH credentials")
-		bmcCredentialsData := map[string]string{
-			"username": bmcUser,
-			"password": bmcPassword,
-		}
-		CreateSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcCredentialsData)
+		By("creating a secret with BMH credentials")
+		CreateBMHCredentialsSecret(ctx, clusterProxy.GetClient(), namespace.Name, secretName, bmcUser, bmcPassword)
 
 		By("creating a BMH with inspection disabled and hardware details added with wrong HostName")
 		newHardwareDetails := strings.Replace(hardwareDetails, "bmo-e2e-0", wrongHostName, 1)
diff --git a/test/go.mod b/test/go.mod
index d322a61d..3249f27d 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/onsi/ginkgo/v2 v2.13.0
 	github.com/onsi/gomega v1.29.0
 	github.com/pkg/errors v0.9.1
-	golang.org/x/crypto v0.17.0
+	golang.org/x/crypto v0.14.0
 	gopkg.in/yaml.v2 v2.4.0
 	k8s.io/api v0.27.7
 	k8s.io/apimachinery v0.27.7
@@ -68,7 +68,7 @@ require (
 	github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
 	github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
-	github.com/google/uuid v1.5.0 // indirect
+	github.com/google/uuid v1.4.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/huandu/xstrings v1.4.0 // indirect
 	github.com/imdario/mergo v0.3.13 // indirect
@@ -113,9 +113,9 @@ require (
 	golang.org/x/mod v0.12.0 // indirect
 	golang.org/x/net v0.17.0 // indirect
 	golang.org/x/oauth2 v0.10.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
-	golang.org/x/term v0.15.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/term v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/tools v0.12.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
diff --git a/test/go.sum b/test/go.sum
index 70fbd8d8..41403b47 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -250,8 +250,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
-github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
+github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
@@ -513,8 +513,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -668,13 +668,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
-golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -685,8 +685,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=