93 |
93 |
holdings = []
|
94 |
94 |
append = holdings.append
|
95 |
95 |
|
96 |
|
for entity, resource in get_holding:
|
|
96 |
for holder, resource in get_holding:
|
97 |
97 |
try:
|
98 |
|
h = Holding.objects.get(entity=entity, resource=resource)
|
|
98 |
h = Holding.objects.get(holder=holder, resource=resource)
|
99 |
99 |
except Holding.DoesNotExist:
|
100 |
100 |
continue
|
101 |
101 |
|
102 |
|
append((h.entity, h.resource, h.policy.policy,
|
|
102 |
append((h.holder, h.resource, h.policy.policy,
|
103 |
103 |
h.imported, h.exported,
|
104 |
104 |
h.returned, h.released, h.flags))
|
105 |
105 |
|
... | ... | |
109 |
109 |
rejected = []
|
110 |
110 |
append = rejected.append
|
111 |
111 |
|
112 |
|
for entity, resource, policy, flags in set_holding:
|
|
112 |
for holder, resource, policy, flags in set_holding:
|
113 |
113 |
try:
|
114 |
114 |
p = Policy.objects.get(policy=policy)
|
115 |
115 |
except Policy.DoesNotExist:
|
116 |
|
append((entity, resource, policy))
|
|
116 |
append((holder, resource, policy))
|
117 |
117 |
continue
|
118 |
118 |
|
119 |
119 |
try:
|
120 |
|
h = db_get_holding(entity=entity, resource=resource,
|
|
120 |
h = db_get_holding(holder=holder, resource=resource,
|
121 |
121 |
for_update=True)
|
122 |
122 |
h.policy = p
|
123 |
123 |
h.flags = flags
|
124 |
124 |
h.save()
|
125 |
125 |
except Holding.DoesNotExist:
|
126 |
|
h = Holding.objects.create(entity=entity, resource=resource,
|
|
126 |
h = Holding.objects.create(holder=holder, resource=resource,
|
127 |
127 |
policy=p, flags=flags)
|
128 |
128 |
|
129 |
129 |
if rejected:
|
... | ... | |
131 |
131 |
return rejected
|
132 |
132 |
|
133 |
133 |
def _init_holding(self,
|
134 |
|
entity, resource, policy,
|
|
134 |
holder, resource, policy,
|
135 |
135 |
imported, exported, returned, released,
|
136 |
136 |
flags):
|
137 |
137 |
try:
|
138 |
|
h = db_get_holding(entity=entity, resource=resource,
|
|
138 |
h = db_get_holding(holder=holder, resource=resource,
|
139 |
139 |
for_update=True)
|
140 |
140 |
except Holding.DoesNotExist:
|
141 |
|
h = Holding(entity=entity, resource=resource)
|
|
141 |
h = Holding(holder=holder, resource=resource)
|
142 |
142 |
|
143 |
143 |
h.policy = policy
|
144 |
144 |
h.flags = flags
|
... | ... | |
157 |
157 |
append = rejected.append
|
158 |
158 |
|
159 |
159 |
for idx, sfh in enumerate(init_holding):
|
160 |
|
(entity, resource, policy,
|
|
160 |
(holder, resource, policy,
|
161 |
161 |
imported, exported, returned, released,
|
162 |
162 |
flags) = sfh
|
163 |
163 |
|
... | ... | |
167 |
167 |
append(idx)
|
168 |
168 |
continue
|
169 |
169 |
|
170 |
|
self._init_holding(entity, resource, p,
|
|
170 |
self._init_holding(holder, resource, p,
|
171 |
171 |
imported, exported,
|
172 |
172 |
returned, released,
|
173 |
173 |
flags)
|
... | ... | |
180 |
180 |
append = rejected.append
|
181 |
181 |
|
182 |
182 |
for idx, tpl in enumerate(reset_holding):
|
183 |
|
(entity, resource,
|
|
183 |
(holder, resource,
|
184 |
184 |
imported, exported, returned, released) = tpl
|
185 |
185 |
|
186 |
186 |
try:
|
187 |
|
h = db_get_holding(entity=entity, resource=resource,
|
|
187 |
h = db_get_holding(holder=holder, resource=resource,
|
188 |
188 |
for_update=True)
|
189 |
189 |
h.imported = imported
|
190 |
190 |
h.importing = imported
|
... | ... | |
203 |
203 |
raise QuotaholderError(rejected)
|
204 |
204 |
return rejected
|
205 |
205 |
|
206 |
|
def _check_pending(self, entity, resource):
|
207 |
|
cs = Commission.objects.filter(entity=entity)
|
|
206 |
def _check_pending(self, holder, resource):
|
|
207 |
cs = Commission.objects.filter(holder=holder)
|
208 |
208 |
cs = [c for c in cs if c.provisions.filter(resource=resource)]
|
209 |
209 |
as_target = [c.serial for c in cs]
|
210 |
210 |
|
211 |
|
ps = Provision.objects.filter(entity=entity, resource=resource)
|
|
211 |
ps = Provision.objects.filter(holder=holder, resource=resource)
|
212 |
212 |
as_source = [p.serial.serial for p in ps]
|
213 |
213 |
|
214 |
214 |
return as_target + as_source
|
... | ... | |
222 |
222 |
rejected = []
|
223 |
223 |
append = rejected.append
|
224 |
224 |
|
225 |
|
for idx, (entity, resource) in enumerate(release_holding):
|
|
225 |
for idx, (holder, resource) in enumerate(release_holding):
|
226 |
226 |
try:
|
227 |
|
h = db_get_holding(entity=entity, resource=resource,
|
|
227 |
h = db_get_holding(holder=holder, resource=resource,
|
228 |
228 |
for_update=True)
|
229 |
229 |
except Holding.DoesNotExist:
|
230 |
230 |
append(idx)
|
231 |
231 |
continue
|
232 |
232 |
|
233 |
|
if self._check_pending(entity, resource):
|
|
233 |
if self._check_pending(holder, resource):
|
234 |
234 |
append(idx)
|
235 |
235 |
continue
|
236 |
236 |
|
... | ... | |
245 |
245 |
raise QuotaholderError(rejected)
|
246 |
246 |
return rejected
|
247 |
247 |
|
248 |
|
def list_resources(self, context=None, entity=None):
|
249 |
|
holdings = Holding.objects.filter(entity=entity)
|
|
248 |
def list_resources(self, context=None, holder=None):
|
|
249 |
holdings = Holding.objects.filter(holder=holder)
|
250 |
250 |
resources = [h.resource for h in holdings]
|
251 |
251 |
return resources
|
252 |
252 |
|
... | ... | |
256 |
256 |
holdings_list = []
|
257 |
257 |
append = holdings_list.append
|
258 |
258 |
|
259 |
|
for entity in list_holdings:
|
260 |
|
holdings = list(Holding.objects.filter(entity=entity))
|
|
259 |
for holder in list_holdings:
|
|
260 |
holdings = list(Holding.objects.filter(holder=holder))
|
261 |
261 |
if not holdings:
|
262 |
|
reject(entity)
|
|
262 |
reject(holder)
|
263 |
263 |
continue
|
264 |
264 |
|
265 |
|
append([[entity, h.resource,
|
|
265 |
append([[holder, h.resource,
|
266 |
266 |
h.imported, h.exported, h.returned, h.released]
|
267 |
267 |
for h in holdings])
|
268 |
268 |
|
... | ... | |
272 |
272 |
quotas = []
|
273 |
273 |
append = quotas.append
|
274 |
274 |
|
275 |
|
entities = set(e for e, r in get_quota)
|
276 |
|
hs = Holding.objects.select_related().filter(entity__in=entities)
|
|
275 |
holders = set(holder for holder, r in get_quota)
|
|
276 |
hs = Holding.objects.select_related().filter(holder__in=holders)
|
277 |
277 |
holdings = {}
|
278 |
278 |
for h in hs:
|
279 |
|
holdings[(h.entity, h.resource)] = h
|
|
279 |
holdings[(h.holder, h.resource)] = h
|
280 |
280 |
|
281 |
|
for entity, resource in get_quota:
|
|
281 |
for holder, resource in get_quota:
|
282 |
282 |
try:
|
283 |
|
h = holdings[(entity, resource)]
|
|
283 |
h = holdings[(holder, resource)]
|
284 |
284 |
except:
|
285 |
285 |
continue
|
286 |
286 |
|
287 |
287 |
p = h.policy
|
288 |
288 |
|
289 |
|
append((h.entity, h.resource, p.quantity, p.capacity,
|
|
289 |
append((h.holder, h.resource, p.quantity, p.capacity,
|
290 |
290 |
p.import_limit, p.export_limit,
|
291 |
291 |
h.imported, h.exported,
|
292 |
292 |
h.returned, h.released,
|
... | ... | |
299 |
299 |
append = rejected.append
|
300 |
300 |
|
301 |
301 |
q_holdings = Q()
|
302 |
|
entities = []
|
303 |
|
for (entity, resource, _, _, _, _, _) in set_quota:
|
304 |
|
entities.append(entity)
|
|
302 |
holders = []
|
|
303 |
for (holder, resource, _, _, _, _, _) in set_quota:
|
|
304 |
holders.append(holder)
|
305 |
305 |
|
306 |
|
hs = Holding.objects.filter(entity__in=entities).select_for_update()
|
|
306 |
hs = Holding.objects.filter(holder__in=holders).select_for_update()
|
307 |
307 |
holdings = {}
|
308 |
308 |
for h in hs:
|
309 |
|
holdings[(h.entity, h.resource)] = h
|
|
309 |
holdings[(h.holder, h.resource)] = h
|
310 |
310 |
|
311 |
311 |
old_policies = []
|
312 |
312 |
|
313 |
|
for (entity, resource,
|
|
313 |
for (holder, resource,
|
314 |
314 |
quantity, capacity,
|
315 |
315 |
import_limit, export_limit, flags) in set_quota:
|
316 |
316 |
|
... | ... | |
322 |
322 |
export_limit=export_limit)
|
323 |
323 |
|
324 |
324 |
try:
|
325 |
|
h = holdings[(entity, resource)]
|
|
325 |
h = holdings[(holder, resource)]
|
326 |
326 |
old_policies.append(h.policy_id)
|
327 |
327 |
h.policy = newp
|
328 |
328 |
h.flags = flags
|
329 |
329 |
except KeyError:
|
330 |
|
h = Holding(entity=entity, resource=resource,
|
|
330 |
h = Holding(holder=holder, resource=resource,
|
331 |
331 |
policy=newp, flags=flags)
|
332 |
332 |
|
333 |
333 |
# the order is intentionally reversed so that it
|
... | ... | |
335 |
335 |
# Has helped before.
|
336 |
336 |
h.save()
|
337 |
337 |
newp.save()
|
338 |
|
holdings[(entity, resource)] = h
|
|
338 |
holdings[(holder, resource)] = h
|
339 |
339 |
|
340 |
340 |
objs = Policy.objects.annotate(refs=Count('holding'))
|
341 |
341 |
objs.filter(policy__in=old_policies, refs=0).delete()
|
... | ... | |
363 |
363 |
|
364 |
364 |
sources = sub_quota + add_quota
|
365 |
365 |
q_holdings = Q()
|
366 |
|
entities = []
|
367 |
|
for (entity, resource, _, _, _, _) in sources:
|
368 |
|
entities.append(entity)
|
|
366 |
holders = []
|
|
367 |
for (holder, resource, _, _, _, _) in sources:
|
|
368 |
holders.append(holder)
|
369 |
369 |
|
370 |
|
hs = Holding.objects.filter(entity__in=entities).select_for_update()
|
|
370 |
hs = Holding.objects.filter(holder__in=holders).select_for_update()
|
371 |
371 |
holdings = {}
|
372 |
372 |
for h in hs:
|
373 |
|
holdings[(h.entity, h.resource)] = h
|
|
373 |
holdings[(h.holder, h.resource)] = h
|
374 |
374 |
|
375 |
375 |
pids = [h.policy_id for h in hs]
|
376 |
376 |
policies = Policy.objects.in_bulk(pids)
|
... | ... | |
378 |
378 |
old_policies = []
|
379 |
379 |
|
380 |
380 |
for removing, source in [(True, sub_quota), (False, add_quota)]:
|
381 |
|
for (entity, resource,
|
|
381 |
for (holder, resource,
|
382 |
382 |
quantity, capacity,
|
383 |
383 |
import_limit, export_limit) in source:
|
384 |
384 |
|
385 |
385 |
try:
|
386 |
|
h = holdings[(entity, resource)]
|
|
386 |
h = holdings[(holder, resource)]
|
387 |
387 |
old_policies.append(h.policy_id)
|
388 |
388 |
try:
|
389 |
389 |
p = policies[h.policy_id]
|
... | ... | |
391 |
391 |
raise AssertionError("no policy %s" % h.policy_id)
|
392 |
392 |
except KeyError:
|
393 |
393 |
if removing:
|
394 |
|
append((entity, resource))
|
|
394 |
append((holder, resource))
|
395 |
395 |
continue
|
396 |
396 |
|
397 |
|
h = Holding(entity=entity, resource=resource, flags=0)
|
|
397 |
h = Holding(holder=holder, resource=resource, flags=0)
|
398 |
398 |
p = None
|
399 |
399 |
|
400 |
400 |
policy = newname('policy_')
|
... | ... | |
412 |
412 |
new_values = [newp.capacity,
|
413 |
413 |
newp.import_limit, newp.export_limit]
|
414 |
414 |
if any(map(_isneg, new_values)):
|
415 |
|
append((entity, resource))
|
|
415 |
append((holder, resource))
|
416 |
416 |
continue
|
417 |
417 |
|
418 |
418 |
h.policy = newp
|
... | ... | |
423 |
423 |
h.save()
|
424 |
424 |
newp.save()
|
425 |
425 |
policies[policy] = newp
|
426 |
|
holdings[(entity, resource)] = h
|
|
426 |
holdings[(holder, resource)] = h
|
427 |
427 |
|
428 |
428 |
objs = Policy.objects.annotate(refs=Count('holding'))
|
429 |
429 |
objs.filter(policy__in=old_policies, refs=0).delete()
|
... | ... | |
477 |
477 |
provisions=()):
|
478 |
478 |
|
479 |
479 |
create = Commission.objects.create
|
480 |
|
commission = create(entity=target, clientkey=clientkey, name=name)
|
|
480 |
commission = create(holder=target, clientkey=clientkey, name=name)
|
481 |
481 |
serial = commission.serial
|
482 |
482 |
|
483 |
483 |
checked = []
|
484 |
|
for entity, resource, quantity in provisions:
|
|
484 |
for holder, resource, quantity in provisions:
|
485 |
485 |
|
486 |
|
if entity == target:
|
487 |
|
m = "Cannot issue commission from an entity to itself (%s)" % (
|
488 |
|
entity,)
|
|
486 |
if holder == target:
|
|
487 |
m = "Cannot issue commission from an holder to itself (%s)" % (
|
|
488 |
holder,)
|
489 |
489 |
raise InvalidDataError(m)
|
490 |
490 |
|
491 |
|
ent_res = entity, resource
|
|
491 |
ent_res = holder, resource
|
492 |
492 |
if ent_res in checked:
|
493 |
493 |
m = "Duplicate provision for %s.%s" % ent_res
|
494 |
494 |
raise DuplicateError(m)
|
... | ... | |
500 |
500 |
|
501 |
501 |
# Source limits checks
|
502 |
502 |
try:
|
503 |
|
h = db_get_holding(entity=entity, resource=resource,
|
|
503 |
h = db_get_holding(holder=holder, resource=resource,
|
504 |
504 |
for_update=True)
|
505 |
505 |
except Holding.DoesNotExist:
|
506 |
506 |
m = ("There is no quantity "
|
507 |
|
"to allocate from in %s.%s" % (entity, resource))
|
|
507 |
"to allocate from in %s.%s" % (holder, resource))
|
508 |
508 |
raise NoQuantityError(m,
|
509 |
|
source=entity, target=target,
|
|
509 |
source=holder, target=target,
|
510 |
510 |
resource=resource, requested=quantity,
|
511 |
511 |
current=0, limit=0)
|
512 |
512 |
|
... | ... | |
516 |
516 |
current = h.exporting
|
517 |
517 |
limit = hp.export_limit
|
518 |
518 |
if current + quantity > limit:
|
519 |
|
m = ("Export limit reached for %s.%s" % (entity, resource))
|
|
519 |
m = ("Export limit reached for %s.%s" % (holder, resource))
|
520 |
520 |
raise ExportLimitError(m,
|
521 |
|
source=entity,
|
|
521 |
source=holder,
|
522 |
522 |
target=target,
|
523 |
523 |
resource=resource,
|
524 |
524 |
requested=quantity,
|
... | ... | |
531 |
531 |
|
532 |
532 |
if quantity > available:
|
533 |
533 |
m = ("There is not enough quantity "
|
534 |
|
"to allocate from in %s.%s" % (entity, resource))
|
|
534 |
"to allocate from in %s.%s" % (holder, resource))
|
535 |
535 |
raise NoQuantityError(m,
|
536 |
|
source=entity,
|
|
536 |
source=holder,
|
537 |
537 |
target=target,
|
538 |
538 |
resource=resource,
|
539 |
539 |
requested=quantity,
|
... | ... | |
545 |
545 |
limit = hp.capacity
|
546 |
546 |
if current - quantity > limit:
|
547 |
547 |
m = ("There is not enough capacity "
|
548 |
|
"to release to in %s.%s" % (entity, resource))
|
|
548 |
"to release to in %s.%s" % (holder, resource))
|
549 |
549 |
raise NoQuantityError(m,
|
550 |
|
source=entity,
|
|
550 |
source=holder,
|
551 |
551 |
target=target,
|
552 |
552 |
resource=resource,
|
553 |
553 |
requested=quantity,
|
... | ... | |
556 |
556 |
|
557 |
557 |
# Target limits checks
|
558 |
558 |
try:
|
559 |
|
th = db_get_holding(entity=target, resource=resource,
|
|
559 |
th = db_get_holding(holder=target, resource=resource,
|
560 |
560 |
for_update=True)
|
561 |
561 |
except Holding.DoesNotExist:
|
562 |
562 |
m = ("There is no capacity "
|
563 |
563 |
"to allocate into in %s.%s" % (target, resource))
|
564 |
564 |
raise NoCapacityError(m,
|
565 |
|
source=entity,
|
|
565 |
source=holder,
|
566 |
566 |
target=target,
|
567 |
567 |
resource=resource,
|
568 |
568 |
requested=quantity,
|
... | ... | |
577 |
577 |
if current + quantity > limit:
|
578 |
578 |
m = ("Import limit reached for %s.%s" % (target, resource))
|
579 |
579 |
raise ImportLimitError(m,
|
580 |
|
source=entity,
|
|
580 |
source=holder,
|
581 |
581 |
target=target,
|
582 |
582 |
resource=resource,
|
583 |
583 |
requested=quantity,
|
... | ... | |
592 |
592 |
m = ("There is not enough capacity "
|
593 |
593 |
"to allocate into in %s.%s" % (target, resource))
|
594 |
594 |
raise NoCapacityError(m,
|
595 |
|
source=entity,
|
|
595 |
source=holder,
|
596 |
596 |
target=target,
|
597 |
597 |
resource=resource,
|
598 |
598 |
requested=quantity,
|
... | ... | |
607 |
607 |
m = ("There is not enough quantity "
|
608 |
608 |
"to release from in %s.%s" % (target, resource))
|
609 |
609 |
raise NoCapacityError(m,
|
610 |
|
source=entity,
|
|
610 |
source=holder,
|
611 |
611 |
target=target,
|
612 |
612 |
resource=resource,
|
613 |
613 |
requested=quantity,
|
... | ... | |
615 |
615 |
limit=limit)
|
616 |
616 |
|
617 |
617 |
Provision.objects.create(serial=commission,
|
618 |
|
entity=entity,
|
|
618 |
holder=holder,
|
619 |
619 |
resource=resource,
|
620 |
620 |
quantity=quantity)
|
621 |
621 |
if release:
|
... | ... | |
634 |
634 |
commission, s_holding, t_holding,
|
635 |
635 |
provision, log_time, reason):
|
636 |
636 |
|
637 |
|
s_entity = s_holding.entity
|
|
637 |
s_holder = s_holding.holder
|
638 |
638 |
s_policy = s_holding.policy
|
639 |
|
t_entity = t_holding.entity
|
|
639 |
t_holder = t_holding.holder
|
640 |
640 |
t_policy = t_holding.policy
|
641 |
641 |
|
642 |
642 |
kwargs = {
|
643 |
643 |
'serial': commission.serial,
|
644 |
644 |
'name': commission.name,
|
645 |
|
'source': s_entity,
|
646 |
|
'target': t_entity,
|
|
645 |
'source': s_holder,
|
|
646 |
'target': t_holder,
|
647 |
647 |
'resource': provision.resource,
|
648 |
648 |
'source_quantity': s_policy.quantity,
|
649 |
649 |
'source_capacity': s_policy.capacity,
|
... | ... | |
681 |
681 |
except Commission.DoesNotExist:
|
682 |
682 |
return
|
683 |
683 |
|
684 |
|
t = c.entity
|
|
684 |
t = c.holder
|
685 |
685 |
|
686 |
686 |
provisions = db_filter_provision(serial=serial, for_update=True)
|
687 |
687 |
for pv in provisions:
|
688 |
688 |
try:
|
689 |
|
h = db_get_holding(entity=pv.entity,
|
|
689 |
h = db_get_holding(holder=pv.holder,
|
690 |
690 |
resource=pv.resource, for_update=True)
|
691 |
|
th = db_get_holding(entity=t, resource=pv.resource,
|
|
691 |
th = db_get_holding(holder=t, resource=pv.resource,
|
692 |
692 |
for_update=True)
|
693 |
693 |
except Holding.DoesNotExist:
|
694 |
694 |
m = "Corrupted provision"
|
... | ... | |
727 |
727 |
except Commission.DoesNotExist:
|
728 |
728 |
return
|
729 |
729 |
|
730 |
|
t = c.entity
|
|
730 |
t = c.holder
|
731 |
731 |
|
732 |
732 |
provisions = db_filter_provision(serial=serial, for_update=True)
|
733 |
733 |
for pv in provisions:
|
734 |
734 |
try:
|
735 |
|
h = db_get_holding(entity=pv.entity,
|
|
735 |
h = db_get_holding(holder=pv.holder,
|
736 |
736 |
resource=pv.resource, for_update=True)
|
737 |
|
th = db_get_holding(entity=t, resource=pv.resource,
|
|
737 |
th = db_get_holding(holder=t, resource=pv.resource,
|
738 |
738 |
for_update=True)
|
739 |
739 |
except Holding.DoesNotExist:
|
740 |
740 |
m = "Corrupted provision"
|
... | ... | |
789 |
789 |
return
|
790 |
790 |
|
791 |
791 |
def get_timeline(self, context=None, after="", before="Z", get_timeline=()):
|
792 |
|
entity_set = set()
|
793 |
|
e_add = entity_set.add
|
|
792 |
holder_set = set()
|
|
793 |
e_add = holder_set.add
|
794 |
794 |
resource_set = set()
|
795 |
795 |
r_add = resource_set.add
|
796 |
796 |
|
797 |
|
for entity, resource in get_timeline:
|
798 |
|
if entity not in entity_set:
|
799 |
|
e_add(entity)
|
|
797 |
for holder, resource in get_timeline:
|
|
798 |
if holder not in holder_set:
|
|
799 |
e_add(holder)
|
800 |
800 |
|
801 |
|
r_add((entity, resource))
|
|
801 |
r_add((holder, resource))
|
802 |
802 |
|
803 |
803 |
chunk_size = 65536
|
804 |
804 |
nr = 0
|
805 |
805 |
timeline = []
|
806 |
806 |
append = timeline.append
|
807 |
807 |
filterlogs = ProvisionLog.objects.filter
|
808 |
|
if entity_set:
|
809 |
|
q_entity = Q(source__in=entity_set) | Q(target__in=entity_set)
|
|
808 |
if holder_set:
|
|
809 |
q_holder = Q(source__in=holder_set) | Q(target__in=holder_set)
|
810 |
810 |
else:
|
811 |
|
q_entity = Q()
|
|
811 |
q_holder = Q()
|
812 |
812 |
|
813 |
813 |
while 1:
|
814 |
|
logs = filterlogs(q_entity,
|
|
814 |
logs = filterlogs(q_holder,
|
815 |
815 |
issue_time__gt=after,
|
816 |
816 |
issue_time__lte=before,
|
817 |
817 |
reason__startswith='ACCEPT:')
|