Add support for rescue mode in enrollment and node configuration workflows

Change-Id: Ifed82bb0bc6bdfbfe5c89454187f00f347e5be45
Implements: blueprint ironic-rescue
This commit is contained in:
Dmitry Tantsur 2018-03-22 16:00:50 +01:00
parent 9f15b6859d
commit 1e6fa0bfb0
5 changed files with 58 additions and 8 deletions

View File

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

View File

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

View File

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

View File

@ -334,7 +334,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,
@ -403,6 +405,7 @@ class NodesTest(base.TestCase):
'network_interface': 'neutron',
'power_interface': 'ipmitool',
'raid_interface': 'agent',
'rescue_interface': 'agent',
'storage_interface': 'cinder',
'vendor_interface': 'ipmitool'}
@ -438,6 +441,7 @@ class NodesTest(base.TestCase):
'network_interface': 'neutron',
'power_interface': 'ipmitool',
'raid_interface': 'agent',
'rescue_interface': 'agent',
'storage_interface': 'cinder',
'vendor_interface': 'ipmitool'}
@ -492,6 +496,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'

View File

@ -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'
@ -312,8 +313,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
@ -420,8 +423,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
@ -437,9 +442,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():