Fix volume upload-to-image for vhd disk-format
It was previously assumed that glance did not support qed disk-format. qemu-img still uses the legacy 'vpc' format name as a parameter. When executing 'qemu-img convert', vhd was being passed as a parameter which is invalid. This fix adds 'vhd' to the valid disk formats and passes 'vpc' to 'qemu-img convert', which is correct use of the command. Also added 'vhdx' to the valid disk formats. Change-Id: I24e6b78505a2c77b309c79ef11466c08bad1c50a Closes-Bug: #1585612
This commit is contained in:
parent
c47d38dc94
commit
e815f56bd5
@ -56,10 +56,10 @@ CONF.register_opts(image_helper_opts)
|
||||
|
||||
|
||||
# NOTE(abhishekk): qemu-img convert command supports raw, qcow2, qed,
|
||||
# vdi, vmdk and vhd disk-formats but glance doesn't support qed and
|
||||
# vhd(vpc) disk-formats.
|
||||
# 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')
|
||||
VALID_DISK_FORMATS = ('raw', 'vmdk', 'vdi', 'qcow2', 'vhd', 'vhdx')
|
||||
|
||||
|
||||
def validate_disk_format(disk_format):
|
||||
@ -395,15 +395,20 @@ def upload_volume(context, image_service, image_meta, volume_path,
|
||||
reason=_("fmt=%(fmt)s backed by:%(backing_file)s")
|
||||
% {'fmt': fmt, 'backing_file': backing_file})
|
||||
|
||||
convert_image(volume_path, tmp, image_meta['disk_format'],
|
||||
out_format = image_meta['disk_format']
|
||||
# qemu-img accepts 'vpc' as argument for vhd format
|
||||
if out_format == 'vhd':
|
||||
out_format = 'vpc'
|
||||
|
||||
convert_image(volume_path, tmp, out_format,
|
||||
run_as_root=run_as_root)
|
||||
|
||||
data = qemu_img_info(tmp, run_as_root=run_as_root)
|
||||
if data.file_format != image_meta['disk_format']:
|
||||
if data.file_format != out_format:
|
||||
raise exception.ImageUnacceptable(
|
||||
image_id=image_id,
|
||||
reason=_("Converted to %(f1)s, but format is now %(f2)s") %
|
||||
{'f1': image_meta['disk_format'], 'f2': data.file_format})
|
||||
{'f1': out_format, 'f2': data.file_format})
|
||||
|
||||
with open(tmp, 'rb') as image_file:
|
||||
image_service.update(context, image_id, {}, image_file)
|
||||
|
@ -1304,3 +1304,49 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
expected['os-volume_upload_image'].update(visibility='public',
|
||||
protected=True)
|
||||
self.assertDictMatch(expected, res_dict)
|
||||
|
||||
@mock.patch.object(volume_api.API, "get_volume_image_metadata")
|
||||
@mock.patch.object(glance.GlanceImageService, "create")
|
||||
@mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image")
|
||||
def test_copy_volume_to_image_vhd(
|
||||
self, mock_copy_to_image, mock_create, mock_get_image_metadata):
|
||||
"""Test create image from volume with vhd disk format"""
|
||||
volume, expected = self._create_volume_with_type()
|
||||
mock_get_image_metadata.return_value = {}
|
||||
mock_create.side_effect = self.fake_image_service_create
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fakeproject/volumes/%s/action' % volume.id)
|
||||
body = self._get_os_volume_upload_image()
|
||||
body['os-volume_upload_image']['force'] = True
|
||||
body['os-volume_upload_image']['container_format'] = 'bare'
|
||||
body['os-volume_upload_image']['disk_format'] = 'vhd'
|
||||
|
||||
res_dict = self.controller._volume_upload_image(req, volume.id, body)
|
||||
|
||||
self.assertDictMatch(expected, res_dict)
|
||||
vol_db = objects.Volume.get_by_id(self.context, volume.id)
|
||||
self.assertEqual('uploading', vol_db.status)
|
||||
self.assertEqual('available', vol_db.previous_status)
|
||||
|
||||
@mock.patch.object(volume_api.API, "get_volume_image_metadata")
|
||||
@mock.patch.object(glance.GlanceImageService, "create")
|
||||
@mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image")
|
||||
def test_copy_volume_to_image_vhdx(
|
||||
self, mock_copy_to_image, mock_create, mock_get_image_metadata):
|
||||
"""Test create image from volume with vhdx disk format"""
|
||||
volume, expected = self._create_volume_with_type()
|
||||
mock_get_image_metadata.return_value = {}
|
||||
mock_create.side_effect = self.fake_image_service_create
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fakeproject/volumes/%s/action' % volume.id)
|
||||
body = self._get_os_volume_upload_image()
|
||||
body['os-volume_upload_image']['force'] = True
|
||||
body['os-volume_upload_image']['container_format'] = 'bare'
|
||||
body['os-volume_upload_image']['disk_format'] = 'vhdx'
|
||||
|
||||
res_dict = self.controller._volume_upload_image(req, volume.id, body)
|
||||
|
||||
self.assertDictMatch(expected, res_dict)
|
||||
vol_db = objects.Volume.get_by_id(self.context, volume.id)
|
||||
self.assertEqual('uploading', vol_db.status)
|
||||
self.assertEqual('available', vol_db.previous_status)
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Added support for vhd and vhdx disk-formats for volume upload-to-image.
|
Loading…
x
Reference in New Issue
Block a user