libvirt: Use oslo.utils >= 4.1.0 to fetch format-specific image data
This change is a follow up to I0c3f14100a18107f7e416293f3d4fcc641ce5e55 and removes the direct call to nova.privsep.qemu with one to the images API that now returns an oslo_utils.imageutils.QemuImgInfo object. Version 4.1.0 of oslo.utils introducing support for the format-specific data returned by qemu-img info for LUKSv1 based images. Change-Id: I573396116e10cf87f80f1ded55f2cd8f498859e4
This commit is contained in:
parent
961df12393
commit
a486ee6272
|
@ -87,7 +87,7 @@ oslo.rootwrap==5.8.0
|
|||
oslo.serialization==2.21.1
|
||||
oslo.service==1.40.1
|
||||
oslo.upgradecheck==0.1.1
|
||||
oslo.utils==3.40.2
|
||||
oslo.utils==4.1.0
|
||||
oslo.versionedobjects==1.35.0
|
||||
oslo.vmware==2.17.0
|
||||
oslotest==3.8.0
|
||||
|
|
|
@ -9223,7 +9223,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
block_device.resize.assert_not_called()
|
||||
|
||||
@mock.patch('os_brick.encryptors.get_encryption_metadata')
|
||||
@mock.patch('nova.privsep.qemu.privileged_qemu_img_info')
|
||||
@mock.patch('nova.virt.images.privileged_qemu_img_info')
|
||||
def test_extend_volume_luksv1_DiskNotFound(self, mock_qemu_img_info,
|
||||
mock_get_encryption_metadata):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
|
@ -9261,7 +9261,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
block_device.resize.assert_not_called()
|
||||
|
||||
@mock.patch('os_brick.encryptors.get_encryption_metadata')
|
||||
@mock.patch('nova.privsep.qemu.privileged_qemu_img_info')
|
||||
@mock.patch('nova.virt.images.privileged_qemu_img_info')
|
||||
def test_extend_volume_luksv1_block(self, mock_qemu_img_info,
|
||||
mock_get_encryption_metadata):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
|
@ -9279,9 +9279,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
guest.get_block_device.return_value = block_device
|
||||
guest.get_power_state.return_value = power_state.RUNNING
|
||||
|
||||
conn = mock.Mock()
|
||||
conn.getVersion = mock.Mock(return_value=mock.sentinel.qemu_version)
|
||||
|
||||
# The requested_size is provided to extend_volume in bytes.
|
||||
new_size = 20 * units.Gi
|
||||
# The LUKSv1 payload offset as reported by qemu-img info in bytes.
|
||||
|
@ -9289,13 +9286,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
# The new size is provided to Libvirt virDomainBlockResize in units.Ki.
|
||||
new_size_minus_offset_kb = (new_size - payload_offset) // units.Ki
|
||||
|
||||
drvr._host.get_connection = mock.Mock(return_value=conn)
|
||||
drvr._host.get_guest = mock.Mock(return_value=guest)
|
||||
drvr._extend_volume = mock.Mock(return_value=new_size)
|
||||
|
||||
info_dict = {
|
||||
'format-specific': {'data': {'payload-offset': payload_offset}}}
|
||||
mock_qemu_img_info.return_value = jsonutils.dumps(info_dict)
|
||||
mock_qemu_img_info.return_value = mock.Mock(
|
||||
format_specific={'data': {'payload-offset': payload_offset}})
|
||||
mock_get_encryption_metadata.return_value = {
|
||||
'provider': 'luks',
|
||||
'control_location': 'front-end'}
|
||||
|
@ -9311,15 +9306,14 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
mock_get_encryption_metadata.assert_called_once_with(
|
||||
self.context, drvr._volume_api, uuids.volume_id, connection_info)
|
||||
mock_qemu_img_info.assert_called_once_with(
|
||||
mock.sentinel.device_path, output_format='json',
|
||||
qemu_version=mock.sentinel.qemu_version)
|
||||
mock.sentinel.device_path, output_format='json')
|
||||
|
||||
# Assert that the Libvirt call to resize the device within the instance
|
||||
# is called with the LUKSv1 payload offset taken into account.
|
||||
block_device.resize.assert_called_once_with(new_size_minus_offset_kb)
|
||||
|
||||
@mock.patch('os_brick.encryptors.get_encryption_metadata')
|
||||
@mock.patch('nova.privsep.qemu.privileged_qemu_img_info')
|
||||
@mock.patch('nova.virt.images.privileged_qemu_img_info')
|
||||
def test_extend_volume_luksv1_rbd(self, mock_qemu_img_info,
|
||||
mock_get_encryption_metadata):
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
|
@ -9343,9 +9337,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
guest.get_power_state.return_value = power_state.RUNNING
|
||||
guest.get_all_disks.return_value = [disk_1, disk_2]
|
||||
|
||||
conn = mock.Mock()
|
||||
conn.getVersion = mock.Mock(return_value=mock.sentinel.qemu_version)
|
||||
|
||||
# The requested_size is provided to extend_volume in bytes.
|
||||
new_size = 20 * units.Gi
|
||||
# The LUKSv1 payload offset as reported by qemu-img info in bytes.
|
||||
|
@ -9353,13 +9344,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
# The new size is provided to Libvirt virDomainBlockResize in units.Ki.
|
||||
new_size_minus_offset_kb = (new_size - payload_offset) // units.Ki
|
||||
|
||||
drvr._host.get_connection = mock.Mock(return_value=conn)
|
||||
drvr._host.get_guest = mock.Mock(return_value=guest)
|
||||
drvr._extend_volume = mock.Mock(return_value=new_size)
|
||||
|
||||
info_dict = {
|
||||
'format-specific': {'data': {'payload-offset': payload_offset}}}
|
||||
mock_qemu_img_info.return_value = jsonutils.dumps(info_dict)
|
||||
mock_qemu_img_info.return_value = mock.Mock(
|
||||
format_specific={'data': {'payload-offset': payload_offset}})
|
||||
mock_get_encryption_metadata.return_value = {
|
||||
'provider': 'luks',
|
||||
'control_location': 'front-end'}
|
||||
|
@ -9375,8 +9364,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
mock_get_encryption_metadata.assert_called_once_with(
|
||||
self.context, drvr._volume_api, uuids.volume_id, connection_info)
|
||||
mock_qemu_img_info.assert_called_once_with(
|
||||
'rbd:pool/volume', output_format='json',
|
||||
qemu_version=mock.sentinel.qemu_version)
|
||||
'rbd:pool/volume', output_format='json')
|
||||
|
||||
# Assert that the Libvirt call to resize the device within the instance
|
||||
# is called with the LUKSv1 payload offset taken into account.
|
||||
|
|
|
@ -59,6 +59,22 @@ def qemu_img_info(path, format=None, output_format=None):
|
|||
return imageutils.QemuImgInfo(info)
|
||||
|
||||
|
||||
def privileged_qemu_img_info(path, format=None, output_format=None):
|
||||
"""Return an object containing the parsed output from qemu-img info."""
|
||||
# TODO(mikal): this code should not be referring to a libvirt specific
|
||||
# flag.
|
||||
if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
|
||||
raise exception.DiskNotFound(location=path)
|
||||
|
||||
info = nova.privsep.qemu.privileged_qemu_img_info(
|
||||
path, format=format, qemu_version=QEMU_VERSION,
|
||||
output_format=output_format)
|
||||
if output_format:
|
||||
return imageutils.QemuImgInfo(info, format=output_format)
|
||||
else:
|
||||
return imageutils.QemuImgInfo(info)
|
||||
|
||||
|
||||
def convert_image(source, dest, in_format, out_format, run_as_root=False,
|
||||
compress=False):
|
||||
"""Convert image to other format."""
|
||||
|
|
|
@ -1956,22 +1956,9 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
path = 'unknown'
|
||||
raise exception.DiskNotFound(location='unknown')
|
||||
|
||||
# TODO(lyarwood): The following direct call to privsep instead
|
||||
# of images.qemu_img_info avoids the need to bump
|
||||
# requirements.txt to depend on a new version of oslo.utils
|
||||
# that provides a version of QemuImgInfo that includes the
|
||||
# format_specific attribute allowing this bugfix to be
|
||||
# backported. Once landed we can replace this with the
|
||||
# following and require oslo.utils >= 4.1.0:
|
||||
#
|
||||
# info = images.qemu_img_info(path, output_format='json',
|
||||
# run_as_root=True)
|
||||
# format_specific_data = info.format_specific['data']
|
||||
info_dict = nova.privsep.qemu.privileged_qemu_img_info(
|
||||
path, output_format='json',
|
||||
qemu_version=self._host.get_connection().getVersion())
|
||||
info = jsonutils.loads(info_dict)
|
||||
format_specific_data = info['format-specific']['data']
|
||||
info = images.privileged_qemu_img_info(
|
||||
path, output_format='json')
|
||||
format_specific_data = info.format_specific['data']
|
||||
payload_offset = format_specific_data['payload-offset']
|
||||
|
||||
# NOTE(lyarwood): Ensure the underlying device is not resized
|
||||
|
|
|
@ -41,7 +41,7 @@ oslo.log>=3.36.0 # Apache-2.0
|
|||
oslo.reports>=1.18.0 # Apache-2.0
|
||||
oslo.serialization!=2.19.1,>=2.21.1 # Apache-2.0
|
||||
oslo.upgradecheck>=0.1.1
|
||||
oslo.utils>=3.40.2 # Apache-2.0
|
||||
oslo.utils>=4.1.0 # Apache-2.0
|
||||
oslo.db>=4.44.0 # Apache-2.0
|
||||
oslo.rootwrap>=5.8.0 # Apache-2.0
|
||||
oslo.messaging>=10.3.0 # Apache-2.0
|
||||
|
|
Loading…
Reference in New Issue