Fix redfish BIOS to use @Redfish.SettingsApplyTime

This change fixes the 'redfish' BIOS interface 'apply_configuration'
cleaning/deploy step to work with Redfish Services that must be supplied
the Distributed Management Task Force (DMTF) Redfish standard
@Redfish.SettingsApplyTime annotation [1] to specify when to apply the
requested settings, such as the Dell EMC integrated Dell Remote Acesss
Controller (iDRAC).

Such services, typically offered by baseboard management controllers
(BMC), require POST of the annotation, along with the future intended
state of the settings. Otherwise, they may never be applied.

When the annotation is not supported, it is not provided with the future
intended state of the settings.

[1] http://redfish.dmtf.org/schemas/DSP0266_1.11.0.html#settings-resource

Co-Authored-By: Eric Barrera <eric_barrera@dell.com>
Co-Authored-By: Aija Jauntēva <aija.jaunteva@dell.com>
Co-Authored-By: Mike Raineri <mraineri@gmail.com>
Story: 2008163
Task: 40913
Depends-On: https://review.opendev.org/#/c/750020/
Change-Id: I28a948f306b40c36b12e6f786e1e43a61e84a0f2
This commit is contained in:
Richard Pioso 2020-09-17 18:27:14 -04:00
parent 4633fe937d
commit 65d5066394
6 changed files with 76 additions and 4 deletions

View File

@ -11,7 +11,7 @@ python-dracclient>=3.1.0,<5.0.0
python-xclarityclient>=0.1.6
# The Redfish hardware type uses the Sushy library
sushy>=3.2.0
sushy>=3.4.0
# Ansible-deploy interface
ansible>=2.7

View File

@ -175,8 +175,15 @@ class RedfishBIOS(base.BIOSInterface):
LOG.debug('Apply BIOS configuration for node %(node_uuid)s: '
'%(settings)r', {'node_uuid': task.node.uuid,
'settings': settings})
if bios.supported_apply_times and (
sushy.APPLY_TIME_ON_RESET in bios.supported_apply_times):
apply_time = sushy.APPLY_TIME_ON_RESET
else:
apply_time = None
try:
bios.set_attributes(attributes)
bios.set_attributes(attributes, apply_time=apply_time)
except sushy.exceptions.SushyError as e:
error_msg = (_('Redfish BIOS apply configuration failed for '
'node %(node)s. Error: %(error)s') %

View File

@ -186,17 +186,20 @@ class RedfishBiosTestCase(db_base.DbTestCase):
mock_build_agent_options.return_value = {'a': 'b'}
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
bios = mock_get_system(task.node).bios
if step == 'factory_reset':
ret = task.driver.bios.factory_reset(task)
if step == 'apply_configuration':
bios.apply_time_settings = None
bios.supported_apply_times = []
ret = task.driver.bios.apply_configuration(task, data)
mock_get_system.assert_called_with(task.node)
mock_power_action.assert_called_once_with(task, states.REBOOT)
bios = mock_get_system(task.node).bios
if step == 'factory_reset':
bios.reset_bios.assert_called_once()
if step == 'apply_configuration':
bios.set_attributes.assert_called_once_with(attributes)
bios.set_attributes.assert_called_once_with(
attributes, apply_time=None)
mock_build_agent_options.assert_called_once_with(task.node)
mock_prepare.assert_called_once_with(mock.ANY, task, {'a': 'b'})
info = task.node.driver_internal_info
@ -378,3 +381,49 @@ class RedfishBiosTestCase(db_base.DbTestCase):
task.driver.bios.apply_configuration(task, settings)
task.driver.bios.post_configuration\
.assert_called_once_with(task, settings)
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot, 'prepare_ramdisk',
spec_set=True, autospec=True)
@mock.patch.object(deploy_utils, 'build_agent_options', autospec=True)
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
def test_apply_configuration_apply_time_settings(self, mock_power_action,
mock_get_system,
mock_build_agent_options,
mock_prepare):
settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
{'name': 'NicBoot1', 'value': 'NetworkBoot'}]
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
bios = mock_get_system(task.node).bios
bios.apply_time_settings = mock.Mock()
bios.supported_apply_times = ['immediate']
task.driver.bios.apply_configuration(task, settings)
bios.set_attributes.assert_called_once_with(
{s['name']: s['value'] for s in settings},
apply_time=None)
@mock.patch.object(redfish_boot.RedfishVirtualMediaBoot, 'prepare_ramdisk',
spec_set=True, autospec=True)
@mock.patch.object(deploy_utils, 'build_agent_options', autospec=True)
@mock.patch.object(redfish_utils, 'get_system', autospec=True)
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
def test_apply_configuration_apply_time_on_reset(self, mock_power_action,
mock_get_system,
mock_build_agent_options,
mock_prepare):
settings = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
{'name': 'NicBoot1', 'value': 'NetworkBoot'}]
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
bios = mock_get_system(task.node).bios
bios.apply_time_settings = None
bios.supported_apply_times = [sushy.APPLY_TIME_ON_RESET]
task.driver.bios.apply_configuration(task, settings)
bios.set_attributes.assert_called_once_with(
{s['name']: s['value'] for s in settings},
apply_time=sushy.APPLY_TIME_ON_RESET)

View File

@ -155,6 +155,7 @@ SUSHY_SPEC = (
'STATE_ABSENT',
'VIRTUAL_MEDIA_CD',
'VIRTUAL_MEDIA_FLOPPY',
'APPLY_TIME_ON_RESET',
)
SUSHY_AUTH_SPEC = (

View File

@ -217,6 +217,7 @@ if not sushy:
STATE_ABSENT='absent',
VIRTUAL_MEDIA_CD='cd',
VIRTUAL_MEDIA_FLOPPY='floppy',
APPLY_TIME_ON_RESET='on reset',
)
sys.modules['sushy'] = sushy

View File

@ -0,0 +1,14 @@
---
fixes:
- |
Fixes ``redfish`` BIOS interface ``apply_configuration`` cleaning/deploy
step to work with Redfish Services that must be supplied the Distributed
Management Task Force (DMTF) Redfish standard
``@Redfish.SettingsApplyTime`` annotation [1] to specify when to apply the
requested settings, such as the Dell EMC integrated Dell Remote Acesss
Controller (iDRAC).
For more information, see `story 2008163
<https://storyboard.openstack.org/#!/story/2008163>`_.
[1] http://redfish.dmtf.org/schemas/DSP0266_1.11.0.html#settings-resource