]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Only create volume with an active image
authorling-yun <zengyunling@huawei.com>
Fri, 4 Apr 2014 14:18:50 +0000 (22:18 +0800)
committerling-yun <zengyunling@huawei.com>
Tue, 27 May 2014 11:36:31 +0000 (19:36 +0800)
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
cinder/volume/flows/api/create_volume.py

index 99752f6596daa3bfd4cfeb48c42a977d1f2ccea7..122d555b1a39636a05b8625295bcdcd2091c3e7e 100644 (file)
@@ -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())
index da985cbc226a2459d29c0252a3a367606d9294bb..9388d7715b09b6b0fdc894f7c1217e3277de41e0 100644 (file)
@@ -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