diff --git a/ironic/drivers/modules/ilo/management.py b/ironic/drivers/modules/ilo/management.py index e879038ed0..91aa8f4521 100644 --- a/ironic/drivers/modules/ilo/management.py +++ b/ironic/drivers/modules/ilo/management.py @@ -585,3 +585,29 @@ class IloManagement(base.ManagementInterface): % {'node': task.node.uuid}) raise exception.IloOperationError(operation=operation, error=ilo_exception) + + @METRICS.timer('IloManagement.inject_nmi') + @task_manager.require_exclusive_lock + def inject_nmi(self, task): + """Inject NMI, Non Maskable Interrupt. + + Inject NMI (Non Maskable Interrupt) for a node immediately. + + :param task: A TaskManager instance containing the node to act on. + :raises: IloCommandNotSupportedError if system does not support + NMI injection. + :raises: IloError on an error from iLO. + :returns: None + """ + node = task.node + ilo_object = ilo_common.get_ilo_object(node) + try: + operation = (_("Injecting NMI for node %(node)s") + % {'node': node.uuid}) + ilo_object.inject_nmi() + except ilo_error.IloCommandNotSupportedError as ilo_exception: + raise exception.IloOperationNotSupported(operation=operation, + error=ilo_exception) + except ilo_error.IloError as ilo_exception: + raise exception.IloOperationError(operation=operation, + error=ilo_exception) diff --git a/ironic/tests/unit/drivers/modules/ilo/test_management.py b/ironic/tests/unit/drivers/modules/ilo/test_management.py index fe6cf3b1f5..190a4b26e4 100644 --- a/ironic/tests/unit/drivers/modules/ilo/test_management.py +++ b/ironic/tests/unit/drivers/modules/ilo/test_management.py @@ -849,3 +849,37 @@ class IloManagementTestCase(test_common.BaseIloTest): self.assertRaises(exception.IloOperationNotSupported, task.driver.management.clear_iscsi_boot_target, task) + + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inject_nmi(self, get_ilo_object_mock): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + ilo_object_mock = get_ilo_object_mock.return_value + + task.driver.management.inject_nmi(task) + ilo_object_mock.inject_nmi.assert_called_once() + + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inject_nmi_failed(self, get_ilo_object_mock): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + ilo_object_mock = get_ilo_object_mock.return_value + ilo_object_mock.inject_nmi.side_effect = ( + ilo_error.IloError('error')) + self.assertRaises(exception.IloOperationError, + task.driver.management.inject_nmi, + task) + + @mock.patch.object(ilo_common, 'get_ilo_object', spec_set=True, + autospec=True) + def test_inject_nmi_not_supported(self, get_ilo_object_mock): + with task_manager.acquire(self.context, self.node.uuid, + shared=False) as task: + ilo_object_mock = get_ilo_object_mock.return_value + ilo_object_mock.inject_nmi.side_effect = ( + ilo_error.IloCommandNotSupportedError('error')) + self.assertRaises(exception.IloOperationNotSupported, + task.driver.management.inject_nmi, + task) diff --git a/releasenotes/notes/ilo-inject-nmi-f487db8c3bfd08ea.yaml b/releasenotes/notes/ilo-inject-nmi-f487db8c3bfd08ea.yaml new file mode 100644 index 0000000000..a5ef83fce0 --- /dev/null +++ b/releasenotes/notes/ilo-inject-nmi-f487db8c3bfd08ea.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Adds support for the injection of Non-Masking Interrupts (NMI) to + ``ilo`` management interface. This is supported on HPE ProLiant + Gen9 and Gen10 servers.