summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-04-20 16:41:52 +0000
committerGerrit Code Review <review@openstack.org>2021-04-20 16:41:52 +0000
commitee8e564de8d6ebbceda4219495f75dbcf588834a (patch)
treec384f00e216379a90c31cdfd32f366bb396686cc
parenta4280518f35d835e63a1a98cb4f78187e6b33980 (diff)
parent97390e4276e70ece095944426a01f0223e664f5a (diff)
downloadironic-ee8e564de8d6ebbceda4219495f75dbcf588834a.tar.gz
Merge "Allow unsupported redfish set_boot_mode" into stable/ussuri
-rw-r--r--ironic/drivers/modules/redfish/management.py13
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_management.py34
-rw-r--r--ironic/tests/unit/drivers/third_party_driver_mocks.py2
-rw-r--r--releasenotes/notes/redfish-boot-mode-override-not-present-handling-92e7263617e467c4.yaml9
4 files changed, 57 insertions, 1 deletions
diff --git a/ironic/drivers/modules/redfish/management.py b/ironic/drivers/modules/redfish/management.py
index 085d2fe84..676749ad0 100644
--- a/ironic/drivers/modules/redfish/management.py
+++ b/ironic/drivers/modules/redfish/management.py
@@ -300,6 +300,19 @@ class RedfishManagement(base.ManagementInterface):
{'node': task.node.uuid, 'mode': mode,
'error': e})
LOG.error(error_msg)
+
+ # NOTE(sbaker): Some systems such as HPE Gen9 do not support
+ # getting or setting the boot mode. When setting failed and the
+ # mode attribute is missing from the boot field, raising
+ # UnsupportedDriverExtension will allow the deploy to continue.
+ if system.boot.get('mode') is None:
+ LOG.info(_('Attempt to set boot mode on node %(node)s '
+ 'failed to set boot mode as the node does not '
+ 'appear to support overriding the boot mode. '
+ 'Possibly partial Redfish implementation?'),
+ {'node': task.node.uuid})
+ raise exception.UnsupportedDriverExtension(
+ driver=task.node.driver, extension='set_boot_mode')
raise exception.RedfishError(error=error_msg)
def get_boot_mode(self, task):
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_management.py b/ironic/tests/unit/drivers/modules/redfish/test_management.py
index 9f69a7c7e..d81fbc56f 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_management.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py
@@ -345,6 +345,12 @@ class RedfishManagementTestCase(db_base.DbTestCase):
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
def test_set_boot_mode(self, mock_get_system):
+ boot_attribute = {
+ 'target': sushy.BOOT_SOURCE_TARGET_PXE,
+ 'enabled': sushy.BOOT_SOURCE_ENABLED_CONTINUOUS,
+ 'mode': sushy.BOOT_SOURCE_MODE_BIOS,
+ }
+ fake_system = mock.Mock(boot=boot_attribute)
fake_system = mock.Mock()
mock_get_system.return_value = fake_system
with task_manager.acquire(self.context, self.node.uuid,
@@ -369,7 +375,12 @@ class RedfishManagementTestCase(db_base.DbTestCase):
@mock.patch.object(sushy, 'Sushy', autospec=True)
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
def test_set_boot_mode_fail(self, mock_get_system, mock_sushy):
- fake_system = mock.Mock()
+ boot_attribute = {
+ 'target': sushy.BOOT_SOURCE_TARGET_PXE,
+ 'enabled': sushy.BOOT_SOURCE_ENABLED_CONTINUOUS,
+ 'mode': sushy.BOOT_SOURCE_MODE_BIOS,
+ }
+ fake_system = mock.Mock(boot=boot_attribute)
fake_system.set_system_boot_options.side_effect = (
sushy.exceptions.SushyError)
mock_get_system.return_value = fake_system
@@ -382,6 +393,27 @@ class RedfishManagementTestCase(db_base.DbTestCase):
mode=boot_modes.UEFI)
mock_get_system.assert_called_once_with(task.node)
+ @mock.patch.object(sushy, 'Sushy', autospec=True)
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_set_boot_mode_unsupported(self, mock_get_system, mock_sushy):
+ boot_attribute = {
+ 'target': sushy.BOOT_SOURCE_TARGET_PXE,
+ 'enabled': sushy.BOOT_SOURCE_ENABLED_CONTINUOUS,
+ }
+ fake_system = mock.Mock(boot=boot_attribute)
+ error = sushy.exceptions.BadRequestError('PATCH', '/', mock.Mock())
+ fake_system.set_system_boot_options.side_effect = error
+ mock_get_system.return_value = fake_system
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ self.assertRaisesRegex(
+ exception.UnsupportedDriverExtension,
+ 'does not support set_boot_mode',
+ task.driver.management.set_boot_mode, task, boot_modes.UEFI)
+ fake_system.set_system_boot_options.assert_called_once_with(
+ mode=boot_modes.UEFI)
+ mock_get_system.assert_called_once_with(task.node)
+
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
def test_get_boot_mode(self, mock_get_system):
boot_attribute = {
diff --git a/ironic/tests/unit/drivers/third_party_driver_mocks.py b/ironic/tests/unit/drivers/third_party_driver_mocks.py
index 62c3b4b89..8a76d87f3 100644
--- a/ironic/tests/unit/drivers/third_party_driver_mocks.py
+++ b/ironic/tests/unit/drivers/third_party_driver_mocks.py
@@ -234,6 +234,8 @@ if not sushy:
type('MissingAttributeError', (sushy.exceptions.SushyError,), {}))
sushy.exceptions.OEMExtensionNotFoundError = (
type('OEMExtensionNotFoundError', (sushy.exceptions.SushyError,), {}))
+ sushy.exceptions.BadRequestError = (
+ type('BadRequestError', (sushy.exceptions.SushyError,), {}))
sushy.auth = mock.MagicMock(spec_set=mock_specs.SUSHY_AUTH_SPEC)
sys.modules['sushy.auth'] = sushy.auth
diff --git a/releasenotes/notes/redfish-boot-mode-override-not-present-handling-92e7263617e467c4.yaml b/releasenotes/notes/redfish-boot-mode-override-not-present-handling-92e7263617e467c4.yaml
new file mode 100644
index 000000000..79f20e439
--- /dev/null
+++ b/releasenotes/notes/redfish-boot-mode-override-not-present-handling-92e7263617e467c4.yaml
@@ -0,0 +1,9 @@
+---
+fixes:
+ - |
+ Adds handling of Redfish BMC's which lack a ``BootSourceOverrideMode``
+ flag, such that it is no longer a fatal error for a deployment if the BMC
+ does not support this field. This most common on BMCs which feature only
+ a partial implementation of the ``ComputerSystem`` resource ``boot``,
+ but may also be observable on some older generations of BMCs which
+ recieved updates to have partial Redfish support.