Revision 2ff02341
b/snf-pithos-app/pithos/api/management/commands/reconcile-resources-pithos.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
from django.core.management.base import NoArgsCommand, CommandError
|
|
34 |
from django.core.management.base import NoArgsCommand |
|
35 | 35 |
|
36 | 36 |
from optparse import make_option |
37 | 37 |
|
38 | 38 |
from pithos.api.util import get_backend |
39 | 39 |
from pithos.api.resources import resources |
40 |
from pithos.backends.modular import CLUSTER_NORMAL, DEFAULT_SOURCE
|
|
40 |
from pithos.backends.modular import DEFAULT_SOURCE |
|
41 | 41 |
|
42 | 42 |
from synnefo.webproject.management import utils |
43 | 43 |
|
44 |
from astakosclient.errors import QuotaLimit |
|
44 |
from astakosclient.errors import QuotaLimit, NotFound
|
|
45 | 45 |
|
46 | 46 |
backend = get_backend() |
47 | 47 |
|
... | ... | |
70 | 70 |
|
71 | 71 |
def handle_noargs(self, **options): |
72 | 72 |
try: |
73 |
qh_result = backend.astakosclient.service_get_quotas( |
|
74 |
backend.service_token) |
|
73 |
userid = options['userid'] |
|
75 | 74 |
|
76 |
users = (options['userid'],) if options['userid'] else None |
|
77 |
account_nodes = backend.node.node_accounts(users) |
|
78 |
if not account_nodes: |
|
79 |
raise CommandError('No users found.') |
|
75 |
# Get holding from Pithos DB |
|
76 |
db_usage = backend.node.node_account_usage(userid) |
|
80 | 77 |
|
81 |
db_usage = {}
|
|
82 |
for path, node in account_nodes:
|
|
83 |
size = backend.node.node_account_usage(node, CLUSTER_NORMAL)
|
|
84 |
db_usage[path] = size or 0
|
|
78 |
users = set(db_usage.keys())
|
|
79 |
if userid and userid not in users:
|
|
80 |
self.stdout.write("User '%s' does not exist in DB!\n" % userid)
|
|
81 |
return
|
|
85 | 82 |
|
86 |
users = set(qh_result.keys()) |
|
87 |
users.update(db_usage.keys()) |
|
83 |
# Get holding from Quotaholder |
|
84 |
try: |
|
85 |
qh_result = backend.astakosclient.service_get_quotas( |
|
86 |
backend.service_token, userid) |
|
87 |
except NotFound: |
|
88 |
self.stdout.write( |
|
89 |
"User '%s' does not exist in Quotaholder!\n" % userid) |
|
90 |
return |
|
91 |
|
|
92 |
users.update(qh_result.keys()) |
|
88 | 93 |
|
89 | 94 |
pending_exists = False |
90 | 95 |
unknown_user_exists = False |
... | ... | |
95 | 100 |
qh_all = qh_result[uuid] |
96 | 101 |
except KeyError: |
97 | 102 |
self.stdout.write( |
98 |
"User '%s' does not exist in Quotaholder!\n" % uuid |
|
99 |
) |
|
103 |
"User '%s' does not exist in Quotaholder!\n" % uuid) |
|
100 | 104 |
unknown_user_exists = True |
101 | 105 |
continue |
102 | 106 |
else: |
... | ... | |
114 | 118 |
self.stdout.write( |
115 | 119 |
"Pending commission. " |
116 | 120 |
"User '%s', resource '%s'.\n" % |
117 |
(uuid, resource) |
|
118 |
) |
|
121 |
(uuid, resource)) |
|
119 | 122 |
pending_exists = True |
120 | 123 |
continue |
121 | 124 |
|
... | ... | |
146 | 149 |
if pending_exists: |
147 | 150 |
self.stdout.write( |
148 | 151 |
"Found pending commissions. Run 'snf-manage" |
149 |
" reconcile-commissions-pithos'\n" |
|
150 |
) |
|
152 |
" reconcile-commissions-pithos'\n") |
|
151 | 153 |
elif not (unsynced or unknown_user_exists): |
152 | 154 |
self.stdout.write("Everything in sync.\n") |
153 | 155 |
finally: |
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/node.py | ||
---|---|---|
480 | 480 |
r.close() |
481 | 481 |
return dict(rows) |
482 | 482 |
|
483 |
def node_account_usage(self, account_node, cluster): |
|
484 |
select_children = select( |
|
485 |
[self.nodes.c.node]).where(self.nodes.c.parent == account_node) |
|
486 |
select_descendants = select([self.nodes.c.node]).where( |
|
487 |
or_(self.nodes.c.parent.in_(select_children), |
|
488 |
self.nodes.c.node.in_(select_children))) |
|
489 |
s = select([func.sum(self.versions.c.size)]) |
|
490 |
s = s.where(self.nodes.c.node == self.versions.c.node) |
|
491 |
s = s.where(self.nodes.c.node.in_(select_descendants)) |
|
483 |
def node_account_usage(self, account=None, cluster=0): |
|
484 |
"""Return usage for a specific account. |
|
485 |
|
|
486 |
Keyword arguments: |
|
487 |
account -- (default None: list usage for all the accounts) |
|
488 |
cluster -- list current, history or deleted usage (default 0: normal) |
|
489 |
""" |
|
490 |
|
|
491 |
n1 = self.nodes.alias('n1') |
|
492 |
n2 = self.nodes.alias('n2') |
|
493 |
n3 = self.nodes.alias('n3') |
|
494 |
|
|
495 |
s = select([n3.c.path, func.sum(self.versions.c.size)]) |
|
496 |
s = s.where(n1.c.node == self.versions.c.node) |
|
492 | 497 |
s = s.where(self.versions.c.cluster == cluster) |
498 |
s = s.where(n1.c.parent == n2.c.node) |
|
499 |
s = s.where(n2.c.parent == n3.c.node) |
|
500 |
s = s.where(n3.c.parent == 0) |
|
501 |
s = s.where(n3.c.node != 0) |
|
502 |
if account: |
|
503 |
s = s.where(n3.c.path == account) |
|
504 |
s = s.group_by(n3.c.path) |
|
493 | 505 |
r = self.conn.execute(s) |
494 |
usage = r.fetchone()[0]
|
|
506 |
usage = r.fetchall()
|
|
495 | 507 |
r.close() |
496 |
return usage
|
|
508 |
return dict(usage)
|
|
497 | 509 |
|
498 | 510 |
def policy_get(self, node): |
499 | 511 |
s = select([self.policy.c.key, self.policy.c.value], |
b/snf-pithos-backend/pithos/backends/lib/sqlite/node.py | ||
---|---|---|
302 | 302 |
for r in self.fetchall(): |
303 | 303 |
hashes += [r[0]] |
304 | 304 |
serials += [r[1]] |
305 |
|
|
305 |
|
|
306 | 306 |
q = ("delete from versions " |
307 | 307 |
"where node in (select node " |
308 | 308 |
"from nodes " |
... | ... | |
402 | 402 |
) |
403 | 403 |
return dict(self.execute(q).fetchall()) |
404 | 404 |
|
405 |
def node_account_usage(self, account_node, cluster): |
|
406 |
select_children = ("select node from nodes where parent = ?") |
|
407 |
select_descedents = ("select node from nodes " |
|
408 |
"where parent in (%s) " |
|
409 |
"or node in (%s) ") % ((select_children,)*2) |
|
410 |
args = [account_node]*2 |
|
411 |
q = ("select sum(v.size) from versions v, nodes n " |
|
412 |
"where v.node = n.node " |
|
413 |
"and n.node in (%s) " |
|
414 |
"and v.cluster = ?") % select_descedents |
|
415 |
args += [cluster] |
|
405 |
def node_account_usage(self, account=None, cluster=0): |
|
406 |
"""Return usage for a specific account. |
|
416 | 407 |
|
408 |
Keyword arguments: |
|
409 |
account -- (default None: list usage for all the accounts) |
|
410 |
cluster -- list current, history or deleted usage (default 0: normal) |
|
411 |
""" |
|
412 |
|
|
413 |
q = ("select n3.path, sum(v.size) from " |
|
414 |
"versions v, nodes n1, nodes n2, nodes n3 " |
|
415 |
"where v.node = n1.node " |
|
416 |
"and v.cluster = ? " |
|
417 |
"and n1.parent = n2.node " |
|
418 |
"and n2.parent = n3.node " |
|
419 |
"and n3.parent = 0 " |
|
420 |
"and n3.node != 0 ") |
|
421 |
args = [cluster] |
|
422 |
if account: |
|
423 |
q += ("and n3.path = ? ") |
|
424 |
args += [account] |
|
425 |
q += ("group by n3.path") |
|
426 |
|
|
427 |
print '###', q, args |
|
417 | 428 |
self.execute(q, args) |
418 |
return self.fetchone()[0]
|
|
429 |
return dict(self.fetchall())
|
|
419 | 430 |
|
420 | 431 |
def policy_get(self, node): |
421 | 432 |
q = "select key, value from policy where node = ?" |
Also available in: Unified diff