Merge "Fix image download to volume for iso images"

This commit is contained in:
Jenkins 2017-07-31 15:01:52 +00:00 committed by Gerrit Code Review
commit 672e02d3f7
2 changed files with 61 additions and 9 deletions

View File

@ -60,18 +60,26 @@ QEMU_IMG_LIMITS = processutils.ProcessLimits(
cpu_time=8,
address_space=1 * units.Gi)
# NOTE(abhishekk): qemu-img convert command supports raw, qcow2, qed,
# vdi, vmdk, vhd and vhdx disk-formats but glance doesn't support qed
# disk-format.
# Ref: http://docs.openstack.org/image-guide/convert-images.html
VALID_DISK_FORMATS = ('raw', 'vmdk', 'vdi', 'qcow2',
'vhd', 'vhdx', 'parallels')
QEMU_IMG_FORMAT_MAP = {
# Convert formats of Glance images to how they are processed with qemu-img.
'iso': 'raw',
'vhd': 'vpc',
}
def validate_disk_format(disk_format):
return disk_format in VALID_DISK_FORMATS
def fixup_disk_format(disk_format):
"""Return the format to be provided to qemu-img convert."""
return QEMU_IMG_FORMAT_MAP.get(disk_format, disk_format)
def qemu_img_info(path, run_as_root=True):
"""Return an object containing the parsed output from qemu-img info."""
cmd = ['env', 'LC_ALL=C', 'qemu-img', 'info', path]
@ -411,11 +419,8 @@ def fetch_to_volume_format(context, image_service,
# image and not a different format with a backing file, which may be
# malicious.
LOG.debug("%s was %s, converting to %s ", image_id, fmt, volume_format)
if image_meta['disk_format'] == 'vhd':
# qemu-img still uses the legacy 'vpc' name for vhd format.
disk_format = 'vpc'
else:
disk_format = image_meta['disk_format']
disk_format = fixup_disk_format(image_meta['disk_format'])
convert_image(tmp, dest, volume_format,
src_format=disk_format,
run_as_root=run_as_root)

View File

@ -825,6 +825,53 @@ class TestFetchToVolumeFormat(test.TestCase):
run_as_root=run_as_root,
src_format=expect_format)
@mock.patch('cinder.image.image_utils.check_available_space')
@mock.patch('cinder.image.image_utils.convert_image')
@mock.patch('cinder.image.image_utils.volume_utils.copy_volume')
@mock.patch('cinder.image.image_utils.is_xenserver_format',
return_value=False)
@mock.patch('cinder.image.image_utils.fetch')
@mock.patch('cinder.image.image_utils.qemu_img_info')
@mock.patch('cinder.image.image_utils.temporary_file')
@mock.patch('cinder.image.image_utils.CONF')
def test_convert_from_iso(self, mock_conf, mock_temp, mock_info,
mock_fetch, mock_is_xen, mock_copy,
mock_convert, mock_check_space):
ctxt = mock.sentinel.context
image_id = mock.sentinel.image_id
dest = mock.sentinel.dest
volume_format = mock.sentinel.volume_format
blocksize = mock.sentinel.blocksize
ctxt.user_id = user_id = mock.sentinel.user_id
project_id = mock.sentinel.project_id
size = 4321
run_as_root = mock.sentinel.run_as_root
data = mock_info.return_value
data.file_format = volume_format
data.backing_file = None
data.virtual_size = 1234
tmp = mock_temp.return_value.__enter__.return_value
image_service = FakeImageService(disk_format='iso')
expect_format = 'raw'
output = image_utils.fetch_to_volume_format(
ctxt, image_service, image_id, dest, volume_format, blocksize,
user_id=user_id, project_id=project_id, size=size,
run_as_root=run_as_root)
self.assertIsNone(output)
mock_temp.assert_called_once_with()
mock_info.assert_has_calls([
mock.call(tmp, run_as_root=run_as_root),
mock.call(tmp, run_as_root=run_as_root)])
mock_fetch.assert_called_once_with(ctxt, image_service, image_id,
tmp, user_id, project_id)
self.assertFalse(mock_copy.called)
mock_convert.assert_called_once_with(tmp, dest, volume_format,
run_as_root=run_as_root,
src_format=expect_format)
@mock.patch('cinder.image.image_utils.check_available_space',
new=mock.Mock())
@mock.patch('cinder.image.image_utils.is_xenserver_format',