diff --git a/ironic/drivers/modules/ilo/power.py b/ironic/drivers/modules/ilo/power.py index 5e798287e3..35439ff256 100644 --- a/ironic/drivers/modules/ilo/power.py +++ b/ironic/drivers/modules/ilo/power.py @@ -94,12 +94,13 @@ def _get_power_state(node): return states.ERROR -def _wait_for_state_change(node, target_state, +def _wait_for_state_change(node, target_state, requested_state, is_final_state=True, timeout=None): """Wait for the power state change to get reflected. :param node: The node. - :param target_state: target power state of the node. + :param target_state: calculated target power state of the node. + :param requested_state: actual requested power state of the node. :param is_final_state: True, if the given target state is the final expected power state of the node. Default is True. :param timeout: timeout (in seconds) positive integer (> 0) for any @@ -130,7 +131,14 @@ def _wait_for_state_change(node, target_state, target_state == states.SOFT_REBOOT and not is_final_state): state_to_check = ilo_common.POST_POWEROFF_STATE else: - state_to_check = ilo_common.POST_FINISHEDPOST_STATE + # It may not be able to finish POST if no bootable device is + # found. Track (POST_FINISHEDPOST_STATE) only for soft reboot. + # For other power-on cases track for beginning of POST operation + # (POST_INPOST_STATE) to return. + state_to_check = ( + ilo_common.POST_FINISHEDPOST_STATE if + requested_state == states.SOFT_REBOOT else + ilo_common.POST_INPOST_STATE) def _wait(state): if use_post_state: @@ -187,6 +195,7 @@ def _set_power_state(task, target_state, timeout=None): # Check if its soft power operation soft_power_op = target_state in [states.SOFT_POWER_OFF, states.SOFT_REBOOT] + requested_state = target_state if target_state == states.SOFT_REBOOT: if _get_power_state(node) == states.POWER_OFF: target_state = states.POWER_ON @@ -229,7 +238,8 @@ def _set_power_state(task, target_state, timeout=None): is_final_state = target_state in (states.SOFT_POWER_OFF, states.POWER_ON) time_consumed = _wait_for_state_change( - node, target_state, is_final_state=is_final_state, timeout=timeout) + node, target_state, requested_state, + is_final_state=is_final_state, timeout=timeout) if target_state == states.SOFT_REBOOT: _attach_boot_iso_if_needed(task) try: @@ -242,11 +252,12 @@ def _set_power_state(task, target_state, timeout=None): # Re-calculate timeout available for power-on operation rem_timeout = timeout - time_consumed time_consumed += _wait_for_state_change( - node, states.SOFT_REBOOT, is_final_state=True, + node, states.SOFT_REBOOT, requested_state, is_final_state=True, timeout=rem_timeout) else: time_consumed = _wait_for_state_change( - node, target_state, is_final_state=True, timeout=timeout) + node, target_state, requested_state, is_final_state=True, + timeout=timeout) LOG.info("The node %(node_id)s operation of '%(state)s' " "is completed in %(time_consumed)s seconds.", {'node_id': node.uuid, 'state': target_state, diff --git a/ironic/tests/unit/drivers/modules/ilo/test_power.py b/ironic/tests/unit/drivers/modules/ilo/test_power.py index e03ad38bb7..3fe38da978 100644 --- a/ironic/tests/unit/drivers/modules/ilo/test_power.py +++ b/ironic/tests/unit/drivers/modules/ilo/test_power.py @@ -99,7 +99,7 @@ class IloPowerInternalMethodsTestCase(test_common.BaseIloTest): get_ilo_object_mock): ilo_mock_object = get_ilo_object_mock.return_value get_post_mock.side_effect = (['FinishedPost', 'PowerOff', - 'FinishedPost']) + 'InPost']) with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: @@ -131,7 +131,7 @@ class IloPowerInternalMethodsTestCase(test_common.BaseIloTest): autospec=True) def test__set_power_state_on_ok(self, get_post_mock, get_ilo_object_mock): ilo_mock_object = get_ilo_object_mock.return_value - get_post_mock.side_effect = ['PowerOff', 'PowerOff', 'FinishedPost'] + get_post_mock.side_effect = ['PowerOff', 'PowerOff', 'InPost'] target_state = states.POWER_ON with task_manager.acquire(self.context, self.node.uuid, diff --git a/releasenotes/notes/story-2006288-ilo-power-on-fails-with-no-boot-device-b698fef59b04e515.yaml b/releasenotes/notes/story-2006288-ilo-power-on-fails-with-no-boot-device-b698fef59b04e515.yaml new file mode 100644 index 0000000000..2f6712bfac --- /dev/null +++ b/releasenotes/notes/story-2006288-ilo-power-on-fails-with-no-boot-device-b698fef59b04e515.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes an issue in powering-on of server in ``ilo`` hardware type. Server + was failing to return success for power-on operation if no bootable + device was found. See `story 2006288 + `__ for details.