]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Use project id from volume when retyping volumes
authorOllie Leahy <oliver.leahy@hp.com>
Thu, 15 Oct 2015 15:20:28 +0000 (15:20 +0000)
committerOllie Leahy <oliver.leahy@hp.com>
Thu, 15 Oct 2015 15:20:28 +0000 (15:20 +0000)
Use the project_id from the volume being retyped to reserve quota in
get_volume_type_reservation(). Previously the project_id from the
context was used, which could cause reservations to be made and never
cleared.

Change-Id: I25f7c00961e259102cdaea6ea9394d04ded96b92
Closes-Bug: #1505307

cinder/quota_utils.py
cinder/tests/unit/api/contrib/test_volume_actions.py
cinder/tests/unit/test_quota.py

index dd7fe0c722f1b0d55b683fa70860af5ef29f2154..1d5db033cda3ec9bc9a8de3020168f2e3b12d9b7 100644 (file)
@@ -31,7 +31,14 @@ def get_volume_type_reservation(ctxt, volume, type_id):
         QUOTAS.add_volume_type_opts(ctxt,
                                     reserve_opts,
                                     type_id)
-        reservations = QUOTAS.reserve(ctxt, **reserve_opts)
+        # Note that usually the project_id on the volume will be the same as
+        # the project_id in the context. But, if they are different then the
+        # reservations must be recorded against the project_id that owns the
+        # volume.
+        project_id = volume['project_id']
+        reservations = QUOTAS.reserve(ctxt,
+                                      project_id=project_id,
+                                      **reserve_opts)
     except exception.OverQuota as e:
         overs = e.kwargs['overs']
         usages = e.kwargs['usages']
index 2aa931e22e2900986195245e90f302515452edb4..b31f3762e7336c5ebf85b606a90a57ed71f96e80 100644 (file)
@@ -53,7 +53,8 @@ class VolumeActionsTest(test.TestCase):
             self.api_patchers[_meth].return_value = True
 
         vol = {'id': 'fake', 'host': 'fake', 'status': 'available', 'size': 1,
-               'migration_status': None, 'volume_type_id': 'fake'}
+               'migration_status': None, 'volume_type_id': 'fake',
+               'project_id': 'project_id'}
         self.get_patcher = mock.patch('cinder.volume.API.get')
         self.mock_volume_get = self.get_patcher.start()
         self.addCleanup(self.get_patcher.stop)
index 6da91874468741a87ff21c22bbfcc5b4cc98933e..e35c518d0ae9e3405c8aee5172bdaf5e2036fd96 100644 (file)
@@ -31,6 +31,7 @@ from cinder.db.sqlalchemy import models as sqa_models
 from cinder import exception
 from cinder import objects
 from cinder import quota
+from cinder import quota_utils
 from cinder import test
 import cinder.tests.unit.image.fake
 from cinder import volume
@@ -1821,3 +1822,38 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase):
                                        usage_id=self.usages['gigabytes'],
                                        project_id='test_project',
                                        delta=-2 * 1024), ])
+
+
+class QuotaVolumeTypeReservationTestCase(test.TestCase):
+
+    def setUp(self):
+        super(QuotaVolumeTypeReservationTestCase, self).setUp()
+
+        self.volume_type_name = CONF.default_volume_type
+        self.volume_type = db.volume_type_create(
+            context.get_admin_context(),
+            dict(name=self.volume_type_name))
+
+    @mock.patch.object(quota.QUOTAS, 'reserve')
+    @mock.patch.object(quota.QUOTAS, 'add_volume_type_opts')
+    def test_volume_type_reservation(self,
+                                     mock_add_volume_type_opts,
+                                     mock_reserve):
+        my_context = FakeContext('MyProject', None)
+        volume = {'name': 'my_vol_name',
+                  'id': 'my_vol_id',
+                  'size': '1',
+                  'project_id': 'vol_project_id',
+                  }
+        reserve_opts = {'volumes': 1, 'gigabytes': volume['size']}
+        quota_utils.get_volume_type_reservation(my_context,
+                                                volume,
+                                                self.volume_type['id'])
+        mock_add_volume_type_opts.assert_called_once_with(
+            my_context,
+            reserve_opts,
+            self.volume_type['id'])
+        mock_reserve.assert_called_once_with(my_context,
+                                             project_id='vol_project_id',
+                                             gigabytes='1',
+                                             volumes=1)