diff --git a/ironic/drivers/modules/redfish/management.py b/ironic/drivers/modules/redfish/management.py index dff790ce56..f415b6d20f 100644 --- a/ironic/drivers/modules/redfish/management.py +++ b/ironic/drivers/modules/redfish/management.py @@ -69,19 +69,28 @@ if sushy: v: k for k, v in INDICATOR_MAP.items()} -def _set_boot_device(task, system, device, enabled=None): +def _set_boot_device(task, system, device, persistent=False): """An internal routine to set the boot device. :param task: a task from TaskManager. :param system: a Redfish System object. :param device: the Redfish boot device. - :param enabled: Redfish boot device persistence value or None. + :param persistent: Boolean value. True if the boot device will + persist to all future boots, False if not. + Default: False. :raises: SushyError on an error from the Sushy library """ + desired_enabled = BOOT_DEVICE_PERSISTENT_MAP_REV[persistent] + current_enabled = system.boot.get('enabled') + + # NOTE(etingof): this can be racy, esp if BMC is not RESTful + enabled = (desired_enabled + if desired_enabled != current_enabled else None) + try: system.set_system_boot_options(device, enabled=enabled) except sushy.exceptions.SushyError as e: - if enabled == sushy.BOOT_SOURCE_ENABLED_CONTINUOUS: + if desired_enabled == sushy.BOOT_SOURCE_ENABLED_CONTINUOUS: # NOTE(dtantsur): continuous boot device settings have been # removed from Redfish, and some vendors stopped supporting # it before an alternative was provided. As a work around, @@ -194,15 +203,10 @@ class RedfishManagement(base.ManagementInterface): system = redfish_utils.get_system(task.node) - desired_persistence = BOOT_DEVICE_PERSISTENT_MAP_REV[persistent] - current_persistence = system.boot.get('enabled') - - # NOTE(etingof): this can be racy, esp if BMC is not RESTful - enabled = (desired_persistence - if desired_persistence != current_persistence else None) try: - _set_boot_device(task, system, BOOT_DEVICE_MAP_REV[device], - enabled=enabled) + _set_boot_device( + task, system, BOOT_DEVICE_MAP_REV[device], + persistent=persistent) except sushy.exceptions.SushyError as e: error_msg = (_('Redfish set boot device failed for node ' '%(node)s. Error: %(error)s') % diff --git a/ironic/tests/unit/drivers/modules/redfish/test_management.py b/ironic/tests/unit/drivers/modules/redfish/test_management.py index 7ee818cef6..70c1d5df9e 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_management.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py @@ -215,7 +215,8 @@ class RedfishManagementTestCase(db_base.DbTestCase): task.driver.management.restore_boot_device(task, fake_system) fake_system.set_system_boot_options.assert_called_once_with( - sushy.BOOT_SOURCE_TARGET_HDD, enabled=None) + sushy.BOOT_SOURCE_TARGET_HDD, + enabled=sushy.BOOT_SOURCE_ENABLED_ONCE) # The stored boot device is kept intact self.assertEqual( sushy.BOOT_SOURCE_TARGET_HDD, @@ -244,7 +245,8 @@ class RedfishManagementTestCase(db_base.DbTestCase): task.driver.management.restore_boot_device(task, fake_system) fake_system.set_system_boot_options.assert_called_once_with( - sushy.BOOT_SOURCE_TARGET_HDD, enabled=None) + sushy.BOOT_SOURCE_TARGET_HDD, + enabled=sushy.BOOT_SOURCE_ENABLED_ONCE) self.assertTrue(mock_log.called) # The stored boot device is kept intact self.assertEqual( diff --git a/releasenotes/notes/fix-redfish-sadness-workaround-ed02cb310ff369f4.yaml b/releasenotes/notes/fix-redfish-sadness-workaround-ed02cb310ff369f4.yaml new file mode 100644 index 0000000000..989a7a646f --- /dev/null +++ b/releasenotes/notes/fix-redfish-sadness-workaround-ed02cb310ff369f4.yaml @@ -0,0 +1,11 @@ +--- +fixes: + - | + Fixes a workaround for hardware that does not support persistent + boot device setting with the ``redfish`` or ``idrac-redfish`` + management interface implementation. When such situation is + detected, ironic falls back to one-time boot device setting, + restoring it on every reboot or power on. + + For more information, see `story 2007733 + `_.