Revision e336910f

b/snf-astakos-app/astakos/im/functions.py
68 68
    AstakosUser, Invitation, ProjectMembership, ProjectApplication, Project,
69 69
    UserSetting,
70 70
    get_resource_names, new_chain)
71
from astakos.im.quotas import (qh_sync_user, qh_sync_users,
71
from astakos.im.quotas import (qh_sync_user, qh_sync_project,
72 72
                               register_pending_apps)
73 73
from astakos.im.project_notif import (
74 74
    membership_change_notify, membership_enroll_notify,
......
293 293
    if not user.activation_sent:
294 294
        user.activation_sent = datetime.now()
295 295
    user.save()
296
    qh_sync_user(user.id)
296
    qh_sync_user(user)
297 297
    send_helpdesk_notification(user, helpdesk_email_template_name)
298 298
    send_greeting(user, email_template_name)
299 299

  
......
526 526

  
527 527
    user = membership.person
528 528
    membership.accept()
529
    qh_sync_user(user.id)
529
    qh_sync_user(user)
530 530
    logger.info("User %s has been accepted in %s." %
531 531
                (user.log_display, project))
532 532

  
......
593 593

  
594 594
    user = membership.person
595 595
    membership.remove()
596
    qh_sync_user(user.id)
596
    qh_sync_user(user)
597 597
    logger.info("User %s has been removed from %s." %
598 598
                (user.log_display, project))
599 599

  
......
614 614
        raise PermissionDenied(m)
615 615

  
616 616
    membership.accept()
617
    qh_sync_user(user.id)
617
    qh_sync_user(user)
618 618
    logger.info("User %s has been enrolled in %s." %
619 619
                (membership.person.log_display, project))
620 620

  
......
655 655
    leave_policy = project.application.member_leave_policy
656 656
    if leave_policy == AUTO_ACCEPT_POLICY:
657 657
        membership.remove()
658
        qh_sync_user(request_user.id)
658
        qh_sync_user(request_user)
659 659
        logger.info("User %s has left %s." %
660 660
                    (membership.person.log_display, project))
661 661
        auto_accepted = True
......
703 703
    if (join_policy == AUTO_ACCEPT_POLICY and (
704 704
            not project.violates_members_limit(adding=1))):
705 705
        membership.accept()
706
        qh_sync_user(request_user.id)
706
        qh_sync_user(request_user)
707 707
        logger.info("User %s joined %s." %
708 708
                    (membership.person.log_display, project))
709 709
        auto_accepted = True
......
844 844

  
845 845
    qh_release_pending_app(application.owner)
846 846
    project = application.approve(reason)
847
    qh_sync_projects([project])
847
    qh_sync_project(project)
848 848
    logger.info("%s has been approved." % (application.log_display))
849 849
    application_approve_notify(application)
850 850

  
......
865 865
    checkAlive(project)
866 866

  
867 867
    project.terminate()
868
    qh_sync_projects([project])
868
    qh_sync_project(project)
869 869
    logger.info("%s has been terminated." % (project))
870 870

  
871 871
    project_termination_notify(project)
872 872

  
873 873

  
874 874
def suspend(project_id, request_user=None):
875
    project = get_project_by_id(project_id)
875
    project = get_project_for_update(project_id)
876 876
    checkAllowed(project, request_user, admin_only=True)
877 877
    checkAlive(project)
878 878

  
879 879
    project.suspend()
880
    qh_sync_projects([project])
880
    qh_sync_project(project)
881 881
    logger.info("%s has been suspended." % (project))
882 882

  
883 883
    project_suspension_notify(project)
......
892 892
        raise PermissionDenied(m)
893 893

  
894 894
    project.resume()
895
    qh_sync_projects([project])
895
    qh_sync_project(project)
896 896
    logger.info("%s has been unsuspended." % (project))
897 897

  
898 898

  
......
969 969

  
970 970
def qh_release_pending_app(user):
971 971
    register_pending_apps(user, -1)
972

  
973

  
974
def qh_sync_projects(projects):
975

  
976
    memberships = ProjectMembership.objects.filter(project__in=projects)
977
    user_ids = set(m.person_id for m in memberships)
978

  
979
    qh_sync_users(user_ids)
b/snf-astakos-app/astakos/im/management/commands/quota.py
35 35
from django.core.management.base import CommandError
36 36

  
37 37
from astakos.im.models import AstakosUser
38
from astakos.im.quotas import set_user_quota, list_user_quotas, add_base_quota
38
from astakos.im.quotas import (
39
    qh_sync_users, list_user_quotas, add_base_quota)
39 40
from astakos.im.functions import get_user_by_uuid
40 41
from astakos.im.management.commands._common import is_uuid, is_email
41 42
from snf_django.lib.db.transaction import commit_on_success_strict
......
104 105
        else:
105 106
            users = AstakosUser.objects.verified()
106 107

  
107
        try:
108
            qh_limits, qh_quotas, astakos_i, diff_q = list_user_quotas(users)
109
        except BaseException as e:
110
            logger.exception(e)
111
            raise CommandError("Failed to compute quota.")
108
        if list_only:
109
            qh_quotas, astakos_i = list_user_quotas(users)
112 110

  
113
        info = {}
114
        for user in users:
115
            info[user.uuid] = user.email
111
            info = {}
112
            for user in users:
113
                info[user.uuid] = user.email
116 114

  
117
        if list_only:
118 115
            print_data, labels = show_quotas(qh_quotas, astakos_i, info)
119 116
            utils.pprint_table(self.stdout, print_data, labels,
120 117
                               output_format)
121 118

  
122
        else:
119
        elif verify or sync:
120
            qh_limits, diff_q = qh_sync_users(users, sync=sync, diff_only=True)
123 121
            if verify:
124 122
                self.print_verify(qh_limits, diff_q)
125 123
            if sync:
126
                try:
127
                    set_user_quota(diff_q)
128
                except BaseException as e:
129
                    logger.exception(e)
130
                    raise CommandError("Failed to sync quota.")
131 124
                self.print_sync(diff_q)
132 125

  
133 126
    def get_user(self, user_ident):
b/snf-astakos-app/astakos/im/quotas.py
83 83
    return quotas
84 84

  
85 85

  
86
def get_users_quotas_and_limits(users, resources=None, sources=None):
86
def get_users_quota_limits(users, resources=None, sources=None):
87 87
    counters = get_counters(users, resources, sources)
88
    quotas = transform_data(counters)
89 88
    limits = transform_data(counters, limits_only)
90
    return quotas, limits
89
    return limits
91 90

  
92 91

  
93 92
def get_user_quotas(user, resources=None, sources=None):
......
112 111
    return lst
113 112

  
114 113

  
115
def set_user_quota(quotas):
114
def _set_user_quota(quotas):
116 115
    q = _level_quota_dict(quotas)
117 116
    qh.set_quota(q)
118 117

  
......
130 129
SYSTEM = 'system'
131 130

  
132 131

  
133
def resolve_pending_serial(serial, accept=True):
134
    return qh.resolve_pending_commission('astakos', serial, accept)
135

  
136

  
137 132
def register_pending_apps(user, quantity, force=False, dry_run=False):
138 133
    provision = (user.uuid, SYSTEM, 'astakos.pending_app'), quantity
139 134
    name = "DRYRUN" if dry_run else ""
......
162 157
    if not created:
163 158
        obj.capacity = capacity
164 159
        obj.save()
165
    qh_sync_user(user.id)
160
    qh_sync_user(user)
166 161

  
167 162

  
168 163
def remove_base_quota(user, resource):
169 164
    AstakosUserQuota.objects.filter(
170 165
        user=user, resource__name=resource).delete()
171
    qh_sync_user(user.id)
166
    qh_sync_user(user)
172 167

  
173 168

  
174 169
def initial_quotas(users):
......
244 239
    return quotas
245 240

  
246 241

  
247
def astakos_user_quotas(user):
248
    quotas = astakos_users_quotas([user])
249
    try:
250
        return quotas[user.uuid]
251
    except KeyError:
252
        raise ValueError("could not compute quotas")
253

  
254

  
255 242
def list_user_quotas(users):
256
    qh_quotas, qh_limits = get_users_quotas_and_limits(users)
243
    qh_quotas = get_users_quotas(users)
257 244
    astakos_initial = initial_quotas(users)
245
    return qh_quotas, astakos_initial
246

  
247

  
248
# Syncing to quotaholder
249

  
250
def qh_sync_users(users, sync=True, diff_only=False):
251
    uids = [user.id for user in users]
252
    if sync:
253
        users = AstakosUser.forupdate.filter(id__in=uids).select_for_update()
254

  
258 255
    astakos_quotas = astakos_users_quotas(users)
259 256

  
260
    diff_quotas = {}
261
    for holder, local in astakos_quotas.iteritems():
262
        registered = qh_limits.get(holder, None)
263
        if local != registered:
264
            diff_quotas[holder] = dict(local)
257
    if diff_only:
258
        qh_limits = get_users_quota_limits(users)
259
        diff_quotas = {}
260
        for holder, local in astakos_quotas.iteritems():
261
            registered = qh_limits.get(holder, None)
262
            if local != registered:
263
                diff_quotas[holder] = dict(local)
264

  
265
        if sync:
266
            _set_user_quota(diff_quotas)
267
        return qh_limits, diff_quotas
268
    else:
269
        if sync:
270
            _set_user_quota(astakos_quotas)
271
        return None
265 272

  
266
    return (qh_limits, qh_quotas,
267
            astakos_initial, diff_quotas)
273

  
274
def qh_sync_user(user):
275
    qh_sync_users([user])
276

  
277

  
278
def qh_sync_projects(projects):
279
    memberships = ProjectMembership.objects.filter(
280
        project__in=projects, state__in=ProjectMembership.ACTUALLY_ACCEPTED)
281
    users = set(m.person for m in memberships)
282

  
283
    qh_sync_users(users)
284

  
285

  
286
def qh_sync_project(project):
287
    qh_sync_projects([project])
268 288

  
269 289

  
270 290
def qh_add_resource_limit(resource, diff):
......
288 308
        data.append((key, limit))
289 309

  
290 310
    qh.set_quota(data)
291

  
292

  
293
def qh_sync_users(user_ids):
294
    users = AstakosUser.forupdate.filter(id__in=user_ids).select_for_update()
295
    astakos_quotas = astakos_users_quotas(list(users))
296
    set_user_quota(astakos_quotas)
297

  
298

  
299
def qh_sync_user(user_id):
300
    qh_sync_users([user_id])
b/snf-astakos-app/astakos/im/tests.py
1417 1417

  
1418 1418
        # create user
1419 1419
        user = get_local_user('test@grnet.gr')
1420
        quotas.qh_sync_user(user.id)
1420
        quotas.qh_sync_user(user)
1421 1421

  
1422 1422
        # create another service
1423 1423
        service2 = Service.objects.create(

Also available in: Unified diff