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``.
|
* ``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
|
Deployment
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -1333,6 +1333,8 @@ class AgentDeployMixin(HeartbeatMixin, AgentOobStepsMixin):
|
|||||||
# image's metadata (via Glance). Fall back to the driver internal
|
# 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).
|
# info in case it is not available (e.g. not set or there's no Glance).
|
||||||
if software_raid:
|
if software_raid:
|
||||||
|
root_uuid = node.instance_info.get('image_rootfs_uuid')
|
||||||
|
if not root_uuid:
|
||||||
image_source = node.instance_info.get('image_source')
|
image_source = node.instance_info.get('image_source')
|
||||||
try:
|
try:
|
||||||
context = task.context
|
context = task.context
|
||||||
@ -1345,7 +1347,8 @@ class AgentDeployMixin(HeartbeatMixin, AgentOobStepsMixin):
|
|||||||
LOG.debug('Got rootfs_uuid from Glance: %s '
|
LOG.debug('Got rootfs_uuid from Glance: %s '
|
||||||
'(node %s)', root_uuid, node.uuid)
|
'(node %s)', root_uuid, node.uuid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.warning('Could not get \'rootfs_uuid\' property for '
|
LOG.warning(
|
||||||
|
'Could not get \'rootfs_uuid\' property for '
|
||||||
'image %(image)s from Glance for node %(node)s. '
|
'image %(image)s from Glance for node %(node)s. '
|
||||||
'%(cls)s: %(error)s.',
|
'%(cls)s: %(error)s.',
|
||||||
{'image': image_source, 'node': node.uuid,
|
{'image': image_source, 'node': node.uuid,
|
||||||
|
@ -1317,6 +1317,8 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
|||||||
def test_configure_local_boot_on_software_raid(
|
def test_configure_local_boot_on_software_raid(
|
||||||
self, install_bootloader_mock, try_set_boot_device_mock,
|
self, install_bootloader_mock, try_set_boot_device_mock,
|
||||||
GlanceImageService_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'],
|
with task_manager.acquire(self.context, self.node['uuid'],
|
||||||
shared=False) as task:
|
shared=False) as task:
|
||||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||||
@ -1336,7 +1338,50 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
|||||||
}
|
}
|
||||||
self.deploy.configure_local_boot(task)
|
self.deploy.configure_local_boot(task)
|
||||||
self.assertTrue(GlanceImageService_mock.called)
|
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(
|
try_set_boot_device_mock.assert_called_once_with(
|
||||||
task, boot_devices.DISK, persistent=True)
|
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