Repository: metal3-io/baremetal-operator (go)

Issue:
Adoption errors cause deprovisioning
If a Host is in the `provisioned` state and an error occurs during Adopt() (i.e. a `provisioned registration error`), the Host will be deprovisioned. This is bad.

The same does _not_ apply to ordinary `registration error` errors, because registration is handled separately.

It _would_ apply to `power management error`, but we have never reported a power management error (c.f. #828), and won't until #841 is merged.

Pull request description:
Don't deprovision provisioned host due to error
During provisioning, we want an error to cause the Host to be
deprovisioned again, but we very much do not want that to happen when
the Host is already provisioned. Due to an error in
0a7713bd3b4ff30aef2dac17c2d62a79bfe02872, provisioned Hosts were being
automatically deprovisioned whenever an error (other than a registration
error) occurred.

In practice this only manifested on Adopt() failures, since we don't yet
report power management failures.

Fixes #915

Patch:
diff --git a/controllers/metal3.io/host_state_machine.go b/controllers/metal3.io/host_state_machine.go
index 60566538..dc63858f 100644
--- a/controllers/metal3.io/host_state_machine.go
+++ b/controllers/metal3.io/host_state_machine.go
@@ -428,9 +428,6 @@ func (hsm *hostStateMachine) handleReady(info *reconcileInfo) actionResult {
 }
 
 func (hsm *hostStateMachine) provisioningCancelled() bool {
-	if hsm.Host.Status.ErrorMessage != "" {
-		return true
-	}
 	if hsm.Host.Spec.Image == nil {
 		return true
 	}
@@ -447,7 +444,7 @@ func (hsm *hostStateMachine) provisioningCancelled() bool {
 }
 
 func (hsm *hostStateMachine) handleProvisioning(info *reconcileInfo) actionResult {
-	if hsm.provisioningCancelled() {
+	if hsm.Host.Status.ErrorType != "" || hsm.provisioningCancelled() {
 		hsm.NextState = metal3v1alpha1.StateDeprovisioning
 		return actionComplete{}
 	}


Test patch:
diff --git a/controllers/metal3.io/host_state_machine_test.go b/controllers/metal3.io/host_state_machine_test.go
index 670f1425..fbf51a5c 100644
--- a/controllers/metal3.io/host_state_machine_test.go
+++ b/controllers/metal3.io/host_state_machine_test.go
@@ -525,6 +525,33 @@ func TestProvisioningCancelled(t *testing.T) {
 			Expected: false,
 		},
 
+		{
+			Scenario: "provisioned with error",
+			Host: metal3v1alpha1.BareMetalHost{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "myhost",
+					Namespace: "myns",
+				},
+				Spec: metal3v1alpha1.BareMetalHostSpec{
+					Image: &metal3v1alpha1.Image{
+						URL: "same",
+					},
+					Online: true,
+				},
+				Status: metal3v1alpha1.BareMetalHostStatus{
+					ErrorType:    metal3v1alpha1.ProvisionedRegistrationError,
+					ErrorMessage: "Adoption failed",
+					ErrorCount:   1,
+					Provisioning: metal3v1alpha1.ProvisionStatus{
+						Image: metal3v1alpha1.Image{
+							URL: "same",
+						},
+					},
+				},
+			},
+			Expected: false,
+		},
+
 		{
 			Scenario: "removed image",
 			Host: metal3v1alpha1.BareMetalHost{