summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/admin/drivers/redfish.rst9
-rw-r--r--driver-requirements.txt2
-rw-r--r--ironic/drivers/modules/redfish/bios.py55
-rw-r--r--ironic/drivers/modules/redfish/boot.py46
-rw-r--r--ironic/drivers/utils.py42
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_bios.py204
-rw-r--r--ironic/tests/unit/drivers/modules/redfish/test_boot.py16
-rw-r--r--ironic/tests/unit/drivers/modules/test_image_utils.py19
-rw-r--r--releasenotes/notes/get-bios-registry-aadc74800e0770f7.yaml6
-rw-r--r--releasenotes/notes/redfish-deploy-iso-9671ae83108f6385.yaml6
10 files changed, 367 insertions, 38 deletions
diff --git a/doc/source/admin/drivers/redfish.rst b/doc/source/admin/drivers/redfish.rst
index cff72a48f..63f2e4bbe 100644
--- a/doc/source/admin/drivers/redfish.rst
+++ b/doc/source/admin/drivers/redfish.rst
@@ -219,13 +219,18 @@ with the Wallaby release it's possible to provide a pre-built ISO image:
.. code-block:: bash
baremetal node set node-0 \
- --driver_info redfish_deploy_iso=http://url/of/deploy.iso \
- --driver_info redfish_rescue_iso=http://url/of/rescue.iso
+ --driver_info deploy_iso=http://url/of/deploy.iso \
+ --driver_info rescue_iso=http://url/of/rescue.iso
.. note::
OpenStack Image service (glance) image IDs and ``file://`` links are also
accepted.
+.. note::
+ Before the Xena release the parameters were called ``redfish_deploy_iso``
+ and ``redfish_rescue_iso`` accordingly. The old names are still supported
+ for backward compatibility.
+
No customization is currently done to the image, so e.g.
:doc:`/admin/dhcp-less` won't work. `Configuring an ESP image`_ is also
unnecessary.
diff --git a/driver-requirements.txt b/driver-requirements.txt
index 151e745bc..e379bb99a 100644
--- a/driver-requirements.txt
+++ b/driver-requirements.txt
@@ -11,7 +11,7 @@ python-dracclient>=5.1.0,<7.0.0
python-xclarityclient>=0.1.6
# The Redfish hardware type uses the Sushy library
-sushy>=3.7.0
+sushy>=3.8.0
# Ansible-deploy interface
ansible>=2.7
diff --git a/ironic/drivers/modules/redfish/bios.py b/ironic/drivers/modules/redfish/bios.py
index ae8acc939..c1af56f24 100644
--- a/ironic/drivers/modules/redfish/bios.py
+++ b/ironic/drivers/modules/redfish/bios.py
@@ -32,6 +32,10 @@ METRICS = metrics_utils.get_metrics_logger(__name__)
sushy = importutils.try_import('sushy')
+registry_fields = ('attribute_type', 'allowable_values', 'lower_bound',
+ 'max_length', 'min_length', 'read_only',
+ 'reset_required', 'unique', 'upper_bound')
+
class RedfishBIOS(base.BIOSInterface):
@@ -51,6 +55,23 @@ class RedfishBIOS(base.BIOSInterface):
driver='redfish',
reason=_("Unable to import the sushy library"))
+ def _parse_allowable_values(self, allowable_values):
+ """Convert the BIOS registry allowable_value list to expected strings
+
+ :param allowable_values: list of dicts of valid values for enumeration
+ :returns: list containing only allowable value names
+ """
+
+ # Get name from ValueName if it exists, otherwise use DisplayValueName
+ new_list = []
+ for dic in allowable_values:
+ for key in dic:
+ if key == 'ValueName' or key == 'DisplayValueName':
+ new_list.append(dic[key])
+ break
+
+ return new_list
+
def cache_bios_settings(self, task):
"""Store or update the current BIOS settings for the node.
@@ -77,7 +98,39 @@ class RedfishBIOS(base.BIOSInterface):
settings = []
# Convert Redfish BIOS attributes to Ironic BIOS settings
if attributes:
- settings = [{'name': k, 'value': v} for k, v in attributes.items()]
+ settings = [{'name': k, 'value': v}
+ for k, v in attributes.items()]
+
+ # Get the BIOS Registry
+ registry_attributes = []
+ try:
+ bios_registry = system.bios.get_attribute_registry()
+
+ if bios_registry:
+ registry_attributes = bios_registry.registry_entries.attributes
+
+ except Exception as e:
+ LOG.info('Cannot get BIOS Registry attributes for node %(node)s, '
+ 'Error %(exc)s.', {'node': task.node.uuid, 'exc': e})
+
+ # TODO(bfournier): use a common list for registry field names
+ # e.g. registry_fields = objects.BIOSSetting.registry_fields
+
+ # The BIOS registry will contain more entries than the BIOS settings
+ # Find the registry entry matching the setting name and get the fields
+ if registry_attributes:
+ for setting in settings:
+ reg = next((r for r in registry_attributes
+ if r.name == setting['name']), None)
+ fields = [attr for attr in dir(reg)
+ if not attr.startswith("_")]
+ settable_keys = [f for f in fields if f in registry_fields]
+ # Set registry fields to current values
+ for k in settable_keys:
+ setting[k] = getattr(reg, k, None)
+ if k == "allowable_values" and isinstance(setting[k],
+ list):
+ setting[k] = self._parse_allowable_values(setting[k])
LOG.debug('Cache BIOS settings for node %(node_uuid)s',
{'node_uuid': task.node.uuid})
diff --git a/ironic/drivers/modules/redfish/boot.py b/ironic/drivers/modules/redfish/boot.py
index b854fc994..0f48b4d1e 100644
--- a/ironic/drivers/modules/redfish/boot.py
+++ b/ironic/drivers/modules/redfish/boot.py
@@ -35,9 +35,11 @@ LOG = log.getLogger(__name__)
REQUIRED_PROPERTIES = {
'deploy_kernel': _("URL or Glance UUID of the deployment kernel. "
- "Required."),
- 'deploy_ramdisk': _("URL or Glance UUID of the ramdisk that is "
- "mounted at boot time. Required.")
+ "Required if deploy_iso is not set."),
+ 'deploy_ramdisk': _("URL or Glance UUID of the ramdisk that is mounted at "
+ "boot time. Required if deploy_iso is not set."),
+ 'deploy_iso': _("URL or Glance UUID of the deployment ISO to use. "
+ "Required if deploy_kernel/deploy_ramdisk are not set.")
}
OPTIONAL_PROPERTIES = {
@@ -56,16 +58,19 @@ OPTIONAL_PROPERTIES = {
"image containing EFI boot loader. This image will be "
"used by ironic when building UEFI-bootable ISO "
"out of kernel and ramdisk. Required for UEFI "
- "boot from partition images."),
+ "when deploy_iso is not provided."),
}
RESCUE_PROPERTIES = {
- 'rescue_kernel': _('URL or Glance UUID of the rescue kernel. This value '
- 'is required for rescue mode.'),
+ 'rescue_kernel': _('URL or Glance UUID of the rescue kernel. Required for '
+ 'rescue mode if rescue_iso is not set.'),
'rescue_ramdisk': _('URL or Glance UUID of the rescue ramdisk with agent '
- 'that is used at node rescue time. This value is '
- 'required for rescue mode.'),
+ 'that is used at node rescue time. Required for '
+ 'rescue mode if rescue_iso is not set.'),
+ 'rescue_iso': _("URL or Glance UUID of the rescue ISO to use. Required "
+ "for rescue mode if rescue_kernel/rescue_ramdisk are "
+ "not set.")
}
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
@@ -73,11 +78,6 @@ COMMON_PROPERTIES.update(driver_utils.OPTIONAL_PROPERTIES)
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
COMMON_PROPERTIES.update(RESCUE_PROPERTIES)
-KERNEL_RAMDISK_LABELS = {
- 'deploy': REQUIRED_PROPERTIES,
- 'rescue': RESCUE_PROPERTIES
-}
-
IMAGE_SUBDIR = 'redfish'
sushy = importutils.try_import('sushy')
@@ -100,23 +100,15 @@ def _parse_driver_info(node):
d_info = node.driver_info
mode = deploy_utils.rescue_or_deploy_mode(node)
- iso_param = 'redfish_%s_iso' % mode
- iso_ref = d_info.get(iso_param)
+ iso_param = f'{mode}_iso'
+ iso_ref = driver_utils.get_agent_iso(node, deprecated_prefix='redfish',
+ mode=mode)
if iso_ref is not None:
deploy_info = {iso_param: iso_ref}
can_config = False
else:
- params_to_check = KERNEL_RAMDISK_LABELS[mode]
-
- deploy_info = {option: d_info.get(option)
- for option in params_to_check}
-
- if not any(deploy_info.values()):
- # NOTE(dtantsur): avoid situation when e.g. deploy_kernel comes
- # from driver_info but deploy_ramdisk comes from configuration,
- # since it's a sign of a potential operator's mistake.
- deploy_info = {k: getattr(CONF.conductor, k)
- for k in params_to_check}
+ # There was never a deprecated prefix for kernel/ramdisk
+ deploy_info = driver_utils.get_agent_kernel_ramdisk(node, mode)
error_msg = _("Error validating Redfish virtual media. Some "
"parameters were missing in node's driver_info")
@@ -378,6 +370,8 @@ class RedfishVirtualMediaBoot(base.BootInterface):
node = task.node
_parse_driver_info(node)
+ # Issue the deprecation warning if needed
+ driver_utils.get_agent_iso(node, deprecated_prefix='redfish')
def _validate_instance_info(self, task):
"""Validate instance image information for the task's node.
diff --git a/ironic/drivers/utils.py b/ironic/drivers/utils.py
index fa826c266..56b4409df 100644
--- a/ironic/drivers/utils.py
+++ b/ironic/drivers/utils.py
@@ -404,3 +404,45 @@ def get_kernel_append_params(node, default):
return result
return default
+
+
+def _get_field(node, name, deprecated_prefix=None):
+ value = node.driver_info.get(name)
+ if value or not deprecated_prefix:
+ return value
+
+ deprecated_name = f'{deprecated_prefix}_{name}'
+ value = node.driver_info.get(deprecated_name)
+ if value:
+ LOG.warning("The driver_info field %s of node %s is deprecated, "
+ "please use %s instead",
+ deprecated_name, node.uuid, name)
+ return value
+
+
+def get_agent_kernel_ramdisk(node, mode='deploy', deprecated_prefix=None):
+ """Get the agent kernel/ramdisk as a dictionary."""
+ kernel_name = f'{mode}_kernel'
+ ramdisk_name = f'{mode}_ramdisk'
+ kernel, ramdisk = (
+ _get_field(node, kernel_name, deprecated_prefix),
+ _get_field(node, ramdisk_name, deprecated_prefix),
+ )
+ # NOTE(dtantsur): avoid situation when e.g. deploy_kernel comes
+ # from driver_info but deploy_ramdisk comes from configuration,
+ # since it's a sign of a potential operator's mistake.
+ if not kernel or not ramdisk:
+ return {
+ kernel_name: getattr(CONF.conductor, kernel_name),
+ ramdisk_name: getattr(CONF.conductor, ramdisk_name),
+ }
+ else:
+ return {
+ kernel_name: kernel,
+ ramdisk_name: ramdisk
+ }
+
+
+def get_agent_iso(node, mode='deploy', deprecated_prefix=None):
+ """Get the agent ISO image."""
+ return _get_field(node, f'{mode}_iso', deprecated_prefix)
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_bios.py b/ironic/tests/unit/drivers/modules/redfish/test_bios.py
index 30aab9587..cd6f9be5f 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_bios.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_bios.py
@@ -99,7 +99,9 @@ class RedfishBiosTestCase(db_base.DbTestCase):
task.driver.bios.cache_bios_settings(task)
mock_get_system.assert_called_once_with(task.node)
mock_setting_list.sync_node_setting.assert_called_once_with(
- task.context, task.node.id, [{'name': 'foo', 'value': 'bar'}])
+ task.context, task.node.id,
+ [{'name': 'foo', 'value': 'bar'}])
+
mock_setting_list.create.assert_not_called()
mock_setting_list.save.assert_not_called()
mock_setting_list.delete.assert_not_called()
@@ -153,7 +155,9 @@ class RedfishBiosTestCase(db_base.DbTestCase):
task.driver.bios.cache_bios_settings(task)
mock_get_system.assert_called_once_with(task.node)
mock_setting_list.sync_node_setting.assert_called_once_with(
- task.context, task.node.id, [{'name': 'foo', 'value': 'bar'}])
+ task.context, task.node.id,
+ [{'name': 'foo', 'value': 'bar'}])
+
mock_setting_list.create.assert_called_once_with(
task.context, task.node.id, create_list)
mock_setting_list.save.assert_called_once_with(
@@ -252,6 +256,7 @@ class RedfishBiosTestCase(db_base.DbTestCase):
# by returning the same as requested
mock_bios.attributes = attributes_after_reboot \
or self.node.driver_internal_info['requested_bios_attrs']
+ mock_bios.get_attribute_registry = []
mock_system = mock.Mock()
mock_system.bios = mock_bios
mock_get_system.return_value = mock_system
@@ -313,7 +318,8 @@ class RedfishBiosTestCase(db_base.DbTestCase):
@mock.patch.object(manager_utils, 'cleaning_error_handler', autospec=True)
def test_apply_conf_post_reboot_cleaning_failed(
self, mock_cleaning_error_handler):
- data = [{'name': 'ProcTurboMode', 'value': 'Enabled'}]
+ data = [{'name': 'ProcTurboMode', 'value': 'Enabled',
+ 'registry': {'description': 'Turbo mode'}}]
self.node.clean_step = {'priority': 100, 'interface': 'bios',
'step': 'apply_configuration',
'argsinfo': {'settings': data}}
@@ -331,8 +337,10 @@ class RedfishBiosTestCase(db_base.DbTestCase):
mock_cleaning_error_handler.assert_called_once()
def test_apply_conf_post_reboot_deploying(self):
- data = [{'name': 'ProcTurboMode', 'value': 'Disabled'},
- {'name': 'NicBoot1', 'value': 'NetworkBoot'}]
+ data = [{'name': 'ProcTurboMode', 'value': 'Enabled',
+ 'registry': {'description': 'Turbo mode'}},
+ {'name': 'NicBoot1', 'value': 'NetworkBoot',
+ 'registry': {'description': 'Boot off network'}}]
self.node.deploy_step = {'priority': 100, 'interface': 'bios',
'step': 'apply_configuration',
'argsinfo': {'settings': data}}
@@ -349,7 +357,8 @@ class RedfishBiosTestCase(db_base.DbTestCase):
@mock.patch.object(manager_utils, 'deploying_error_handler', autospec=True)
def test_apply_conf_post_reboot_deploying_failed(
self, mock_deploying_error_handler):
- data = [{'name': 'ProcTurboMode', 'value': 'Enabled'}]
+ data = [{'name': 'ProcTurboMode', 'value': 'Enabled',
+ 'registry': {'description': 'Turbo mode'}}]
self.node.deploy_step = {'priority': 100, 'interface': 'bios',
'step': 'apply_configuration',
'argsinfo': {'settings': data}}
@@ -503,3 +512,186 @@ class RedfishBiosTestCase(db_base.DbTestCase):
bios.set_attributes.assert_called_once_with(
{s['name']: s['value'] for s in settings},
apply_time=None)
+
+
+@mock.patch('oslo_utils.eventletutils.EventletEvent.wait',
+ lambda *args, **kwargs: None)
+class RedfishBiosRegistryTestCase(db_base.DbTestCase):
+
+ def setUp(self):
+ super(RedfishBiosRegistryTestCase, self).setUp()
+ self.config(enabled_bios_interfaces=['redfish'],
+ enabled_hardware_types=['redfish'],
+ enabled_power_interfaces=['redfish'],
+ enabled_boot_interfaces=['redfish-virtual-media'],
+ enabled_management_interfaces=['redfish'])
+ self.node = obj_utils.create_test_node(
+ self.context, driver='redfish', driver_info=INFO_DICT)
+
+ self.settings = {'SystemModelName': 'UltraSumma',
+ 'DcuStreamPrefetcher': 'Enabled',
+ 'BootDelay': 10}
+
+ class AttributeField():
+
+ def __init__(self):
+ self.name = None
+ self.allowable_values = None
+ self.attribute_type = None
+ self.lower_bound = None
+ self.max_length = None
+ self.min_length = None
+ self.read_only = None
+ self.reset_required = None
+ self.type = None
+ self.unique = None
+ self.upper_bound = None
+
+ class AttributeRegistryEntryField():
+
+ def __init__(self, num_entries):
+ self.attributes = []
+ for _ in range(num_entries):
+ self.attributes.append(AttributeField())
+
+ class AttributeRegistryTest():
+
+ def __init__(self, num_entries):
+ self.registry_entries = AttributeRegistryEntryField(
+ num_entries)
+
+ self.registry = AttributeRegistryTest(4)
+ self.registry.registry_entries.attributes[0].name = "SystemModelName"
+ self.registry.registry_entries.attributes[0].attribute_type = "String"
+ self.registry.registry_entries.attributes[0].max_length = 32
+ self.registry.registry_entries.attributes[0].read_only = True
+ self.registry.registry_entries.attributes[0].unique = True
+ self.registry.registry_entries.attributes[1].name =\
+ "DcuStreamPrefetcher"
+ self.registry.registry_entries.attributes[1].attribute_type =\
+ "Enumeration"
+ self.registry.registry_entries.attributes[1].read_only = False
+ self.registry.registry_entries.attributes[1].allowable_values =\
+ [{'ValueName': 'Enabled', 'ValueDisplayName': 'Enabled'},
+ {'ValueName': 'Disabled', 'ValueDisplayName': 'Disabled'}]
+ self.registry.registry_entries.attributes[2].name = "BootDelay"
+ self.registry.registry_entries.attributes[2].attribute_type = "Integer"
+ self.registry.registry_entries.attributes[2].lower_bound = 5
+ self.registry.registry_entries.attributes[2].upper_bound = 30
+ self.registry.registry_entries.attributes[2].reset_required = True
+ self.registry.registry_entries.attributes[3].name = "SomeAttribute"
+ self.registry.registry_entries.attributes[3].attribute_type = "String"
+ self.registry.registry_entries.attributes[3].max_length = 32
+ self.registry.registry_entries.attributes[3].read_only = True
+
+ self.expected_no_registry = [
+ {'name': 'SystemModelName', 'value': 'UltraSumma'},
+ {'name': 'DcuStreamPrefetcher', 'value': 'Enabled'},
+ {'name': 'BootDelay', 'value': 10}]
+
+ @mock.patch.object(objects, 'BIOSSettingList', autospec=True)
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_cache_bios_registry_save(self, mock_get_system,
+ mock_setting_list):
+ create_list = []
+ update_list = []
+ delete_list = []
+ nochange_list = []
+ mock_setting_list.sync_node_setting.return_value = (
+ create_list, update_list, delete_list, nochange_list
+ )
+
+ expected = [{'name': 'SystemModelName', 'value': 'UltraSumma',
+ 'allowable_values': None, 'lower_bound': None,
+ 'max_length': 32, 'min_length': None, 'read_only': True,
+ 'reset_required': None, 'attribute_type': 'String',
+ 'unique': True, 'upper_bound': None},
+ {'name': 'DcuStreamPrefetcher', 'value': 'Enabled',
+ 'allowable_values': ['Enabled', 'Disabled'],
+ 'lower_bound': None, 'max_length': None,
+ 'min_length': None, 'read_only': False,
+ 'reset_required': None, 'attribute_type':
+ 'Enumeration', 'unique': None, 'upper_bound': None},
+ {'name': 'BootDelay', 'value': 10,
+ 'allowable_values': None, 'lower_bound': 5,
+ 'max_length': None, 'min_length': None, 'read_only': None,
+ 'reset_required': True, 'attribute_type': 'Integer',
+ 'unique': None, 'upper_bound': 30}]
+
+ mock_get_system.return_value.bios.attributes = self.settings
+ mock_get_system.return_value.bios.get_attribute_registry.\
+ return_value = self.registry
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ task.driver.bios.cache_bios_settings(task)
+ mock_get_system.assert_called_once_with(task.node)
+ mock_setting_list.sync_node_setting.assert_called_once_with(
+ task.context, task.node.id, expected)
+
+ @mock.patch.object(objects, 'BIOSSettingList', autospec=True)
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_cache_empty_bios_registry(self, mock_get_system,
+ mock_setting_list):
+ create_list = []
+ update_list = []
+ delete_list = []
+ nochange_list = []
+ mock_setting_list.sync_node_setting.return_value = (
+ create_list, update_list, delete_list, nochange_list
+ )
+
+ mock_get_system.return_value.bios.attributes = self.settings
+ mock_get_system.return_value.bios.get_attribute_registry.\
+ return_value = {}
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ task.driver.bios.cache_bios_settings(task)
+ mock_setting_list.sync_node_setting.assert_called_once_with(
+ task.context, task.node.id, self.expected_no_registry)
+
+ @mock.patch.object(objects, 'BIOSSettingList', autospec=True)
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_cache_no_bios_registry(self, mock_get_system,
+ mock_setting_list):
+ create_list = []
+ update_list = []
+ delete_list = []
+ nochange_list = []
+ mock_setting_list.sync_node_setting.return_value = (
+ create_list, update_list, delete_list, nochange_list
+ )
+
+ mock_get_system.return_value.bios.attributes = self.settings
+ mock_get_system.return_value.bios.get_attribute_registry.\
+ return_value = None
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ task.driver.bios.cache_bios_settings(task)
+ mock_setting_list.sync_node_setting.assert_called_once_with(
+ task.context, task.node.id, self.expected_no_registry)
+
+ @mock.patch.object(objects, 'BIOSSettingList', autospec=True)
+ @mock.patch.object(redfish_utils, 'get_system', autospec=True)
+ def test_cache_exception_bios_registry(self, mock_get_system,
+ mock_setting_list):
+ create_list = []
+ update_list = []
+ delete_list = []
+ nochange_list = []
+ mock_setting_list.sync_node_setting.return_value = (
+ create_list, update_list, delete_list, nochange_list
+ )
+
+ mock_get_system.return_value.bios.attributes = self.settings
+
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ bios = mock_get_system(task.node).bios
+ bios.reset_bios.side_effect = sushy.exceptions.SushyError
+
+ task.driver.bios.cache_bios_settings(task)
+ mock_setting_list.sync_node_setting.assert_called_once_with(
+ task.context, task.node.id, self.expected_no_registry)
diff --git a/ironic/tests/unit/drivers/modules/redfish/test_boot.py b/ironic/tests/unit/drivers/modules/redfish/test_boot.py
index d4471cda5..e0f0dbf17 100644
--- a/ironic/tests/unit/drivers/modules/redfish/test_boot.py
+++ b/ironic/tests/unit/drivers/modules/redfish/test_boot.py
@@ -78,19 +78,31 @@ class RedfishVirtualMediaBootTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
task.node.driver_info.update(
+ {'deploy_iso': 'http://boot.iso'})
+
+ actual_driver_info = redfish_boot._parse_driver_info(task.node)
+
+ self.assertEqual('http://boot.iso',
+ actual_driver_info['deploy_iso'])
+ self.assertFalse(actual_driver_info['can_provide_config'])
+
+ def test_parse_driver_info_iso_deprecated(self):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+ task.node.driver_info.update(
{'redfish_deploy_iso': 'http://boot.iso'})
actual_driver_info = redfish_boot._parse_driver_info(task.node)
self.assertEqual('http://boot.iso',
- actual_driver_info['redfish_deploy_iso'])
+ actual_driver_info['deploy_iso'])
self.assertFalse(actual_driver_info['can_provide_config'])
def test_parse_driver_info_removable(self):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
task.node.driver_info.update(
- {'redfish_deploy_iso': 'http://boot.iso',
+ {'deploy_iso': 'http://boot.iso',
'config_via_removable': True}
)
diff --git a/ironic/tests/unit/drivers/modules/test_image_utils.py b/ironic/tests/unit/drivers/modules/test_image_utils.py
index 1e105a08f..91c0e514c 100644
--- a/ironic/tests/unit/drivers/modules/test_image_utils.py
+++ b/ironic/tests/unit/drivers/modules/test_image_utils.py
@@ -654,6 +654,25 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
shared=True) as task:
d_info = {
+ 'deploy_iso': 'iso',
+ }
+ task.node.driver_info.update(d_info)
+
+ task.node.instance_info.update(deploy_boot_mode='uefi')
+
+ image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info)
+
+ mock__prepare_iso_image.assert_called_once_with(
+ task, None, None, None, params={},
+ inject_files={}, base_iso='iso')
+
+ @mock.patch.object(image_utils, '_prepare_iso_image', autospec=True)
+ def test_prepare_deploy_iso_existing_iso_vendor_prefix(
+ self, mock__prepare_iso_image):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=True) as task:
+
+ d_info = {
'redfish_deploy_iso': 'iso',
}
task.node.driver_info.update(d_info)
diff --git a/releasenotes/notes/get-bios-registry-aadc74800e0770f7.yaml b/releasenotes/notes/get-bios-registry-aadc74800e0770f7.yaml
new file mode 100644
index 000000000..c158fb0e2
--- /dev/null
+++ b/releasenotes/notes/get-bios-registry-aadc74800e0770f7.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Get the BIOS Registry from Sushy and store the fields in the Ironic DB
+ with the BIOS setting. See `story
+ 2008571 <https://storyboard.openstack.org/#!/story/2008571>`_.
diff --git a/releasenotes/notes/redfish-deploy-iso-9671ae83108f6385.yaml b/releasenotes/notes/redfish-deploy-iso-9671ae83108f6385.yaml
new file mode 100644
index 000000000..10111a795
--- /dev/null
+++ b/releasenotes/notes/redfish-deploy-iso-9671ae83108f6385.yaml
@@ -0,0 +1,6 @@
+---
+deprecations:
+ - |
+ The node's ``driver_info`` parameters ``redfish_deploy_iso`` and
+ ``redfish_rescue_iso`` have been renamed to ``deploy_iso`` and
+ ``rescue_iso`` accordingly. The old names are deprecated.