From: ling-yun Date: Fri, 4 Apr 2014 14:18:50 +0000 (+0800) Subject: Only create volume with an active image X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=0756cf8ec3f2c73b4141b4b6dc597e82e47de669;p=openstack-build%2Fcinder-build.git 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 --- 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