diff --git a/controllers/metal3.io/host_state_machine.go b/controllers/metal3.io/host_state_machine.go index 833d25e55a..3a37d2929f 100644 --- a/controllers/metal3.io/host_state_machine.go +++ b/controllers/metal3.io/host_state_machine.go @@ -536,15 +536,9 @@ func (hsm *hostStateMachine) handleDeprovisioning(info *reconcileInfo) actionRes hsm.Host.Status.ErrorCount = 0 } } else { - skipToDelete := func() actionResult { - hsm.NextState = metal3api.StateDeleting - info.postSaveCallbacks = append(info.postSaveCallbacks, deleteWithoutDeprov.Inc) - return actionComplete{} - } - switch r := actResult.(type) { case actionComplete: - hsm.NextState = metal3api.StateDeleting + hsm.NextState = metal3api.StatePoweringOffBeforeDelete hsm.Host.Status.ErrorCount = 0 case actionFailed: // If the provisioner gives up deprovisioning and @@ -552,14 +546,18 @@ func (hsm *hostStateMachine) handleDeprovisioning(info *reconcileInfo) actionRes if hsm.Host.Status.ErrorCount > 3 { info.log.Info("Giving up on host clean up after 3 attempts. The host may still be operational " + "and cause issues in your clusters. You should clean it up manually now.") - return skipToDelete() + hsm.NextState = metal3api.StatePoweringOffBeforeDelete + info.postSaveCallbacks = append(info.postSaveCallbacks, deleteWithoutDeprov.Inc) + return actionComplete{} } case actionError: if r.NeedsRegistration() && !hsm.haveCreds { // If the host is not registered as a node in Ironic and we // lack the credentials to deprovision it, just continue to // delete. - return skipToDelete() + hsm.NextState = metal3api.StateDeleting + info.postSaveCallbacks = append(info.postSaveCallbacks, deleteWithoutPowerOff.Inc) + return actionComplete{} } } } diff --git a/controllers/metal3.io/host_state_machine_test.go b/controllers/metal3.io/host_state_machine_test.go index 2f90580f42..4478aa0f9d 100644 --- a/controllers/metal3.io/host_state_machine_test.go +++ b/controllers/metal3.io/host_state_machine_test.go @@ -997,8 +997,13 @@ func TestErrorCountClearedOnStateTransition(t *testing.T) { TargetState: metal3api.StateAvailable, }, { - Scenario: "deprovisioning-to-deleting", + Scenario: "deprovisioning-to-powering-off", Host: host(metal3api.StateDeprovisioning).setDeletion().withFinalizer().build(), + TargetState: metal3api.StatePoweringOffBeforeDelete, + }, + { + Scenario: "powering-off-to-deleting", + Host: host(metal3api.StatePoweringOffBeforeDelete).setDeletion().withFinalizer().build(), TargetState: metal3api.StateDeleting, }, } diff --git a/docs/BaremetalHost_ProvisioningState.dot b/docs/BaremetalHost_ProvisioningState.dot index f8950bfcb4..4fd8149c5f 100644 --- a/docs/BaremetalHost_ProvisioningState.dot +++ b/docs/BaremetalHost_ProvisioningState.dot @@ -5,57 +5,49 @@ digraph BaremetalHost { Unmanaged [shape=doublecircle] Unmanaged -> Registering [label="BMC.* != \"\""] - Unmanaged -> Deleting1 [label="!DeletionTimestamp.IsZero()"] - - Deleting1 [shape=point] + Unmanaged -> PoweringOffBeforeDelete [label="!DeletionTimestamp.IsZero()"] ExternallyProvisioned [label="Externally\nProvisioned"] - Registering -> Inspecting [label="!externallyProvisioned && NeedsHardwareInspection()"] - Registering -> Preparing [label="!externallyProvisioned && inspectionDisabled()"] + Registering -> Inspecting [label="!externallyProvisioned &&\nNeedsHardwareInspection()"] + Registering -> Preparing [label="!externallyProvisioned &&\ninspectionDisabled()"] Registering -> ExternallyProvisioned [label="externallyProvisioned"] - Registering -> Deleting2 [label="!DeletionTimestamp.IsZero()"] - - Deleting2 [shape=point] + Registering -> PoweringOffBeforeDelete [label="!DeletionTimestamp.IsZero()"] - ExternallyProvisioned -> Inspecting [label="!externallyProvisioned && NeedsHardwareInspection()"] - ExternallyProvisioned -> Preparing [label="!externallyProvisioned && !NeedsHardwareInspection()"] + ExternallyProvisioned -> Inspecting [label="!externallyProvisioned &&\nNeedsHardwareInspection()"] + ExternallyProvisioned -> Preparing [label="!externallyProvisioned &&\n!NeedsHardwareInspection()"] Available -> ExternallyProvisioned [label="externallyProvisioned"] Inspecting -> Preparing [label="done"] - Inspecting -> Deleting3 [label="!DeletionTimestamp.IsZero()"] - - Deleting3 [shape=point] - - Deleting5 [shape=point] + Inspecting -> PoweringOffBeforeDelete [label="!DeletionTimestamp.IsZero()"] Preparing -> Available [label="done"] - Preparing -> Deleting6 [label="!DeletionTimestamp.IsZero()"] - - Deleting6 [shape=point] + Preparing -> PoweringOffBeforeDelete [label="!DeletionTimestamp.IsZero()"] Available [shape=doublecircle] Available -> Provisioning [label="NeedsProvisioning()"] Available -> Preparing [label="saveHostProvisioningSettings()"] Available -> Preparing [label="getHostFirmwareSettings()"] - Available -> Deleting7 [label="!DeletionTimestamp.IsZero()"] + Available -> PoweringOffBeforeDelete [label="!DeletionTimestamp.IsZero()"] Available -> Inspecting [label="hasInspectAnnotation()"] Deleting7 [shape=point] Provisioning -> Provisioned [label=done] - Provisioning -> Deprovisioning [label="failed || !DeletionTimestamp.IsZero()"] + Provisioning -> Deprovisioning [label="failed ||\n!DeletionTimestamp.IsZero()"] Provisioned [shape=doublecircle] Provisioned -> Deprovisioning [label="provisioningCancelled()"] Provisioned -> Deprovisioning [label="!DeletionTimestamp.IsZero()"] ExternallyProvisioned [shape=doublecircle] - ExternallyProvisioned -> Deleting [label="!DeletionTimestamp.IsZero()"] + ExternallyProvisioned -> PoweringOffBeforeDelete [label="!DeletionTimestamp.IsZero()"] Deprovisioning -> Provisioning [label="NeedsProvisioning()"] Deprovisioning -> Available [label="!NeedsProvisioning()"] - Deprovisioning -> Deleting [label="!DeletionTimestamp.IsZero()"] + + Deprovisioning -> PoweringOffBeforeDelete + PoweringOffBeforeDelete -> Deleting Deleting [shape=doublecircle] } diff --git a/docs/BaremetalHost_ProvisioningState.png b/docs/BaremetalHost_ProvisioningState.png index f576959dbd..63c3b009fc 100644 Binary files a/docs/BaremetalHost_ProvisioningState.png and b/docs/BaremetalHost_ProvisioningState.png differ