diff --git a/ironic/drivers/modules/oneview/power.py b/ironic/drivers/modules/oneview/power.py index b86e12a0dd..2100159a86 100644 --- a/ironic/drivers/modules/oneview/power.py +++ b/ironic/drivers/modules/oneview/power.py @@ -120,12 +120,14 @@ class OneViewPower(base.PowerInterface): @METRICS.timer('OneViewPower.set_power_state') @task_manager.require_exclusive_lock - def set_power_state(self, task, power_state): + def set_power_state(self, task, power_state, timeout=None): """Turn the current power state on or off. :param task: a TaskManager instance. :param power_state: The desired power state POWER_ON, POWER_OFF or REBOOT from :mod:`ironic.common.states`. + :param timeout: timeout (in seconds) positive integer (> 0) for any + power state. ``None`` indicates to use default timeout. :raises: InvalidParameterValue if an invalid power state was specified. :raises: PowerStateFailure if the power couldn't be set to power_state. :raises: OneViewError if OneView fails setting the power state. @@ -152,21 +154,26 @@ class OneViewPower(base.PowerInterface): {'node_uuid': task.node.uuid, 'power_state': power_state}) server_hardware = task.node.driver_info.get('server_hardware_uri') + timeout = (-1 if timeout is None else timeout) try: if power_state == states.POWER_ON: management.set_boot_device(task) oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(power_state), server_hardware) + SET_POWER_STATE_MAP.get(power_state), + server_hardware, timeout=timeout) elif power_state == states.REBOOT: oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(states.POWER_OFF), server_hardware) + SET_POWER_STATE_MAP.get(states.POWER_OFF), + server_hardware, timeout=timeout) management.set_boot_device(task) oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(states.POWER_ON), server_hardware) + SET_POWER_STATE_MAP.get(states.POWER_ON), + server_hardware, timeout=timeout) else: oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(power_state), server_hardware) + SET_POWER_STATE_MAP.get(power_state), + server_hardware, timeout=timeout) except client_exception.HPOneViewException as exc: raise exception.OneViewError( _("Failed to setting power state on node: %(node)s. " @@ -177,15 +184,17 @@ class OneViewPower(base.PowerInterface): @METRICS.timer('OneViewPower.reboot') @task_manager.require_exclusive_lock - def reboot(self, task): - """Reboot the node + def reboot(self, task, timeout=None): + """Reboot the node. :param task: a TaskManager instance. + :param timeout: timeout (in seconds) positive integer (> 0) for any + power state. ``None`` indicates to use default timeout. :raises: PowerStateFailure if the final state of the node is not POWER_ON. """ current_power_state = self.get_power_state(task) if current_power_state == states.POWER_ON: - self.set_power_state(task, states.REBOOT) + self.set_power_state(task, states.REBOOT, timeout=timeout) else: - self.set_power_state(task, states.POWER_ON) + self.set_power_state(task, states.POWER_ON, timeout=timeout) diff --git a/ironic/tests/unit/drivers/modules/oneview/test_power.py b/ironic/tests/unit/drivers/modules/oneview/test_power.py index b4d86cabcd..18be7e2393 100644 --- a/ironic/tests/unit/drivers/modules/oneview/test_power.py +++ b/ironic/tests/unit/drivers/modules/oneview/test_power.py @@ -120,7 +120,21 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase): self.driver.power.set_power_state(task, states.POWER_ON) self.assertTrue(mock_set_boot_device.called) update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_ON, server_hardware) + update.assert_called_once_with(power.POWER_ON, server_hardware, + timeout=-1) + + @mock.patch.object(common, 'get_hponeview_client') + @mock.patch.object(management, 'set_boot_device') + def test_set_power_on_with_timeout( + self, mock_set_boot_device, mock_get_ov_client): + client = mock_get_ov_client() + server_hardware = self.node.driver_info.get('server_hardware_uri') + with task_manager.acquire(self.context, self.node.uuid) as task: + self.driver.power.set_power_state(task, states.POWER_ON, timeout=2) + self.assertTrue(mock_set_boot_device.called) + update = client.server_hardware.update_power_state + update.assert_called_once_with(power.POWER_ON, server_hardware, + timeout=2) @mock.patch.object(common, 'get_hponeview_client') @mock.patch.object(management, 'set_boot_device') @@ -131,7 +145,22 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase): self.driver.power.set_power_state(task, states.POWER_OFF) self.assertFalse(mock_set_boot_device.called) update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_OFF, server_hardware) + update.assert_called_once_with(power.POWER_OFF, server_hardware, + timeout=-1) + + @mock.patch.object(common, 'get_hponeview_client') + @mock.patch.object(management, 'set_boot_device') + def test_set_power_off_with_timeout( + self, mock_set_boot_device, mock_get_ov_client): + client = mock_get_ov_client() + server_hardware = self.node.driver_info.get('server_hardware_uri') + with task_manager.acquire(self.context, self.node.uuid) as task: + self.driver.power.set_power_state(task, states.POWER_OFF, + timeout=2) + self.assertFalse(mock_set_boot_device.called) + update = client.server_hardware.update_power_state + update.assert_called_once_with(power.POWER_OFF, server_hardware, + timeout=2) @mock.patch.object(common, 'get_hponeview_client') @mock.patch.object(management, 'set_boot_device') @@ -140,8 +169,8 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase): server_hardware = self.node.driver_info.get('server_hardware_uri') with task_manager.acquire(self.context, self.node.uuid) as task: self.driver.power.set_power_state(task, states.REBOOT) - calls = [mock.call(power.POWER_OFF, server_hardware), - mock.call(power.POWER_ON, server_hardware)] + calls = [mock.call(power.POWER_OFF, server_hardware, timeout=-1), + mock.call(power.POWER_ON, server_hardware, timeout=-1)] update = client.server_hardware.update_power_state update.assert_has_calls(calls) @@ -227,8 +256,8 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase): server_hardware = self.node.driver_info.get('server_hardware_uri') with task_manager.acquire(self.context, self.node.uuid) as task: self.driver.power.reboot(task) - calls = [mock.call(power.POWER_OFF, server_hardware), - mock.call(power.POWER_ON, server_hardware)] + calls = [mock.call(power.POWER_OFF, server_hardware, timeout=-1), + mock.call(power.POWER_ON, server_hardware, timeout=-1)] update = client.server_hardware.update_power_state update.assert_has_calls(calls) mock_set_boot_device.assert_called_once_with(task) @@ -242,7 +271,23 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase): client.server_hardware.get.return_value = server_hardware server_hardware = self.node.driver_info.get('server_hardware_uri') with task_manager.acquire(self.context, self.node.uuid) as task: - self.driver.power.reboot(task) + self.driver.power.reboot(task, timeout=-1) update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_ON, server_hardware) + update.assert_called_once_with(power.POWER_ON, server_hardware, + timeout=-1) + mock_set_boot_device.assert_called_once_with(task) + + @mock.patch.object(common, 'get_hponeview_client') + @mock.patch.object(management, 'set_boot_device') + def test_set_power_reboot_with_hardware_off_with_timeout( + self, mock_set_boot_device, mock_get_ov_client): + client = mock_get_ov_client() + server_hardware = {'powerState': 'Off'} + client.server_hardware.get.return_value = server_hardware + server_hardware = self.node.driver_info.get('server_hardware_uri') + with task_manager.acquire(self.context, self.node.uuid) as task: + self.driver.power.reboot(task, timeout=2) + update = client.server_hardware.update_power_state + update.assert_called_once_with(power.POWER_ON, server_hardware, + timeout=2) mock_set_boot_device.assert_called_once_with(task) diff --git a/releasenotes/notes/oneview-timeout-power-db5125e05831d925.yaml b/releasenotes/notes/oneview-timeout-power-db5125e05831d925.yaml new file mode 100644 index 0000000000..1b968cdc5d --- /dev/null +++ b/releasenotes/notes/oneview-timeout-power-db5125e05831d925.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for ``timeout`` parameter when powering on/off and reboot + a bare metal node managed by the ``oneview`` hardware type.