diff --git a/releasenotes/notes/ironic-rescue-ce08f432ccdcece4.yaml b/releasenotes/notes/ironic-rescue-ce08f432ccdcece4.yaml new file mode 100644 index 000000000..e67a6ea8a --- /dev/null +++ b/releasenotes/notes/ironic-rescue-ce08f432ccdcece4.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Sets ``rescue_kernel`` and ``rescue_ramdisk`` to the same values as + ``deploy_kernel`` and ``deploy_ramdisk`` on node enrollment or + configuration. + - | + Adds support for ``rescue_interface`` when enrolling nodes. diff --git a/tripleo_common/actions/baremetal.py b/tripleo_common/actions/baremetal.py index 02254f0b4..e7c6d5225 100644 --- a/tripleo_common/actions/baremetal.py +++ b/tripleo_common/actions/baremetal.py @@ -152,6 +152,16 @@ class ConfigureBootAction(base.TripleOAction): 'path': '/driver_info/deploy_kernel', 'value': image_ids['kernel'], }, + { + 'op': 'add', + 'path': '/driver_info/rescue_ramdisk', + 'value': image_ids['ramdisk'], + }, + { + 'op': 'add', + 'path': '/driver_info/rescue_kernel', + 'value': image_ids['kernel'], + }, ]) LOG.debug("Configuring boot option for Node %s", self.node_uuid) except Exception as err: diff --git a/tripleo_common/tests/actions/test_baremetal.py b/tripleo_common/tests/actions/test_baremetal.py index 3732b872d..8445c0fb2 100644 --- a/tripleo_common/tests/actions/test_baremetal.py +++ b/tripleo_common/tests/actions/test_baremetal.py @@ -35,6 +35,12 @@ class TestConfigureBootAction(base.TestCase): 'value': 'r_id'}, {'op': 'add', 'path': '/driver_info/deploy_kernel', + 'value': 'k_id'}, + {'op': 'add', + 'path': '/driver_info/rescue_ramdisk', + 'value': 'r_id'}, + {'op': 'add', + 'path': '/driver_info/rescue_kernel', 'value': 'k_id'}] self.ironic = mock.MagicMock() @@ -118,8 +124,18 @@ class TestConfigureBootAction(base.TestCase): self.assertIsNone(result) - self.node_update[1].update({'value': 'test_ramdisk_id'}) - self.node_update[2].update({'value': 'test_kernel_id'}) + self.node_update[1:] = [{'op': 'add', + 'path': '/driver_info/deploy_ramdisk', + 'value': 'test_ramdisk_id'}, + {'op': 'add', + 'path': '/driver_info/deploy_kernel', + 'value': 'test_kernel_id'}, + {'op': 'add', + 'path': '/driver_info/rescue_ramdisk', + 'value': 'test_ramdisk_id'}, + {'op': 'add', + 'path': '/driver_info/rescue_kernel', + 'value': 'test_kernel_id'}] self.ironic.node.update.assert_called_once_with(mock.ANY, self.node_update) diff --git a/tripleo_common/tests/utils/test_nodes.py b/tripleo_common/tests/utils/test_nodes.py index d2d6bc495..17df95d28 100644 --- a/tripleo_common/tests/utils/test_nodes.py +++ b/tripleo_common/tests/utils/test_nodes.py @@ -336,7 +336,9 @@ class NodesTest(base.TestCase): "ipmi_username": "test", "ipmi_password": "random", "deploy_kernel": "kernel-123", - "deploy_ramdisk": "ramdisk-999"} + "deploy_ramdisk": "ramdisk-999", + "rescue_kernel": "kernel-123", + "rescue_ramdisk": "ramdisk-999"} pxe_node = mock.call(driver="ipmi", name='node1', driver_info=pxe_node_driver_info, @@ -408,6 +410,7 @@ class NodesTest(base.TestCase): 'network_interface': 'neutron', 'power_interface': 'ipmitool', 'raid_interface': 'agent', + 'rescue_interface': 'agent', 'storage_interface': 'cinder', 'vendor_interface': 'ipmitool'} @@ -444,6 +447,7 @@ class NodesTest(base.TestCase): 'network_interface': 'neutron', 'power_interface': 'ipmitool', 'raid_interface': 'agent', + 'rescue_interface': 'agent', 'storage_interface': 'cinder', 'vendor_interface': 'ipmitool'} @@ -498,6 +502,8 @@ class NodesTest(base.TestCase): {'path': '/properties/capabilities', 'value': 'num_nics:6'}, {'path': '/driver_info/deploy_kernel', 'value': 'image-k'}, {'path': '/driver_info/deploy_ramdisk', 'value': 'image-r'}, + {'path': '/driver_info/rescue_kernel', 'value': 'image-k'}, + {'path': '/driver_info/rescue_ramdisk', 'value': 'image-r'}, {'path': '/driver_info/ipmi_username', 'value': 'test'}] for key in update_patch: key['op'] = 'add' diff --git a/tripleo_common/utils/nodes.py b/tripleo_common/utils/nodes.py index 8137d34c4..002e5597e 100644 --- a/tripleo_common/utils/nodes.py +++ b/tripleo_common/utils/nodes.py @@ -28,7 +28,8 @@ LOG = logging.getLogger(__name__) _KNOWN_INTERFACE_FIELDS = [ '%s_interface' % field for field in ('boot', 'console', 'deploy', 'inspect', 'management', 'network', - 'power', 'raid', 'storage', 'vendor') + 'power', 'raid', 'rescue', 'storage', + 'vendor') ] CTLPLANE_NETWORK = 'ctlplane' @@ -326,8 +327,10 @@ def register_ironic_node(node, client): if "kernel_id" in node: driver_info["deploy_kernel"] = node["kernel_id"] + driver_info["rescue_kernel"] = node["kernel_id"] if "ramdisk_id" in node: driver_info["deploy_ramdisk"] = node["ramdisk_id"] + driver_info["rescue_ramdisk"] = node["ramdisk_id"] interface_fields = {field: node.pop(field) for field in _KNOWN_INTERFACE_FIELDS @@ -439,8 +442,10 @@ _NON_DRIVER_FIELDS = {'cpu': '/properties/cpus', 'root_device': '/properties/root_device', 'name': '/name', 'resource_class': '/resource_class', - 'kernel_id': '/driver_info/deploy_kernel', - 'ramdisk_id': '/driver_info/deploy_ramdisk', + 'kernel_id': ['/driver_info/deploy_kernel', + '/driver_info/rescue_kernel'], + 'ramdisk_id': ['/driver_info/deploy_ramdisk', + '/driver_info/rescue_ramdisk'], 'capabilities': '/properties/capabilities'} _NON_DRIVER_FIELDS.update({field: '/%s' % field @@ -456,9 +461,14 @@ def _update_or_register_ironic_node(node, node_map, client): node_uuid) patched = {} - for field, path in _NON_DRIVER_FIELDS.items(): + for field, paths in _NON_DRIVER_FIELDS.items(): + if isinstance(paths, six.string_types): + paths = [paths] + if field in node: - patched[path] = node.pop(field) + value = node.pop(field) + for path in paths: + patched[path] = value driver_info = handler.convert(node) for key, value in driver_info.items():