From 0756cf8ec3f2c73b4141b4b6dc597e82e47de669 Mon Sep 17 00:00:00 2001 From: ling-yun Date: Fri, 4 Apr 2014 22:18:50 +0800 Subject: [PATCH] Only create volume with an active image 1. Currently cinder doesn't check whether the image is active when create volume with an image id, we can even create volume with a deleted/saving/queued image. 2. For deleted image, it only happened when using admin credentials. When using non-admin credentials, it returned an error that image is not found by using 'glance image-show' on a deleted image, which is expected. Also when creating a volume from this deleted image, it returned a 404 error upfront. This again is the expected result. When using admin credentials, we can view the details of deleted image with 'glance image-show'. If create a volume out of an image ID (which is now deleted), the operation succeeds, but the volume is left in 'error' state. 3. This accounts for a bug(he volume shouldn't be created) and should be fixed. Change-Id: If4f59695fbf6636778d0d352aef28d90bb45ee91 Closes-Bug: #1302621 --- cinder/tests/test_volume.py | 27 +++++++++++++++++++++--- cinder/volume/flows/api/create_volume.py | 6 ++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py index 99752f659..122d555b1 100644 --- a/cinder/tests/test_volume.py +++ b/cinder/tests/test_volume.py @@ -84,7 +84,8 @@ class FakeImageService: def show(self, context, image_id): return {'size': 2 * units.GiB, 'disk_format': 'raw', - 'container_format': 'bare'} + 'container_format': 'bare', + 'status': 'active'} class BaseVolumeTestCase(test.TestCase): @@ -1876,7 +1877,8 @@ class VolumeTestCase(BaseVolumeTestCase): def show(self, context, image_id): return {'size': 2 * units.GiB + 1, 'disk_format': 'raw', - 'container_format': 'bare'} + 'container_format': 'bare', + 'status': 'active'} volume_api = cinder.volume.api.API(image_service= _ModifiedFakeImageService()) @@ -1893,7 +1895,26 @@ class VolumeTestCase(BaseVolumeTestCase): return {'size': 2 * units.GiB, 'disk_format': 'raw', 'container_format': 'bare', - 'min_disk': 5} + 'min_disk': 5, + 'status': 'active'} + + volume_api = cinder.volume.api.API(image_service= + _ModifiedFakeImageService()) + + self.assertRaises(exception.InvalidInput, + volume_api.create, + self.context, 2, + 'name', 'description', image_id=1) + + def test_create_volume_with_deleted_imaged(self): + """Verify create volume from image will cause an error.""" + class _ModifiedFakeImageService(FakeImageService): + def show(self, context, image_id): + return {'size': 2 * units.GiB, + 'disk_format': 'raw', + 'container_format': 'bare', + 'min_disk': 5, + 'status': 'deleted'} volume_api = cinder.volume.api.API(image_service= _ModifiedFakeImageService()) diff --git a/cinder/volume/flows/api/create_volume.py b/cinder/volume/flows/api/create_volume.py index da985cbc2..9388d7715 100644 --- a/cinder/volume/flows/api/create_volume.py +++ b/cinder/volume/flows/api/create_volume.py @@ -179,6 +179,12 @@ class ExtractVolumeRequestTask(flow_utils.CinderTask): # exist, this is expected as it signals that the image_id is missing. image_meta = self.image_service.show(context, image_id) + #check whether image is active + if image_meta['status'] != 'active': + msg = _('Image %(image_id)s is not active.')\ + % {'image_id': image_id} + raise exception.InvalidInput(reason=msg) + # Check image size is not larger than volume size. image_size = utils.as_int(image_meta['size'], quiet=False) image_size_in_gb = (image_size + GB - 1) / GB -- 2.45.2