summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-03-24 10:23:32 +0000
committerGerrit Code Review <review@openstack.org>2021-03-24 10:23:32 +0000
commit2466d5e36507a8a83e7937cf0fbf796c5fabc0ef (patch)
tree3439db03a7e81916e7168397ffc6f5e2ddb081de
parentd81433f8beff2b548c67309e3a3a6f1e15e7ecfd (diff)
parent13fc01fe386d27589f0cde37d0f9a26298bdbf8c (diff)
downloadironic-2466d5e36507a8a83e7937cf0fbf796c5fabc0ef.tar.gz
Merge "Allow unsupported redfish set_boot_mode" into stable/victoria
-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 c4ebd953c..24713fc61 100644
--- a/ironic/drivers/modules/redfish/management.py
+++ b/ironic/drivers/modules/redfish/management.py
@@ -303,6 +303,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 f9e74d964..1732e5f85 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_management.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py
@@ -350,6 +350,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,
@@ -374,7 +380,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
@@ -387,6 +398,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 80d0a19e6..94c5b2442 100644
--- a/ironic/tests/unit/drivers/third_party_driver_mocks.py
+++ b/ironic/tests/unit/drivers/third_party_driver_mocks.py
@@ -237,6 +237,8 @@ if not sushy:
type('OEMExtensionNotFoundError', (sushy.exceptions.SushyError,), {}))
sushy.exceptions.ServerSideError = (
type('ServerSideError', (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.