From 90453d5c60e7a9d023c916ad257c03f47a4e4031 Mon Sep 17 00:00:00 2001 From: Aarti Kriplani Date: Wed, 29 May 2013 11:18:24 +0530 Subject: Fix quota checks while resizing up by admin Fixes LP 1184594 Fixing a bug when admin issues a resize up for a user, it checks for admin's quota instead of user's quota. Change-Id: Ida5db9039396df0a08c699711b72882e2ef136f8 --- nova/compute/api.py | 13 +++++++++---- nova/tests/compute/test_compute.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 80c8074d9..653b96bbc 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1989,8 +1989,10 @@ class API(base.Base): old_instance_type, 1, -1) @staticmethod - def _reserve_quota_delta(context, deltas): - return QUOTAS.reserve(context, **deltas) if deltas else None + def _reserve_quota_delta(context, deltas, project_id=None): + if not deltas: + return + return QUOTAS.reserve(context, project_id=project_id, **deltas) @wrap_check_policy @check_instance_lock @@ -2046,7 +2048,9 @@ class API(base.Base): deltas = self._upsize_quota_delta(context, new_instance_type, current_instance_type) try: - reservations = self._reserve_quota_delta(context, deltas) + reservations = self._reserve_quota_delta(context, deltas, + project_id=instance[ + 'project_id']) except exception.OverQuota as exc: quotas = exc.kwargs['quotas'] usages = exc.kwargs['usages'] @@ -2092,7 +2096,8 @@ class API(base.Base): # With cells, the best we can do right now is commit the reservations # immediately... if CONF.cells.enable and reservations: - QUOTAS.commit(context, reservations) + QUOTAS.commit(context, reservations, + project_id=instance['project_id']) reservations = [] args = { diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 491ecf544..18858d5fd 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -6513,6 +6513,40 @@ class ComputeAPITestCase(BaseTestCase): flavors.destroy(name) self.compute.terminate_instance(self.context, instance=instance) + def test_resize_by_admin_for_tenant_with_sufficient_quota(self): + user_project_id = 'user' + instance = self._create_fake_instance({'project_id': user_project_id}) + self.context.is_admin = True + db.quota_create(self.context, self.context.project_id, 'ram', 0) + instance = db.instance_get_by_uuid(self.context, instance['uuid']) + instance = jsonutils.to_primitive(instance) + self.compute.run_instance(self.context, instance=instance) + name = 'test_resize_with_big_mem' + flavor_id = 11 + flavors.create(name, 1024, 1, 0, ephemeral_gb=0, flavorid=flavor_id, + swap=0, rxtx_factor=1.0, is_public=True) + deltas = {'ram': 512} + reservations = ['reservation_id'] + + self.mox.StubOutWithMock(self.compute_api, '_reserve_quota_delta') + + self.compute_api._reserve_quota_delta(self.context, + deltas, + project_id=user_project_id). \ + AndReturn(reservations) + + CONF.cells.enable = True + self.mox.StubOutWithMock(nova.quota.QUOTAS, 'commit') + nova.quota.QUOTAS.commit(self.context, reservations, + project_id=user_project_id) + self.mox.ReplayAll() + + self.compute_api.resize(self.context, instance, flavor_id) + + flavors.destroy(name) + db.quota_destroy_all_by_project(self.context, self.context.project_id) + self.compute.terminate_instance(self.context, instance=instance) + def test_resize_revert_deleted_flavor_fails(self): orig_name = 'test_resize_revert_orig_flavor' orig_flavorid = 11 -- cgit