Created
March 20, 2015 23:50
-
-
Save sorrison/99c8e87295756e0ed787 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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