From 685131fd3658b2ff0b131d19d32fd82d74f3bb17 Mon Sep 17 00:00:00 2001 From: Bob Fournier Date: Mon, 19 Oct 2020 14:28:15 -0400 Subject: [PATCH] Sync boot mode when changing the boot device via Redfish After changing the boot device via Redfish, check that the boot mode being reported matches what is configured and, if not, set it to the configured value. Some BMCs change the boot mode when the device is set via Redfish, this will ensure the mode is set properly. Change-Id: Ib077f7f32de029833e6bd936853c382305bce36e Story: 2008252 Task: 41103 --- ironic/drivers/modules/redfish/management.py | 5 ++++ .../modules/redfish/test_management.py | 28 +++++++++++-------- ...nging-redfish-device-f60ef90ba5675215.yaml | 8 ++++++ 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 releasenotes/notes/sync-boot-mode-after-changing-redfish-device-f60ef90ba5675215.yaml diff --git a/ironic/drivers/modules/redfish/management.py b/ironic/drivers/modules/redfish/management.py index e4fec1a2e9..1486767e04 100644 --- a/ironic/drivers/modules/redfish/management.py +++ b/ironic/drivers/modules/redfish/management.py @@ -33,6 +33,7 @@ from ironic.conductor import task_manager from ironic.conductor import utils as manager_utils from ironic.conf import CONF from ironic.drivers import base +from ironic.drivers.modules import boot_mode_utils from ironic.drivers.modules import deploy_utils from ironic.drivers.modules.redfish import utils as redfish_utils @@ -222,6 +223,10 @@ class RedfishManagement(base.ManagementInterface): LOG.error(error_msg) raise exception.RedfishError(error=error_msg) + # Ensure that boot mode is synced with what is set. + # Some BMCs reset it to default (BIOS) when changing the boot device. + boot_mode_utils.sync_boot_mode(task) + def get_boot_device(self, task): """Get the current boot device for a node. diff --git a/ironic/tests/unit/drivers/modules/redfish/test_management.py b/ironic/tests/unit/drivers/modules/redfish/test_management.py index 827dbf9bb6..f592c08654 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_management.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_management.py @@ -101,9 +101,11 @@ class RedfishManagementTestCase(db_base.DbTestCase): task.driver.management.set_boot_device(task, target) # Asserts - fake_system.set_system_boot_options.assert_called_once_with( - expected, enabled=sushy.BOOT_SOURCE_ENABLED_ONCE) - mock_get_system.assert_called_once_with(task.node) + fake_system.set_system_boot_options.assert_has_calls( + [mock.call(expected, + enabled=sushy.BOOT_SOURCE_ENABLED_ONCE), + mock.call(mode=sushy.BOOT_SOURCE_MODE_BIOS)]) + mock_get_system.assert_called_with(task.node) self.assertNotIn('redfish_boot_device', task.node.driver_internal_info) @@ -126,9 +128,11 @@ class RedfishManagementTestCase(db_base.DbTestCase): task.driver.management.set_boot_device( task, boot_devices.PXE, persistent=target) - fake_system.set_system_boot_options.assert_called_once_with( - sushy.BOOT_SOURCE_TARGET_PXE, enabled=expected) - mock_get_system.assert_called_once_with(task.node) + fake_system.set_system_boot_options.assert_has_calls( + [mock.call(sushy.BOOT_SOURCE_TARGET_PXE, + enabled=expected), + mock.call(mode=sushy.BOOT_SOURCE_MODE_BIOS)]) + mock_get_system.assert_called_with(task.node) self.assertNotIn('redfish_boot_device', task.node.driver_internal_info) @@ -153,9 +157,10 @@ class RedfishManagementTestCase(db_base.DbTestCase): task.driver.management.set_boot_device( task, boot_devices.PXE, persistent=target) - fake_system.set_system_boot_options.assert_called_once_with( - sushy.BOOT_SOURCE_TARGET_PXE, enabled=None) - mock_get_system.assert_called_once_with(task.node) + fake_system.set_system_boot_options.assert_has_calls( + [mock.call(sushy.BOOT_SOURCE_TARGET_PXE, enabled=None), + mock.call(mode=sushy.BOOT_SOURCE_MODE_BIOS)]) + mock_get_system.assert_called_with(task.node) # Reset mocks fake_system.set_system_boot_options.reset_mock() @@ -220,6 +225,7 @@ class RedfishManagementTestCase(db_base.DbTestCase): fake_system.set_system_boot_options.side_effect = [ sushy.exceptions.SushyError(), None, + None ] mock_get_system.return_value = fake_system with task_manager.acquire(self.context, self.node.uuid, @@ -230,9 +236,9 @@ class RedfishManagementTestCase(db_base.DbTestCase): mock.call(sushy.BOOT_SOURCE_TARGET_PXE, enabled=sushy.BOOT_SOURCE_ENABLED_CONTINUOUS), mock.call(sushy.BOOT_SOURCE_TARGET_PXE, - enabled=sushy.BOOT_SOURCE_ENABLED_ONCE), + enabled=sushy.BOOT_SOURCE_ENABLED_ONCE) ]) - mock_get_system.assert_called_once_with(task.node) + mock_get_system.assert_called_with(task.node) task.node.refresh() self.assertEqual( diff --git a/releasenotes/notes/sync-boot-mode-after-changing-redfish-device-f60ef90ba5675215.yaml b/releasenotes/notes/sync-boot-mode-after-changing-redfish-device-f60ef90ba5675215.yaml new file mode 100644 index 0000000000..629d9527c2 --- /dev/null +++ b/releasenotes/notes/sync-boot-mode-after-changing-redfish-device-f60ef90ba5675215.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + After changing the boot device via Redfish, check that the boot mode being + reported matches what is configured and, if not, set it to the configured + value. Some BMCs change the boot mode when the device is + set via Redfish, see `story 2008252 + `__ for details.