diff --git a/nova/api/openstack/compute/quota_sets.py b/nova/api/openstack/compute/quota_sets.py index bd653c3d276a..cfaa13af8fc5 100644 --- a/nova/api/openstack/compute/quota_sets.py +++ b/nova/api/openstack/compute/quota_sets.py @@ -81,6 +81,22 @@ class QuotaSetsController(wsgi.Controller): values = QUOTAS.get_project_quotas(context, id, usages=usages) if usages: + # NOTE(melwitt): For the detailed quota view with usages, the API + # returns a response in the format: + # { + # "quota_set": { + # "cores": { + # "in_use": 0, + # "limit": 20, + # "reserved": 0 + # }, + # ... + # We've re-architected quotas to eliminate reservations, so we no + # longer have a 'reserved' key returned from get_*_quotas, so set + # it here to satisfy the REST API response contract. + reserved = QUOTAS.get_reserved() + for v in values.values(): + v['reserved'] = reserved return values else: return {k: v['limit'] for k, v in values.items()} diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index cfa289bc0805..6042e901f336 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -295,9 +295,15 @@ class ProjectCommands(object): quota = QUOTAS.get_user_quotas(ctxt, project_id, user_id) else: quota = QUOTAS.get_project_quotas(ctxt, project_id) + reserved = QUOTAS.get_reserved() for key, value in quota.items(): if value['limit'] is None or value['limit'] < 0: value['limit'] = 'unlimited' + # NOTE(melwitt): We've re-architected quotas to eliminate + # reservations, so we no longer have a 'reserved' key returned from + # get_*_quotas, so set it here to satisfy what's expected from the + # command output. + value['reserved'] = reserved print(print_format % (key, value['limit'], value['in_use'], value['reserved'])) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 05341b40001e..fc077a6ed41e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3571,16 +3571,6 @@ def quota_destroy_all_by_project_and_user(context, project_id, user_id): filter_by(user_id=user_id).\ soft_delete(synchronize_session=False) - model_query(context, models.QuotaUsage, read_deleted="no").\ - filter_by(project_id=project_id).\ - filter_by(user_id=user_id).\ - soft_delete(synchronize_session=False) - - model_query(context, models.Reservation, read_deleted="no").\ - filter_by(project_id=project_id).\ - filter_by(user_id=user_id).\ - soft_delete(synchronize_session=False) - @pick_context_manager_writer def quota_destroy_all_by_project(context, project_id): @@ -3592,14 +3582,6 @@ def quota_destroy_all_by_project(context, project_id): filter_by(project_id=project_id).\ soft_delete(synchronize_session=False) - model_query(context, models.QuotaUsage, read_deleted="no").\ - filter_by(project_id=project_id).\ - soft_delete(synchronize_session=False) - - model_query(context, models.Reservation, read_deleted="no").\ - filter_by(project_id=project_id).\ - soft_delete(synchronize_session=False) - ################### diff --git a/nova/objects/quotas.py b/nova/objects/quotas.py index ebd0fb2514e8..ee5dbfdedae8 100644 --- a/nova/objects/quotas.py +++ b/nova/objects/quotas.py @@ -255,7 +255,7 @@ class Quotas(base.NovaObject): def reserve(self, expire=None, project_id=None, user_id=None, **deltas): # Honor the expected attributes even though we're not reserving - # anything anymore. This will protect against things exploding if a + # anything anymore. This will protect against things exploding if # someone has an Ocata compute host running by accident, for example. self.reservations = None self.project_id = project_id diff --git a/nova/quota.py b/nova/quota.py index 44c354bbd748..b353be21bc62 100644 --- a/nova/quota.py +++ b/nova/quota.py @@ -136,7 +136,6 @@ class DbQuotaDriver(object): usage = usages.get(resource.name, {}) modified_quotas[resource.name].update( in_use=usage.get('in_use', 0), - reserved=0, ) # Initialize remains quotas with the default limits. @@ -710,7 +709,6 @@ class NoopQuotaDriver(object): quotas[resource.name]['limit'] = -1 if usages: quotas[resource.name]['in_use'] = -1 - quotas[resource.name]['reserved'] = -1 if remains: quotas[resource.name]['remains'] = -1 return quotas @@ -1241,6 +1239,11 @@ class QuotaEngine(object): def resources(self): return sorted(self._resources.keys()) + def get_reserved(self): + if isinstance(self._driver, NoopQuotaDriver): + return -1 + return 0 + def _keypair_get_count_by_user(context, user_id): count = objects.KeyPairList.get_count_by_user(context, user_id) diff --git a/nova/tests/unit/test_quota.py b/nova/tests/unit/test_quota.py index 95c287972e83..e3c026444177 100644 --- a/nova/tests/unit/test_quota.py +++ b/nova/tests/unit/test_quota.py @@ -978,72 +978,58 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=5, in_use=2, - reserved=0, ), cores=dict( limit=10, in_use=4, - reserved=0, ), ram=dict( limit=25 * 1024, in_use=10 * 1024, - reserved=0, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, ), metadata_items=dict( limit=64, in_use=0, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_content_bytes=dict( limit=5 * 1024, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), security_groups=dict( limit=10, in_use=0, - reserved=0, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, ), server_groups=dict( limit=10, in_use=0, - reserved=0, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, ), )) @@ -1054,7 +1040,7 @@ class DbQuotaDriverTestCase(test.TestCase): self.assertEqual(user_id, 'fake_user') self.assertEqual(resource, 'test_resource') return dict( - test_resource=dict(in_use=20, reserved=10), + test_resource=dict(in_use=20), ) self.stub_out('nova.db.quota_get', fake_quota_get) @@ -1066,7 +1052,7 @@ class DbQuotaDriverTestCase(test.TestCase): self.assertEqual(self.calls, ['quota_get']) self.assertEqual(result, dict( - test_resource=dict(in_use=20, reserved=10), + test_resource=dict(in_use=20), )) def _stub_get_by_project(self): @@ -1113,72 +1099,58 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=5, in_use=2, - reserved=0, ), cores=dict( limit=10, in_use=4, - reserved=0, ), ram=dict( limit=25 * 1024, in_use=10 * 1024, - reserved=0, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, ), metadata_items=dict( limit=64, in_use=0, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_content_bytes=dict( limit=5 * 1024, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), security_groups=dict( limit=10, in_use=0, - reserved=0, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, ), server_groups=dict( limit=10, in_use=0, - reserved=0, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, ), )) @@ -1203,85 +1175,71 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=5, in_use=2, - reserved=0, remains=0, ), cores=dict( limit=10, in_use=4, - reserved=0, remains=8, ), ram=dict( limit=25 * 1024, in_use=10 * 1024, - reserved=0, remains=25 * 1024, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, remains=10, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, remains=10, ), metadata_items=dict( limit=64, in_use=0, - reserved=0, remains=64, ), injected_files=dict( limit=2, in_use=0, - reserved=0, remains=2, ), injected_file_content_bytes=dict( limit=5 * 1024, in_use=0, - reserved=0, remains=5 * 1024, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, remains=127, ), security_groups=dict( limit=10, in_use=0, - reserved=0, remains=10, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, remains=20, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, remains=100, ), server_groups=dict( limit=10, in_use=0, - reserved=0, remains=10, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, remains=10, ), )) @@ -1306,72 +1264,58 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=10, in_use=2, - reserved=0, ), cores=dict( limit=10, in_use=4, - reserved=0, ), ram=dict( limit=50 * 1024, in_use=10 * 1024, - reserved=0, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, ), metadata_items=dict( limit=128, in_use=0, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_content_bytes=dict( limit=10 * 1024, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), security_groups=dict( limit=10, in_use=0, - reserved=0, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, ), server_groups=dict( limit=10, in_use=0, - reserved=0, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, ), )) @@ -1394,72 +1338,58 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=5, in_use=2, - reserved=0, ), cores=dict( limit=10, in_use=4, - reserved=0, ), ram=dict( limit=25 * 1024, in_use=10 * 1024, - reserved=0, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, ), metadata_items=dict( limit=64, in_use=0, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_content_bytes=dict( limit=5 * 1024, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), security_groups=dict( limit=10, in_use=0, - reserved=0, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, ), server_groups=dict( limit=10, in_use=0, - reserved=0, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, ), )) @@ -1485,72 +1415,58 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=5, in_use=2, - reserved=0, ), cores=dict( limit=10, in_use=4, - reserved=0, ), ram=dict( limit=25 * 1024, in_use=10 * 1024, - reserved=0, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, ), metadata_items=dict( limit=64, in_use=0, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_content_bytes=dict( limit=5 * 1024, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), security_groups=dict( limit=10, in_use=0, - reserved=0, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, ), server_groups=dict( limit=10, in_use=0, - reserved=0, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, ), )) @@ -1575,72 +1491,58 @@ class DbQuotaDriverTestCase(test.TestCase): instances=dict( limit=5, in_use=2, - reserved=0, ), cores=dict( limit=10, in_use=4, - reserved=0, ), ram=dict( limit=25 * 1024, in_use=10 * 1024, - reserved=0, ), floating_ips=dict( limit=10, in_use=2, - reserved=0, ), fixed_ips=dict( limit=10, in_use=0, - reserved=0, ), metadata_items=dict( limit=64, in_use=0, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_content_bytes=dict( limit=5 * 1024, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), security_groups=dict( limit=10, in_use=0, - reserved=0, ), security_group_rules=dict( limit=20, in_use=1, - reserved=0, ), key_pairs=dict( limit=100, in_use=2, - reserved=0, ), server_groups=dict( limit=10, in_use=0, - reserved=0, ), server_group_members=dict( limit=10, in_use=3, - reserved=0, ), )) @@ -1665,17 +1567,14 @@ class DbQuotaDriverTestCase(test.TestCase): cores=dict( limit=10, in_use=4, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), )) @@ -1698,17 +1597,14 @@ class DbQuotaDriverTestCase(test.TestCase): cores=dict( limit=10, in_use=4, - reserved=0, ), injected_files=dict( limit=2, in_use=0, - reserved=0, ), injected_file_path_bytes=dict( limit=127, in_use=0, - reserved=0, ), )) @@ -2286,8 +2182,7 @@ class NoopQuotaDriverTestCase(test.TestCase): self.expected_settable_quotas = {} for r in quota.QUOTAS._resources: self.expected_with_usages[r] = dict(limit=-1, - in_use=-1, - reserved=-1) + in_use=-1) self.expected_without_usages[r] = dict(limit=-1) self.expected_without_dict[r] = -1 self.expected_settable_quotas[r] = dict(minimum=0, maximum=-1)