Allow passing rootfs_uuid for the standalone case
Using software RAID with whole disk images requires specifying a root partition UUID, but it is only possible through Glance. This change adds an explicit field for that. Change-Id: I55e3727aab3960ef472ec2db1f23c25db405e801
This commit is contained in:
parent
3ba3f4d399
commit
0a68622187
@ -300,6 +300,13 @@ Populating instance_info
|
||||
|
||||
* ``ilo_boot_iso``, ``image_source``, ``root_gb`` under ``instance_info``.
|
||||
|
||||
#. For software RAID with whole-disk images, the root UUID of the root
|
||||
partition has to be provided so that the bootloader can be correctly
|
||||
installed::
|
||||
|
||||
baremetal node set $NODE_UUID \
|
||||
--instance-info image_rootfs_uuid=<uuid>
|
||||
|
||||
Deployment
|
||||
----------
|
||||
|
||||
|
@ -1333,26 +1333,29 @@ class AgentDeployMixin(HeartbeatMixin, AgentOobStepsMixin):
|
||||
# image's metadata (via Glance). Fall back to the driver internal
|
||||
# info in case it is not available (e.g. not set or there's no Glance).
|
||||
if software_raid:
|
||||
image_source = node.instance_info.get('image_source')
|
||||
try:
|
||||
context = task.context
|
||||
context.is_admin = True
|
||||
glance = image_service.GlanceImageService(
|
||||
context=context)
|
||||
image_info = glance.show(image_source)
|
||||
image_properties = image_info.get('properties')
|
||||
root_uuid = image_properties['rootfs_uuid']
|
||||
LOG.debug('Got rootfs_uuid from Glance: %s '
|
||||
'(node %s)', root_uuid, node.uuid)
|
||||
except Exception as e:
|
||||
LOG.warning('Could not get \'rootfs_uuid\' property for '
|
||||
'image %(image)s from Glance for node %(node)s. '
|
||||
'%(cls)s: %(error)s.',
|
||||
{'image': image_source, 'node': node.uuid,
|
||||
'cls': e.__class__.__name__, 'error': e})
|
||||
root_uuid = internal_info.get('root_uuid_or_disk_id')
|
||||
LOG.debug('Got rootfs_uuid from driver internal info: '
|
||||
'%s (node %s)', root_uuid, node.uuid)
|
||||
root_uuid = node.instance_info.get('image_rootfs_uuid')
|
||||
if not root_uuid:
|
||||
image_source = node.instance_info.get('image_source')
|
||||
try:
|
||||
context = task.context
|
||||
context.is_admin = True
|
||||
glance = image_service.GlanceImageService(
|
||||
context=context)
|
||||
image_info = glance.show(image_source)
|
||||
image_properties = image_info.get('properties')
|
||||
root_uuid = image_properties['rootfs_uuid']
|
||||
LOG.debug('Got rootfs_uuid from Glance: %s '
|
||||
'(node %s)', root_uuid, node.uuid)
|
||||
except Exception as e:
|
||||
LOG.warning(
|
||||
'Could not get \'rootfs_uuid\' property for '
|
||||
'image %(image)s from Glance for node %(node)s. '
|
||||
'%(cls)s: %(error)s.',
|
||||
{'image': image_source, 'node': node.uuid,
|
||||
'cls': e.__class__.__name__, 'error': e})
|
||||
root_uuid = internal_info.get('root_uuid_or_disk_id')
|
||||
LOG.debug('Got rootfs_uuid from driver internal info: '
|
||||
'%s (node %s)', root_uuid, node.uuid)
|
||||
|
||||
# For whole disk images it is not necessary that the root_uuid
|
||||
# be provided since the bootloaders on the disk will be used
|
||||
|
@ -1317,6 +1317,8 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
def test_configure_local_boot_on_software_raid(
|
||||
self, install_bootloader_mock, try_set_boot_device_mock,
|
||||
GlanceImageService_mock):
|
||||
image = GlanceImageService_mock.return_value.show.return_value
|
||||
image.get.return_value = {'rootfs_uuid': 'rootfs'}
|
||||
with task_manager.acquire(self.context, self.node['uuid'],
|
||||
shared=False) as task:
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||
@ -1336,7 +1338,50 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
}
|
||||
self.deploy.configure_local_boot(task)
|
||||
self.assertTrue(GlanceImageService_mock.called)
|
||||
self.assertTrue(install_bootloader_mock.called)
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node,
|
||||
root_uuid='rootfs',
|
||||
efi_system_part_uuid=None,
|
||||
prep_boot_part_uuid=None,
|
||||
target_boot_mode='bios',
|
||||
software_raid=True)
|
||||
try_set_boot_device_mock.assert_called_once_with(
|
||||
task, boot_devices.DISK, persistent=True)
|
||||
|
||||
@mock.patch.object(image_service, 'GlanceImageService', autospec=True)
|
||||
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
|
||||
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
||||
autospec=True)
|
||||
def test_configure_local_boot_on_software_raid_explicit_uuid(
|
||||
self, install_bootloader_mock, try_set_boot_device_mock,
|
||||
GlanceImageService_mock):
|
||||
with task_manager.acquire(self.context, self.node['uuid'],
|
||||
shared=False) as task:
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||
task.node.instance_info['image_rootfs_uuid'] = 'rootfs'
|
||||
task.node.target_raid_config = {
|
||||
"logical_disks": [
|
||||
{
|
||||
"size_gb": 100,
|
||||
"raid_level": "1",
|
||||
"controller": "software",
|
||||
},
|
||||
{
|
||||
"size_gb": 'MAX',
|
||||
"raid_level": "0",
|
||||
"controller": "software",
|
||||
}
|
||||
]
|
||||
}
|
||||
self.deploy.configure_local_boot(task)
|
||||
self.assertFalse(GlanceImageService_mock.called)
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node,
|
||||
root_uuid='rootfs',
|
||||
efi_system_part_uuid=None,
|
||||
prep_boot_part_uuid=None,
|
||||
target_boot_mode='bios',
|
||||
software_raid=True)
|
||||
try_set_boot_device_mock.assert_called_once_with(
|
||||
task, boot_devices.DISK, persistent=True)
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
When deploying a node with software RAID with an image not from Glance,
|
||||
the new ``instance_info`` field ``image_rootfs_uuid`` can be used to
|
||||
specify the UUID of the root partition to install the bootloader on.
|
Loading…
Reference in New Issue
Block a user