From 6e287c0f2bb7d4994d50f1763f412277e4dac6f7 Mon Sep 17 00:00:00 2001 From: Xavier Queralt Date: Tue, 22 Oct 2013 20:37:53 +0200 Subject: [PATCH] Fail when image is bigger than the volume When creating a new volume from a qcow2 image stored in glance, we will be given the physical size of the image instead of the virtual size. Most drivers will convert that image to raw after downloading for resizing it to the requested volume size afterwards. If the virtual size of the image is bigger than the requested one, the resulting volume might end up being unusable after the resize even though the creation went good. This patch will make the volume creation fail if the virtual size of the image exceeds the one of the requested volume. Closes-Bug: #1235358 Change-Id: I254cd9e3acf5d9eb7eb913b37d27a14e97568dec --- cinder/image/image_utils.py | 36 +++- cinder/tests/test_block_device.py | 4 +- cinder/tests/test_coraid.py | 3 +- cinder/tests/test_image_utils.py | 288 +++++++++++--------------- cinder/tests/test_nfs.py | 3 +- cinder/tests/test_rbd.py | 6 +- cinder/tests/test_scality.py | 3 +- cinder/tests/test_volume.py | 2 +- cinder/volume/driver.py | 3 +- cinder/volume/drivers/block_device.py | 3 +- cinder/volume/drivers/gpfs.py | 2 +- cinder/volume/drivers/lvm.py | 2 +- cinder/volume/drivers/nfs.py | 3 +- cinder/volume/drivers/rbd.py | 2 +- cinder/volume/drivers/scality.py | 3 +- 15 files changed, 178 insertions(+), 185 deletions(-) diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py index 7ce3c1768..f853f75be 100644 --- a/cinder/image/image_utils.py +++ b/cinder/image/image_utils.py @@ -37,7 +37,7 @@ from cinder.openstack.common import fileutils from cinder.openstack.common import imageutils from cinder.openstack.common import log as logging from cinder.openstack.common import processutils -from cinder.openstack.common import strutils +from cinder import units from cinder import utils from cinder.volume import utils as volume_utils @@ -84,7 +84,7 @@ def fetch(context, image_service, image_id, path, _user_id, _project_id): def fetch_verify_image(context, image_service, image_id, dest, - user_id=None, project_id=None): + user_id=None, project_id=None, size=None): fetch(context, image_service, image_id, dest, None, None) @@ -103,6 +103,15 @@ def fetch_verify_image(context, image_service, image_id, dest, reason=(_("fmt=%(fmt)s backed by: %(backing_file)s") % {'fmt': fmt, 'backing_file': backing_file})) + # NOTE(xqueralt): If the image virtual size doesn't fit in the + # requested volume there is no point on resizing it because it will + # generate an unusable image. + if size is not None and data.virtual_size > size: + params = {'image_size': data.virtual_size, 'volume_size': size} + reason = _("Size is %(image_size)dGB and doesn't fit in a " + "volume of size %(volume_size)dGB.") % params + raise exception.ImageUnacceptable(image_id=image_id, reason=reason) + def fetch_to_vhd(context, image_service, image_id, dest, @@ -113,19 +122,19 @@ def fetch_to_vhd(context, image_service, def fetch_to_raw(context, image_service, image_id, dest, - user_id=None, project_id=None): + user_id=None, project_id=None, size=None): fetch_to_volume_format(context, image_service, image_id, dest, 'raw', - user_id, project_id) + user_id, project_id, size) def fetch_to_volume_format(context, image_service, image_id, dest, volume_format, - user_id=None, project_id=None): + user_id=None, project_id=None, size=None): if (CONF.image_conversion_dir and not os.path.exists(CONF.image_conversion_dir)): os.makedirs(CONF.image_conversion_dir) - no_qemu_img = False + qemu_img = True image_meta = image_service.show(context, image_id) # NOTE(avishay): I'm not crazy about creating temp files which may be @@ -143,7 +152,7 @@ def fetch_to_volume_format(context, image_service, # Use the empty tmp file to make sure qemu_img_info works. qemu_img_info(tmp) except processutils.ProcessExecutionError: - no_qemu_img = True + qemu_img = False if image_meta: if image_meta['disk_format'] != 'raw': raise exception.ImageUnacceptable( @@ -164,7 +173,7 @@ def fetch_to_volume_format(context, image_service, if is_xenserver_image(context, image_service, image_id): replace_xenserver_image_with_coalesced_vhd(tmp) - if no_qemu_img: + if not qemu_img: # qemu-img is not installed but we do have a RAW image. As a # result we only need to copy the image to the destination and then # return. @@ -175,6 +184,17 @@ def fetch_to_volume_format(context, image_service, return data = qemu_img_info(tmp) + virt_size = data.virtual_size / units.GiB + + # NOTE(xqueralt): If the image virtual size doesn't fit in the + # requested volume there is no point on resizing it because it will + # generate an unusable image. + if size is not None and virt_size > size: + params = {'image_size': virt_size, 'volume_size': size} + reason = _("Size is %(image_size)dGB and doesn't fit in a " + "volume of size %(volume_size)dGB.") % params + raise exception.ImageUnacceptable(image_id=image_id, reason=reason) + fmt = data.file_format if fmt is None: raise exception.ImageUnacceptable( diff --git a/cinder/tests/test_block_device.py b/cinder/tests/test_block_device.py index 2cc0d208c..5a71afe72 100644 --- a/cinder/tests/test_block_device.py +++ b/cinder/tests/test_block_device.py @@ -145,14 +145,14 @@ class TestBlockDeviceDriver(cinder.test.TestCase): 'None None None /dev/loop2'}) def test_copy_image_to_volume(self): - TEST_VOLUME = {'provider_location': '1 2 3 /dev/loop1'} + TEST_VOLUME = {'provider_location': '1 2 3 /dev/loop1', 'size': 1} TEST_IMAGE_SERVICE = "image_service" TEST_IMAGE_ID = "image_id" self.mox.StubOutWithMock(image_utils, 'fetch_to_raw') self.mox.StubOutWithMock(self.drv, 'local_path') self.drv.local_path(TEST_VOLUME).AndReturn('/dev/loop1') image_utils.fetch_to_raw(context, TEST_IMAGE_SERVICE, - TEST_IMAGE_ID, '/dev/loop1') + TEST_IMAGE_ID, '/dev/loop1', size=1) self.mox.ReplayAll() self.drv.copy_image_to_volume(context, TEST_VOLUME, TEST_IMAGE_SERVICE, TEST_IMAGE_ID) diff --git a/cinder/tests/test_coraid.py b/cinder/tests/test_coraid.py index 277ba6ef7..2dd2cecad 100644 --- a/cinder/tests/test_coraid.py +++ b/cinder/tests/test_coraid.py @@ -827,7 +827,8 @@ class CoraidDriverImageTestCases(CoraidDriverTestCase): image_utils.fetch_to_raw({}, fake_image_service, fake_image_id, - self.fake_dev_path) + self.fake_dev_path, + size=fake_volume_size) self.mox.ReplayAll() diff --git a/cinder/tests/test_image_utils.py b/cinder/tests/test_image_utils.py index 174c263ab..def72d4a4 100644 --- a/cinder/tests/test_image_utils.py +++ b/cinder/tests/test_image_utils.py @@ -19,11 +19,11 @@ import contextlib import mox import tempfile -import textwrap from cinder import context from cinder import exception from cinder.image import image_utils +from cinder.openstack.common import processutils from cinder import test from cinder import units from cinder import utils @@ -53,6 +53,8 @@ class TestUtils(test.TestCase): def setUp(self): super(TestUtils, self).setUp() self._mox = mox.Mox() + self._image_service = FakeImageService() + self.addCleanup(self._mox.UnsetStubs) def test_resize_image(self): @@ -191,174 +193,158 @@ class TestUtils(test.TestCase): self.assertEquals(str(inf), TEST_STR) - def test_fetch_to_raw(self): - TEST_RET = "image: qemu.qcow2\n"\ - "file_format: qcow2 \n"\ - "virtual_size: 50M (52428800 bytes)\n"\ - "cluster_size: 65536\n"\ - "disk_size: 196K (200704 bytes)" - TEST_RETURN_RAW = "image: qemu.raw\n"\ - "file_format: raw\n"\ - "virtual_size: 50M (52428800 bytes)\n"\ - "cluster_size: 65536\n"\ - "disk_size: 196K (200704 bytes)\n"\ - - fake_image_service = FakeImageService() + def _test_fetch_to_raw(self, has_qemu=True, src_inf=None, dest_inf=None): mox = self._mox - mox.StubOutWithMock(image_utils, 'create_temporary_file') mox.StubOutWithMock(utils, 'execute') mox.StubOutWithMock(image_utils, 'fetch') - image_utils.create_temporary_file().AndReturn(self.TEST_DEV_PATH) - image_utils.fetch(context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH, None, None) - - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) - - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) + TEST_INFO = ("image: qemu.qcow2\n" + "file format: raw\n" + "virtual size: 0 (0 bytes)\n" + "disk size: 0") - utils.execute('qemu-img', 'convert', '-O', 'raw', - self.TEST_DEV_PATH, self.TEST_DEV_PATH, run_as_root=True) + image_utils.create_temporary_file().AndReturn(self.TEST_DEV_PATH) - utils.execute( + test_qemu_img = utils.execute( 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RETURN_RAW, 'ignored') - ) - - mox.ReplayAll() + self.TEST_DEV_PATH, run_as_root=True) + + if has_qemu: + test_qemu_img.AndReturn((TEST_INFO, 'ignored')) + image_utils.fetch(context, self._image_service, self.TEST_IMAGE_ID, + self.TEST_DEV_PATH, None, None) + else: + test_qemu_img.AndRaise(processutils.ProcessExecutionError()) + + if has_qemu and src_inf: + utils.execute( + 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', + self.TEST_DEV_PATH, run_as_root=True).AndReturn( + (src_inf, 'ignored') + ) + + if has_qemu and dest_inf: + utils.execute( + 'qemu-img', 'convert', '-O', 'raw', + self.TEST_DEV_PATH, self.TEST_DEV_PATH, run_as_root=True) + + utils.execute( + 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', + self.TEST_DEV_PATH, run_as_root=True).AndReturn( + (dest_inf, 'ignored') + ) + + self._mox.ReplayAll() - image_utils.fetch_to_raw(context, fake_image_service, + def test_fetch_to_raw(self): + SRC_INFO = ("image: qemu.qcow2\n" + "file_format: qcow2 \n" + "virtual_size: 50M (52428800 bytes)\n" + "cluster_size: 65536\n" + "disk_size: 196K (200704 bytes)") + DST_INFO = ("image: qemu.raw\n" + "file_format: raw\n" + "virtual_size: 50M (52428800 bytes)\n" + "cluster_size: 65536\n" + "disk_size: 196K (200704 bytes)\n") + + self._test_fetch_to_raw(src_inf=SRC_INFO, dest_inf=DST_INFO) + + image_utils.fetch_to_raw(context, self._image_service, self.TEST_IMAGE_ID, self.TEST_DEV_PATH) - mox.VerifyAll() + self._mox.VerifyAll() - def test_fetch_to_raw_on_error_parsing_failed(self): - TEST_RET = "image: qemu.qcow2\n"\ - "virtual_size: 50M (52428800 bytes)\n"\ - "cluster_size: 65536\n"\ - "disk_size: 196K (200704 bytes)" + def test_fetch_to_raw_no_qemu_img(self): + self._test_fetch_to_raw(has_qemu=False) - fake_image_service = FakeImageService() - mox = self._mox - - mox.StubOutWithMock(image_utils, 'create_temporary_file') - mox.StubOutWithMock(utils, 'execute') - mox.StubOutWithMock(image_utils, 'fetch') - - image_utils.create_temporary_file().AndReturn(self.TEST_DEV_PATH) - image_utils.fetch(context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH, None, None) + self.assertRaises(exception.ImageUnacceptable, + image_utils.fetch_to_raw, + context, self._image_service, + self.TEST_IMAGE_ID, self.TEST_DEV_PATH) - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) + self._mox.VerifyAll() - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) + def test_fetch_to_raw_on_error_parsing_failed(self): + SRC_INFO_NO_FORMAT = ("image: qemu.qcow2\n" + "virtual_size: 50M (52428800 bytes)\n" + "cluster_size: 65536\n" + "disk_size: 196K (200704 bytes)") - mox.ReplayAll() + self._test_fetch_to_raw(src_inf=SRC_INFO_NO_FORMAT) self.assertRaises(exception.ImageUnacceptable, - image_utils.fetch_to_raw, context, - fake_image_service, self.TEST_IMAGE_ID, - self.TEST_DEV_PATH) + image_utils.fetch_to_raw, + context, self._image_service, + self.TEST_IMAGE_ID, self.TEST_DEV_PATH) + self._mox.VerifyAll() def test_fetch_to_raw_on_error_backing_file(self): - TEST_RET = "image: qemu.qcow2\n"\ - "backing_file: qemu.qcow2 (actual path: qemu.qcow2)\n"\ - "file_format: qcow2 \n"\ - "virtual_size: 50M (52428800 bytes)\n"\ - "cluster_size: 65536\n"\ - "disk_size: 196K (200704 bytes)" + SRC_INFO_BACKING_FILE = ("image: qemu.qcow2\n" + "backing_file: qemu.qcow2\n" + "file_format: qcow2 \n" + "virtual_size: 50M (52428800 bytes)\n" + "cluster_size: 65536\n" + "disk_size: 196K (200704 bytes)") - fake_image_service = FakeImageService() - mox = self._mox + self._test_fetch_to_raw(src_inf=SRC_INFO_BACKING_FILE) - mox.StubOutWithMock(image_utils, 'create_temporary_file') - mox.StubOutWithMock(utils, 'execute') - mox.StubOutWithMock(image_utils, 'fetch') - - image_utils.create_temporary_file().AndReturn(self.TEST_DEV_PATH) - image_utils.fetch(context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH, None, None) + self.assertRaises(exception.ImageUnacceptable, + image_utils.fetch_to_raw, + context, self._image_service, + self.TEST_IMAGE_ID, self.TEST_DEV_PATH) + self._mox.VerifyAll() - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) + def test_fetch_to_raw_on_error_not_convert_to_raw(self): + IMG_INFO = ("image: qemu.qcow2\n" + "file_format: qcow2 \n" + "virtual_size: 50M (52428800 bytes)\n" + "cluster_size: 65536\n" + "disk_size: 196K (200704 bytes)") - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) + self._test_fetch_to_raw(src_inf=IMG_INFO, dest_inf=IMG_INFO) - mox.ReplayAll() self.assertRaises(exception.ImageUnacceptable, image_utils.fetch_to_raw, - context, fake_image_service, + context, self._image_service, self.TEST_IMAGE_ID, self.TEST_DEV_PATH) - def test_fetch_to_raw_on_error_not_convert_to_raw(self): - TEST_RET = "image: qemu.qcow2\n"\ - "file_format: qcow2 \n"\ - "virtual_size: 50M (52428800 bytes)\n"\ - "cluster_size: 65536\n"\ - "disk_size: 196K (200704 bytes)" + def test_fetch_to_raw_on_error_image_size(self): + TEST_VOLUME_SIZE = 1 + SRC_INFO = ("image: qemu.qcow2\n" + "file_format: qcow2 \n" + "virtual_size: 2G (2147483648 bytes)\n" + "cluster_size: 65536\n" + "disk_size: 196K (200704 bytes)") + self._test_fetch_to_raw(src_inf=SRC_INFO) + + self.assertRaises(exception.ImageUnacceptable, + image_utils.fetch_to_raw, + context, self._image_service, + self.TEST_IMAGE_ID, self.TEST_DEV_PATH, + size=TEST_VOLUME_SIZE) + + def _test_fetch_verify_image(self, qemu_info, volume_size=1): fake_image_service = FakeImageService() mox = self._mox - - mox.StubOutWithMock(image_utils, 'create_temporary_file') - mox.StubOutWithMock(utils, 'execute') mox.StubOutWithMock(image_utils, 'fetch') - - image_utils.create_temporary_file().AndReturn(self.TEST_DEV_PATH) + mox.StubOutWithMock(utils, 'execute') image_utils.fetch(context, fake_image_service, self.TEST_IMAGE_ID, self.TEST_DEV_PATH, None, None) utils.execute( 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') + (qemu_info, 'ignored') ) - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) - - utils.execute('qemu-img', 'convert', '-O', 'raw', - self.TEST_DEV_PATH, self.TEST_DEV_PATH, run_as_root=True) - - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RET, 'ignored') - ) - - mox.ReplayAll() - + self._mox.ReplayAll() self.assertRaises(exception.ImageUnacceptable, - image_utils.fetch_to_raw, + image_utils.fetch_verify_image, context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH) + self.TEST_IMAGE_ID, self.TEST_DEV_PATH, + size=volume_size) def test_fetch_verify_image_with_backing_file(self): TEST_RETURN = "image: qemu.qcow2\n"\ @@ -371,25 +357,7 @@ class TestUtils(test.TestCase): "ID TAG VM SIZE DATE VM CLOCK\n"\ "1 snap1 1.7G 2011-10-04 19:04:00 32:06:34.974" - fake_image_service = FakeImageService() - mox = self._mox - mox.StubOutWithMock(image_utils, 'fetch') - mox.StubOutWithMock(utils, 'execute') - image_utils.fetch(context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH, None, None) - - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RETURN, 'ignored') - ) - - mox.ReplayAll() - - self.assertRaises(exception.ImageUnacceptable, - image_utils.fetch_verify_image, - context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH) + self._test_fetch_verify_image(TEST_RETURN) def test_fetch_verify_image_without_file_format(self): TEST_RETURN = "image: qemu.qcow2\n"\ @@ -400,25 +368,19 @@ class TestUtils(test.TestCase): "ID TAG VM SIZE DATE VM CLOCK\n"\ "1 snap1 1.7G 2011-10-04 19:04:00 32:06:34.974" - fake_image_service = FakeImageService() - mox = self._mox - mox.StubOutWithMock(image_utils, 'fetch') - mox.StubOutWithMock(utils, 'execute') - image_utils.fetch(context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH, None, None) + self._test_fetch_verify_image(TEST_RETURN) - utils.execute( - 'env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', - self.TEST_DEV_PATH, run_as_root=True).AndReturn( - (TEST_RETURN, 'ignored') - ) - - mox.ReplayAll() + def test_fetch_verify_image_image_size(self): + TEST_RETURN = "image: qemu.qcow2\n"\ + "file_format: qcow2\n"\ + "virtual_size: 2G (2147483648 bytes)\n"\ + "cluster_size: 65536\n"\ + "disk_size: 196K (200704 bytes)\n"\ + "Snapshot list:\n"\ + "ID TAG VM SIZE DATE VM CLOCK\n"\ + "1 snap1 1.7G 2011-10-04 19:04:00 32:06:34.974" - self.assertRaises(exception.ImageUnacceptable, - image_utils.fetch_verify_image, - context, fake_image_service, - self.TEST_IMAGE_ID, self.TEST_DEV_PATH) + self._test_fetch_verify_image(TEST_RETURN) def test_upload_volume(self): image_meta = {'id': 1, 'disk_format': 'qcow2'} diff --git a/cinder/tests/test_nfs.py b/cinder/tests/test_nfs.py index 993f35d17..7ce00e1b3 100644 --- a/cinder/tests/test_nfs.py +++ b/cinder/tests/test_nfs.py @@ -175,7 +175,8 @@ class NfsDriverTestCase(test.TestCase): self.stubs.Set(drv, 'local_path', fake_local_path) mox.StubOutWithMock(image_utils, 'fetch_to_raw') - image_utils.fetch_to_raw(None, None, None, TEST_IMG_SOURCE) + image_utils.fetch_to_raw(None, None, None, TEST_IMG_SOURCE, + size=self.TEST_SIZE_IN_GB) mox.StubOutWithMock(image_utils, 'resize_image') image_utils.resize_image(TEST_IMG_SOURCE, self.TEST_SIZE_IN_GB) diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py index 33fc0630e..97ca7fd76 100644 --- a/cinder/tests/test_rbd.py +++ b/cinder/tests/test_rbd.py @@ -293,9 +293,13 @@ class RBDTestCase(test.TestCase): def __init__(self, name): self.name = name yield FakeTmp('test') + + def fake_fetch_to_raw(ctx, image_service, image_id, path, size=None): + pass + self.stubs.Set(tempfile, 'NamedTemporaryFile', fake_temp_file) self.stubs.Set(os.path, 'exists', lambda x: True) - self.stubs.Set(image_utils, 'fetch_to_raw', lambda w, x, y, z: None) + self.stubs.Set(image_utils, 'fetch_to_raw', fake_fetch_to_raw) self.stubs.Set(self.driver, 'delete_volume', lambda x: None) self.stubs.Set(self.driver, '_resize', lambda x: None) self.driver.copy_image_to_volume(None, {'name': 'test', diff --git a/cinder/tests/test_scality.py b/cinder/tests/test_scality.py index 5c4c62d37..f3f9ea8ba 100644 --- a/cinder/tests/test_scality.py +++ b/cinder/tests/test_scality.py @@ -237,7 +237,8 @@ class ScalityDriverTestCase(test.TestCase): image_utils.fetch_to_raw(context, self.TEST_IMAGE_SERVICE, self.TEST_IMAGE_ID, - self.TEST_VOLPATH) + self.TEST_VOLPATH, + size=self.TEST_VOLSIZE) self.mox.ReplayAll() diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py index 86cff8bc5..5017acbc4 100644 --- a/cinder/tests/test_volume.py +++ b/cinder/tests/test_volume.py @@ -1214,7 +1214,7 @@ class VolumeTestCase(BaseVolumeTestCase): image_service, image_id): pass - def fake_fetch_to_raw(context, image_service, image_id, vol_path): + def fake_fetch_to_raw(ctx, image_service, image_id, path, size=None): pass def fake_clone_image(volume_ref, image_location, image_id): diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py index a286b4b3b..98b6fad00 100644 --- a/cinder/volume/driver.py +++ b/cinder/volume/driver.py @@ -337,7 +337,8 @@ class VolumeDriver(object): image_utils.fetch_to_raw(context, image_service, image_id, - attach_info['device']['path']) + attach_info['device']['path'], + size=volume['size']) finally: self._detach_volume(attach_info) self.terminate_connection(volume, properties) diff --git a/cinder/volume/drivers/block_device.py b/cinder/volume/drivers/block_device.py index 76bfcf018..4d0aca280 100644 --- a/cinder/volume/drivers/block_device.py +++ b/cinder/volume/drivers/block_device.py @@ -294,7 +294,8 @@ class BlockDeviceDriver(driver.ISCSIDriver): image_utils.fetch_to_raw(context, image_service, image_id, - self.local_path(volume)) + self.local_path(volume), + size=volume['size']) def copy_volume_to_image(self, context, volume, image_service, image_meta): """Copy the volume to the specified image.""" diff --git a/cinder/volume/drivers/gpfs.py b/cinder/volume/drivers/gpfs.py index 2e5b8119c..13cf89dcb 100644 --- a/cinder/volume/drivers/gpfs.py +++ b/cinder/volume/drivers/gpfs.py @@ -542,7 +542,7 @@ class GPFSDriver(driver.VolumeDriver): LOG.debug('Copy image to vol %s using image_utils fetch_to_raw' % volume['id']) image_utils.fetch_to_raw(context, image_service, image_id, - self.local_path(volume)) + self.local_path(volume), size=volume['size']) image_utils.resize_image(self.local_path(volume), volume['size']) def copy_volume_to_image(self, context, volume, image_service, image_meta): diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py index e1cb9fe0e..cdd5a4c0b 100644 --- a/cinder/volume/drivers/lvm.py +++ b/cinder/volume/drivers/lvm.py @@ -275,7 +275,7 @@ class LVMVolumeDriver(driver.VolumeDriver): image_utils.fetch_to_raw(context, image_service, image_id, - self.local_path(volume)) + self.local_path(volume), size=volume['size']) def copy_volume_to_image(self, context, volume, image_service, image_meta): """Copy the volume to the specified image.""" diff --git a/cinder/volume/drivers/nfs.py b/cinder/volume/drivers/nfs.py index 277b173a6..c92335b81 100644 --- a/cinder/volume/drivers/nfs.py +++ b/cinder/volume/drivers/nfs.py @@ -227,7 +227,8 @@ class RemoteFsDriver(driver.VolumeDriver): image_utils.fetch_to_raw(context, image_service, image_id, - self.local_path(volume)) + self.local_path(volume), + size=volume['size']) # NOTE (leseb): Set the virtual size of the image # the raw conversion overwrote the destination file diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py index 0ab857c3a..ea75f74a8 100644 --- a/cinder/volume/drivers/rbd.py +++ b/cinder/volume/drivers/rbd.py @@ -743,7 +743,7 @@ class RBDDriver(driver.VolumeDriver): with tempfile.NamedTemporaryFile(dir=tmp_dir) as tmp: image_utils.fetch_to_raw(context, image_service, image_id, - tmp.name) + tmp.name, size=volume['size']) self.delete_volume(volume) diff --git a/cinder/volume/drivers/scality.py b/cinder/volume/drivers/scality.py index 0d2d0d37c..4cf49c6b7 100644 --- a/cinder/volume/drivers/scality.py +++ b/cinder/volume/drivers/scality.py @@ -239,7 +239,8 @@ class ScalityDriver(driver.VolumeDriver): image_utils.fetch_to_raw(context, image_service, image_id, - self.local_path(volume)) + self.local_path(volume), + size=volume['size']) self.create_volume(volume) def copy_volume_to_image(self, context, volume, image_service, image_meta): -- 2.45.2