IPMINative: Check the boot mode when setting the boot device

This patch is making the ipminative drive to take in consideration the
boot mode (UEFI or BIOS) of the node when changing its boot device
order. Otherwise, nodes in UEFI will switch to legacy BIOS as part of
the set_boot_device() call.

Closes-Bug: #1612287
Change-Id: I6a7f522ae9c7d58f216a7d5dfedf067da0a0fc32
This commit is contained in:
Lucas Alvares Gomes 2016-08-11 16:17:07 +01:00
parent ba1e15e3a9
commit bcfab9f8ba
3 changed files with 43 additions and 4 deletions

View File

@ -38,6 +38,7 @@ from ironic.conductor import task_manager
from ironic.conf import CONF
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')
@ -453,13 +454,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"),

View File

@ -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
@ -344,7 +345,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):
@ -361,7 +363,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):
@ -378,7 +381,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:
@ -387,6 +391,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):

View File

@ -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.