diff --git a/ironic/drivers/modules/ipminative.py b/ironic/drivers/modules/ipminative.py index 9b9409a2f4..efcf0fa4fa 100644 --- a/ironic/drivers/modules/ipminative.py +++ b/ironic/drivers/modules/ipminative.py @@ -37,6 +37,7 @@ from ironic.common import utils from ironic.conductor import task_manager from ironic.drivers import base from ironic.drivers.modules import console_utils +from ironic.drivers.modules import deploy_utils from ironic.drivers import utils as driver_utils pyghmi = importutils.try_import('pyghmi') @@ -473,13 +474,15 @@ class NativeIPMIManagement(base.ManagementInterface): # persistent or we do not have admin rights. persistent = False + boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) driver_info = _parse_driver_info(task.node) try: ipmicmd = ipmi_command.Command(bmc=driver_info['address'], userid=driver_info['username'], password=driver_info['password']) bootdev = _BOOT_DEVICES_MAP[device] - ipmicmd.set_bootdev(bootdev, persist=persistent) + uefiboot = boot_mode == 'uefi' + ipmicmd.set_bootdev(bootdev, persist=persistent, uefiboot=uefiboot) except pyghmi_exception.IpmiException as e: LOG.error(_LE("IPMI set boot device failed for node %(node_id)s " "with the following error: %(error)s"), diff --git a/ironic/tests/unit/drivers/modules/test_ipminative.py b/ironic/tests/unit/drivers/modules/test_ipminative.py index e745590f67..90bd50e22a 100644 --- a/ironic/tests/unit/drivers/modules/test_ipminative.py +++ b/ironic/tests/unit/drivers/modules/test_ipminative.py @@ -29,6 +29,7 @@ from ironic.common import exception from ironic.common import states from ironic.conductor import task_manager from ironic.drivers.modules import console_utils +from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import ipminative from ironic.drivers import utils as driver_utils from ironic.tests.unit.conductor import mgr_utils @@ -343,7 +344,8 @@ class IPMINativeDriverTestCase(db_base.DbTestCase): self.node.uuid) as task: self.driver.management.set_boot_device(task, boot_devices.PXE) # PXE is converted to 'network' internally by ipminative - ipmicmd.set_bootdev.assert_called_once_with('network', persist=False) + ipmicmd.set_bootdev.assert_called_once_with('network', persist=False, + uefiboot=False) @mock.patch('pyghmi.ipmi.command.Command', autospec=True) def test_force_set_boot_device_ok(self, ipmi_mock): @@ -360,7 +362,8 @@ class IPMINativeDriverTestCase(db_base.DbTestCase): task.node.driver_internal_info['is_next_boot_persistent'] ) # PXE is converted to 'network' internally by ipminative - ipmicmd.set_bootdev.assert_called_once_with('network', persist=False) + ipmicmd.set_bootdev.assert_called_once_with('network', persist=False, + uefiboot=False) @mock.patch('pyghmi.ipmi.command.Command', autospec=True) def test_set_boot_device_with_persistent(self, ipmi_mock): @@ -377,7 +380,8 @@ class IPMINativeDriverTestCase(db_base.DbTestCase): boot_devices.PXE, task.node.driver_internal_info['persistent_boot_device']) # PXE is converted to 'network' internally by ipminative - ipmicmd.set_bootdev.assert_called_once_with('network', persist=False) + ipmicmd.set_bootdev.assert_called_once_with('network', persist=False, + uefiboot=False) def test_set_boot_device_bad_device(self): with task_manager.acquire(self.context, self.node.uuid) as task: @@ -386,6 +390,32 @@ class IPMINativeDriverTestCase(db_base.DbTestCase): task, 'fake-device') + @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy') + @mock.patch('pyghmi.ipmi.command.Command', autospec=True) + def test_set_boot_device_uefi(self, ipmi_mock, boot_mode_mock): + ipmicmd = ipmi_mock.return_value + boot_mode_mock.return_value = 'uefi' + + with task_manager.acquire(self.context, self.node.uuid) as task: + self.driver.management.set_boot_device(task, boot_devices.PXE) + # PXE is converted to 'network' internally by ipminative + ipmicmd.set_bootdev.assert_called_once_with('network', persist=False, + uefiboot=True) + + @mock.patch.object(deploy_utils, 'get_boot_mode_for_deploy') + @mock.patch('pyghmi.ipmi.command.Command', autospec=True) + def test_set_boot_device_uefi_and_persistent( + self, ipmi_mock, boot_mode_mock): + ipmicmd = ipmi_mock.return_value + boot_mode_mock.return_value = 'uefi' + + with task_manager.acquire(self.context, self.node.uuid) as task: + self.driver.management.set_boot_device(task, boot_devices.PXE, + persistent=True) + # PXE is converted to 'network' internally by ipminative + ipmicmd.set_bootdev.assert_called_once_with('network', persist=True, + uefiboot=True) + @mock.patch.object(driver_utils, 'ensure_next_boot_device', autospec=True) @mock.patch.object(ipminative, '_reboot', autospec=True) def test_reboot_ok(self, reboot_mock, mock_next_boot): diff --git a/releasenotes/notes/ipminative-bootdev-uefi-954a0dd825bcef97.yaml b/releasenotes/notes/ipminative-bootdev-uefi-954a0dd825bcef97.yaml new file mode 100644 index 0000000000..85459f004b --- /dev/null +++ b/releasenotes/notes/ipminative-bootdev-uefi-954a0dd825bcef97.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - Fixes a problem where the boot mode (UEFI or BIOS) wasn't being + considered when setting the boot device of a node using the ipminative + driver making it to switch from UEFI to legacy BIOS as part of the + request to change the boot device.