Merge "For Supermicro BMCs set enable when changing boot device" into stable/ussuri

This commit is contained in:
Zuul 2021-04-20 15:44:02 +00:00 committed by Gerrit Code Review
commit ed1509c9c7
3 changed files with 64 additions and 5 deletions

View File

@ -81,12 +81,26 @@ def _set_boot_device(task, system, device, persistent=False):
Default: False. Default: False.
:raises: SushyError on an error from the Sushy library :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 # The BMC handling of the persistent setting is vendor specific.
enabled = (desired_enabled # Some vendors require that it not be set if currently equal to
if desired_enabled != current_enabled else None) # desired state (see https://storyboard.openstack.org/#!/story/2007355).
# Supermicro BMCs handle it in the opposite manner - the
# persistent setting must be set when setting the boot device
# (see https://storyboard.openstack.org/#!/story/2008547).
vendor = task.node.properties.get('vendor', None)
if vendor and vendor.lower() == 'supermicro':
enabled = BOOT_DEVICE_PERSISTENT_MAP_REV[persistent]
LOG.debug('Setting BootSourceOverrideEnable to %(enable)s '
'on Supermicro BMC, node %(node)s',
{'enable': enabled, 'node': task.node.uuid})
else:
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: try:
system.set_system_boot_options(device, enabled=enabled) system.set_system_boot_options(device, enabled=enabled)

View File

@ -240,6 +240,36 @@ class RedfishManagementTestCase(db_base.DbTestCase):
sushy.BOOT_SOURCE_TARGET_PXE, sushy.BOOT_SOURCE_TARGET_PXE,
task.node.driver_internal_info['redfish_boot_device']) task.node.driver_internal_info['redfish_boot_device'])
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
def test_set_boot_device_persistency_vendor(self, mock_get_system):
fake_system = mock_get_system.return_value
fake_system.boot.get.return_value = \
sushy.BOOT_SOURCE_ENABLED_CONTINUOUS
values = [
('SuperMicro', sushy.BOOT_SOURCE_ENABLED_CONTINUOUS),
('SomeVendor', None)
]
for vendor, expected in values:
properties = self.node.properties
properties['vendor'] = vendor
self.node.properties = properties
self.node.save()
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.driver.management.set_boot_device(
task, boot_devices.PXE, persistent=True)
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)])
# Reset mocks
fake_system.set_system_boot_options.reset_mock()
mock_get_system.reset_mock()
def test_restore_boot_device(self): def test_restore_boot_device(self):
fake_system = mock.Mock() fake_system = mock.Mock()
with task_manager.acquire(self.context, self.node.uuid, with task_manager.acquire(self.context, self.node.uuid,

View File

@ -0,0 +1,15 @@
---
fixes:
- |
When Ironic configures the BootSourceOverrideTarget setting via Redfish,
on Supermicro BMCs it must always configure BootSourceOverrideEnabled or
that will revert to default (Once) on the BMC, see `story 2008547
<https://storyboard.openstack.org/#!/story/2008547>`_ for details.
This is different than what is currently implemented for other BMCs in
which the BootSourceOverrideEnabled is not configured if it matches the
current setting (see `story 2007355
<https://storyboard.openstack.org/#!/story/2007355>`_).
This requires that node.properties['vendor'] be 'supermicro' which will
be set by Ironic from the Redfish system response or can be set
manually.