Skip to content

Instantly share code, notes, and snippets.

@sorrison
Created March 20, 2015 23:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sorrison/99c8e87295756e0ed787 to your computer and use it in GitHub Desktop.
Save sorrison/99c8e87295756e0ed787 to your computer and use it in GitHub Desktop.
from nova import context
from nova.openstack.common import timeutils
from nova.db.sqlalchemy import api
from nova.openstack.common.db.sqlalchemy import session as db_session
from nova.db.sqlalchemy.api import (
PER_PROJECT_QUOTAS,
_get_project_user_quota_usages,
_quota_usage_create,
require_context,
_retry_on_deadlock,
QUOTA_SYNC_FUNCTIONS,
get_session
)
from nova.quota import QUOTAS
from nova.openstack.common import log as logging
LOG = logging.getLogger(__name__)
@require_context
@_retry_on_deadlock
def quota_sync(context,
project_id=None, user_id=None,
until_refresh=1, max_age=0):
resources = QUOTAS._resources
quotas = ['instances', 'cores', 'ram', 'security_groups']
#print("Quota sync")
elevated = context.elevated()
session = get_session()
with session.begin():
if project_id is None:
project_id = context.project_id
if user_id is None:
user_id = context.user_id
# Get the current usages
project_usages, user_usages = _get_project_user_quota_usages(
context, session, project_id, user_id)
# Handle usage refresh
work = set(quotas)
while work:
resource = work.pop()
# Do we need to refresh the usage?
refresh = True
if ((resource not in PER_PROJECT_QUOTAS) and
(resource not in user_usages)):
user_usages[resource] = _quota_usage_create(elevated,
project_id,
user_id,
resource,
0, 0,
until_refresh or None,
session=session)
refresh = True
elif ((resource in PER_PROJECT_QUOTAS) and
(resource not in user_usages)):
user_usages[resource] = _quota_usage_create(elevated,
project_id,
None,
resource,
0, 0,
until_refresh or None,
session=session)
refresh = True
elif user_usages[resource].in_use < 0:
# Negative in_use count indicates a desync, so try to
# heal from that...
refresh = True
elif user_usages[resource].until_refresh is not None:
user_usages[resource].until_refresh -= 1
if user_usages[resource].until_refresh <= 0:
refresh = True
elif max_age and (user_usages[resource].updated_at -
timeutils.utcnow()).seconds >= max_age:
refresh = True
# OK, refresh the usage
if refresh:
# Grab the sync routine
sync = QUOTA_SYNC_FUNCTIONS[resources[resource].sync]
deltas = []
updates = sync(elevated, project_id, user_id, session)
for res, in_use in updates.items():
# Make sure we have a destination for the usage!
if ((res not in PER_PROJECT_QUOTAS) and
(res not in user_usages)):
user_usages[res] = _quota_usage_create(elevated,
project_id,
user_id,
res,
0, 0,
until_refresh or None,
session=session)
if ((res in PER_PROJECT_QUOTAS) and
(res not in user_usages)):
user_usages[res] = _quota_usage_create(elevated,
project_id,
None,
res,
0, 0,
until_refresh or None,
session=session)
if user_usages[res].in_use != in_use:
deltas.append((res, user_usages[res].in_use - in_use))
# Update the usage
user_usages[res].in_use = in_use
user_usages[res].until_refresh = until_refresh or None
# Because more than one resource may be refreshed
# by the call to the sync routine, and we don't
# want to double-sync, we make sure all refreshed
# resources are dropped from the work set.
work.discard(res)
# NOTE(Vek): We make the assumption that the sync
# routine actually refreshes the
# resources that it is the sync routine
# for. We don't check, because this is
# a best-effort mechanism.
if deltas:
print('Changes for project %s, user %s:' % (project_id, user_id))
for resource, delta in deltas:
print(' %s %s' % (resource, delta))
# Apply updates to the usages table
for usage_ref in user_usages.values():
session.add(usage_ref)
def main():
data = open('/root/keystone_project_users.txt').readlines()
for line in data:
project, user = line.strip().split('\t')
project = project.strip()
user = user.strip()
if project and user:
quota_sync(context.get_admin_context(), project_id=project, user_id=user)
def sync_project_user_quota(project, user):
quota_sync(context.get_admin_context(), project_id=project, user_id=user)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment