From 521d51b985babca8ba8dd5e2c29049fee4f60ad4 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Mon, 16 Feb 2015 19:43:17 +0200 Subject: [PATCH] Fix fetch_to_volume_format if vhd is requested qemu-img still uses the legacy 'vpc' format name. If the caller requests a vhd image, the format check would raise an exception. This patch adds an extra check to prevent this issue. Change-Id: Ie72c0a79c08e8b7eefbd1534e45bc46f91ace96e Partially-implements: blueprint bp/image-caching-support --- cinder/image/image_utils.py | 12 ++++++++- cinder/tests/unit/test_image_utils.py | 37 +++++++++++++++++++-------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py index 6e5e2fb19..34fddc402 100644 --- a/cinder/image/image_utils.py +++ b/cinder/image/image_utils.py @@ -317,7 +317,8 @@ def fetch_to_volume_format(context, image_service, run_as_root=run_as_root) data = qemu_img_info(dest, run_as_root=run_as_root) - if data.file_format != volume_format: + + if not _validate_file_format(data, volume_format): raise exception.ImageUnacceptable( image_id=image_id, reason=_("Converted to %(vol_format)s, but format is " @@ -326,6 +327,15 @@ def fetch_to_volume_format(context, image_service, file_format}) +def _validate_file_format(image_data, expected_format): + if image_data.file_format == expected_format: + return True + elif image_data.file_format == 'vpc' and expected_format == 'vhd': + # qemu-img still uses the legacy 'vpc' name for the vhd format. + return True + return False + + def upload_volume(context, image_service, image_meta, volume_path, volume_format='raw', run_as_root=True): image_id = image_meta['id'] diff --git a/cinder/tests/unit/test_image_utils.py b/cinder/tests/unit/test_image_utils.py index ab4124383..3eea79edd 100644 --- a/cinder/tests/unit/test_image_utils.py +++ b/cinder/tests/unit/test_image_utils.py @@ -937,14 +937,15 @@ class TestFetchToVolumeFormat(test.TestCase): @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_format_mismatch(self, mock_conf, mock_temp, mock_info, mock_fetch, - mock_is_xen, mock_repl_xen, mock_copy, - mock_convert): + def _test_format_name_mismatch(self, mock_conf, mock_temp, mock_info, + mock_fetch, mock_is_xen, mock_repl_xen, + mock_copy, mock_convert, + legacy_format_name=False): ctxt = mock.sentinel.context image_service = mock.Mock() image_id = mock.sentinel.image_id dest = mock.sentinel.dest - volume_format = mock.sentinel.volume_format + volume_format = 'vhd' blocksize = mock.sentinel.blocksize user_id = mock.sentinel.user_id project_id = mock.sentinel.project_id @@ -952,17 +953,23 @@ class TestFetchToVolumeFormat(test.TestCase): run_as_root = mock.sentinel.run_as_root data = mock_info.return_value - data.file_format = mock.sentinel.file_format + data.file_format = 'vpc' if legacy_format_name else 'raw' data.backing_file = None data.virtual_size = 1234 tmp = mock_temp.return_value.__enter__.return_value - self.assertRaises( - exception.ImageUnacceptable, - 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) + if legacy_format_name: + 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) + else: + self.assertRaises( + exception.ImageUnacceptable, + 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) image_service.show.assert_called_once_with(ctxt, image_id) mock_temp.assert_called_once_with() @@ -977,6 +984,14 @@ class TestFetchToVolumeFormat(test.TestCase): mock_convert.assert_called_once_with(tmp, dest, volume_format, run_as_root=run_as_root) + def test_format_mismatch(self): + self._test_format_name_mismatch() + + def test_format_name_mismatch_same_format(self): + # Make sure no exception is raised because of qemu-img still using + # the legacy 'vpc' format name if 'vhd' is requested. + self._test_format_name_mismatch(legacy_format_name=True) + @mock.patch('cinder.image.image_utils.convert_image') @mock.patch('cinder.image.image_utils.volume_utils.copy_volume') @mock.patch( -- 2.45.2