Update cinder manage quota commands

This patch updates the cinder manage quota commands to leverage the new
method _get_sync_updates from cinder db, allowing us to simplify our
code.

Change-Id: I099d101a3f2bcfbd2026306081a9858c610ab1ff
This commit is contained in:
Gorka Eguileor 2021-03-15 17:58:56 +01:00
parent 1fb0767d88
commit cdd60605f4
1 changed files with 25 additions and 41 deletions

View File

@ -417,15 +417,10 @@ class QuotaCommands(object):
project_ids = [row.project_id for row in projects]
return project_ids
def _get_quota_syncs(self, ctxt, session, resources, project_id):
def _get_usages(self, ctxt, session, resources, project_id):
"""Get data necessary to check out of sync quota usage.
Returns a list of tuples where each tuple contains a QuotaUsage
instance, the corresponding resource from quota.QUOTAS.resources, the
volume type id, and the volume type name.
Volume type id and name will be None for non volume type entries, as
expected by the DB sync methods.
Returns a list QuotaUsage instances for the specific project
"""
usages = db_api.model_query(ctxt,
db_api.models.QuotaUsage,
@ -434,14 +429,7 @@ class QuotaCommands(object):
filter_by(project_id=project_id).\
with_for_update().\
all()
res = []
for usage in usages:
resource = resources[usage.resource]
volume_type_id = getattr(resource, 'volume_type_id', None)
volume_type_name = getattr(resource, 'volume_type_name', None)
res.append((usage, resource, volume_type_id, volume_type_name))
return res
return usages
def _get_reservations(self, ctxt, session, project_id, usage_id):
"""Get reservations for a given project and usage id."""
@ -453,33 +441,30 @@ class QuotaCommands(object):
all()
return reservations
def _check_duplicates(self, ctxt, session, sync_data, do_fix):
def _check_duplicates(self, ctxt, session, usages, do_fix):
"""Look for duplicated quota used entries (bug#1484343)
If we have duplicates and we are fixing them, then we reassign the
reservations of the usage we are removing.
"""
resources = collections.defaultdict(list)
for sync in sync_data:
usage = sync[0]
resources[usage.resource].append(sync)
for usage in usages:
resources[usage.resource].append(usage)
duplicates_found = False
result = []
for syncs in resources.values():
keep_sync = syncs[0]
if len(syncs) > 1:
for resource_usages in resources.values():
keep_usage = resource_usages[0]
if len(resource_usages) > 1:
duplicates_found = True
keep_usage = keep_sync[0]
print('\t%s: %s duplicated usage entries - ' %
(keep_usage.resource, len(syncs) - 1),
(keep_usage.resource, len(resource_usages) - 1),
end='')
if do_fix:
# Each of the duplicates can have reservations
reassigned = 0
for sync in syncs[1:]:
usage = sync[0]
for usage in resource_usages[1:]:
reservations = self._get_reservations(ctxt, session,
usage.project_id,
usage.id)
@ -493,7 +478,7 @@ class QuotaCommands(object):
reassigned)
else:
print('ignored')
result.append(keep_sync)
result.append(keep_usage)
return result, duplicates_found
def _check_sync(self, project_id, do_fix):
@ -521,28 +506,27 @@ class QuotaCommands(object):
with session.begin():
print('Processing quota usage for project %s' % project)
# We only want to sync existing quota usage rows
syncs = self._get_quota_syncs(ctxt, session, resources,
project)
usages = self._get_usages(ctxt, session, resources, project)
# Check for duplicated entries (bug#1484343)
syncs, duplicates_found = self._check_duplicates(ctxt, session,
syncs, do_fix)
usages, duplicates_found = self._check_duplicates(ctxt,
session,
usages,
do_fix)
if duplicates_found:
discrepancy = True
# Check quota and reservations
for usage, resource, vol_type_id, vol_type_name in syncs:
for usage in usages:
resource_name = usage.resource
# Get the correct value for this quota usage resource
sync = db_api.QUOTA_SYNC_FUNCTIONS[resource.sync]
updates = sync(ctxt, project,
volume_type_id=vol_type_id,
volume_type_name=vol_type_name,
session=session)
in_use = list(updates.values())[0]
updates = db_api._get_sync_updates(ctxt, project, session,
resources,
resource_name)
in_use = updates[resource_name]
if in_use != usage.in_use:
print('\t%s: invalid usage saved=%s actual=%s%s' %
(usage.resource, usage.in_use, in_use,
(resource_name, usage.in_use, in_use,
action_msg))
discrepancy = True
if do_fix:
@ -554,7 +538,7 @@ class QuotaCommands(object):
if r.delta > 0)
if num_reservations != usage.reserved:
print('\t%s: invalid reserved saved=%s actual=%s%s' %
(usage.resource, usage.reserved,
(resource_name, usage.reserved,
num_reservations, action_msg))
discrepancy = True
if do_fix: