root / test / pgerakios.py @ e0c7f0ba
History | View | Annotate | Download (27.8 kB)
1 |
#!/usr/bin/env python
|
---|---|
2 |
import sys |
3 |
import os |
4 |
from commissioning.clients.http import HTTP_API_Client, init_logger_stderr |
5 |
from commissioning import QuotaholderAPI |
6 |
import random |
7 |
import copy |
8 |
import inspect |
9 |
|
10 |
|
11 |
init_logger_stderr('mylogger', level='INFO') |
12 |
|
13 |
def environ_get(key, default_value=''): |
14 |
if os.environ.has_key(key):
|
15 |
return os.environ.get(key)
|
16 |
else:
|
17 |
return default_value
|
18 |
|
19 |
QH_HOST = environ_get("TEST_QH_HOST", environ_get("QH_HOST", "127.0.0.1")) |
20 |
QH_PORT = environ_get("TEST_QH_PORT", environ_get("QH_PORT", "8008")) |
21 |
QH_DEBUG = True
|
22 |
|
23 |
assert QH_HOST != None |
24 |
assert QH_PORT != None |
25 |
|
26 |
def printf(fmt, *args): |
27 |
global QH_DEBUG
|
28 |
if(QH_DEBUG):
|
29 |
print(fmt.format(*args)) |
30 |
return 0 |
31 |
|
32 |
|
33 |
def exn(fmt, *args): |
34 |
raise Exception(fmt.format(*args)) |
35 |
|
36 |
|
37 |
def cexn(b, fmt, *args): |
38 |
if(b):
|
39 |
raise Exception(fmt.format(*args)) |
40 |
|
41 |
printf("Will connect to QH_HOST = {0}", QH_HOST)
|
42 |
printf(" and QH_PORT = {0}", QH_PORT)
|
43 |
|
44 |
QH_URL = "http://{0}:{1}/api/quotaholder/v".format(QH_HOST, QH_PORT)
|
45 |
|
46 |
def new_qh_client(): |
47 |
"""
|
48 |
Create a new quota holder api client
|
49 |
"""
|
50 |
|
51 |
class QuotaholderHTTP(HTTP_API_Client): |
52 |
api_spec = QuotaholderAPI() |
53 |
|
54 |
global QH_URL
|
55 |
return QuotaholderHTTP(QH_URL)
|
56 |
|
57 |
|
58 |
def rand_string(): |
59 |
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
60 |
min = 5
|
61 |
max = 15
|
62 |
string = ''
|
63 |
for x in random.sample(alphabet, random.randint(min, max)): |
64 |
string += x |
65 |
return string
|
66 |
|
67 |
|
68 |
def enum(*sequential, **named): |
69 |
enums = dict(zip(sequential, range(len(sequential))), **named) |
70 |
return type('Enum', (), enums) |
71 |
|
72 |
|
73 |
def find(f, seq): |
74 |
for item in seq: |
75 |
if f(item):
|
76 |
return item
|
77 |
return None |
78 |
|
79 |
def split(f, seq): |
80 |
a = [] |
81 |
b = [] |
82 |
for item in seq: |
83 |
if f(item):
|
84 |
a.append(item) |
85 |
else:
|
86 |
b.append(item) |
87 |
return (a, b)
|
88 |
|
89 |
|
90 |
class Client(object): |
91 |
qh = new_qh_client() |
92 |
clientKey = rand_string() |
93 |
|
94 |
@staticmethod
|
95 |
def get(): |
96 |
return Client.qh
|
97 |
|
98 |
#getPending
|
99 |
@staticmethod
|
100 |
def getPending(): |
101 |
#get_pending_commissions
|
102 |
pass
|
103 |
|
104 |
#
|
105 |
@staticmethod
|
106 |
def removePending(): |
107 |
#resolve_pending_commissions
|
108 |
pass
|
109 |
|
110 |
|
111 |
class Config(object): |
112 |
Context = {} |
113 |
Flags = 0
|
114 |
|
115 |
@staticmethod
|
116 |
def con(): |
117 |
return Client.get()
|
118 |
|
119 |
|
120 |
class Policy(Config): |
121 |
|
122 |
PolicyState = enum('NOT_EXISTS', 'EXISTS', 'DUMMY') |
123 |
|
124 |
policies = {} |
125 |
|
126 |
@staticmethod
|
127 |
def copy(policy): |
128 |
return copy.deepcopy(policy)
|
129 |
|
130 |
@staticmethod
|
131 |
def union(policy1,policy2): |
132 |
return copy(policy1)
|
133 |
|
134 |
@staticmethod
|
135 |
def get(name): |
136 |
#TODO:
|
137 |
exn("Not implemented")
|
138 |
|
139 |
# Dummy policies are neither loaded nor saved.
|
140 |
@staticmethod
|
141 |
def newDummy(**kwargs): |
142 |
p = Policy(**kwargs) |
143 |
p.exist = Policy.PolicyState.DUMMY |
144 |
return p
|
145 |
|
146 |
@staticmethod
|
147 |
def splitRejected(policyList, rejectedList): |
148 |
(a, b) = split((lambda p: p.policyName not in rejectedList), policyList) |
149 |
if(b != []):
|
150 |
printf("Rejected entities (call to set_limits): {0}", rejectedList)
|
151 |
return (a, b)
|
152 |
|
153 |
@staticmethod
|
154 |
def splitAccepted(policyList, acceptedList): |
155 |
acceptedListNames = [x[0] for x in acceptedList] |
156 |
(a, b) = split((lambda p: p.policyName in acceptedListNames), policyList) |
157 |
if(b != []):
|
158 |
printf("Accepted entities (call to get_limits): {0}", acceptedList)
|
159 |
return (a, b)
|
160 |
|
161 |
@staticmethod
|
162 |
def saveMany(policyList): |
163 |
inputList = [(p.policyName, p.quantity, p.capacity, p.importLimit, p.exportLimit) |
164 |
for p in policyList if(p.valid() and not p.isDummy())] |
165 |
rejectedList = Policy.con().set_limits(context=Policy.Context, set_limits=inputList) |
166 |
ok, notok = Policy.splitRejected(policyList, rejectedList) |
167 |
for p in ok: |
168 |
p.exist = Policy.PolicyState.EXISTS |
169 |
for p in notok: |
170 |
if(p.exist == Policy.EXISTS):
|
171 |
p.exist = Policy.PolicyState.NOT_EXISTS |
172 |
return notok
|
173 |
|
174 |
@staticmethod
|
175 |
def loadMany(policyList): |
176 |
inputList = [p.policyName for p in policyList if(not p.isDummy())] |
177 |
acceptedList = Policy.con().get_limits(context=Policy.Context, get_limits=inputList) |
178 |
(ok, notok) = Policy.splitAccepted(policyList, acceptedList) |
179 |
# fill the policy
|
180 |
for p in ok: |
181 |
p.exist = Policy.PolicyState.EXISTS |
182 |
g = find((lambda x: x[0]), acceptedList) |
183 |
p.quantity = g[1]
|
184 |
p.capacity = g[2]
|
185 |
p.importLimit = g[3]
|
186 |
p.exportLimit = g[4]
|
187 |
for p in notok: |
188 |
if(p.exist == Policy.EXISTS):
|
189 |
p.exist = Policy.PolicyState.NOT_EXISTS |
190 |
|
191 |
return notok
|
192 |
|
193 |
def reset(self): |
194 |
self.set(None, 0, 0, 0, 0) |
195 |
|
196 |
def set(self, name, q, c, i, e): |
197 |
self.policyName = name
|
198 |
self.quantity = q
|
199 |
self.capacity = c
|
200 |
self.importLimit = i
|
201 |
self.exportLimit = e
|
202 |
self.exist = Policy.PolicyState.NOT_EXISTS
|
203 |
|
204 |
def __init__(self, **kwargs): |
205 |
self.policyName = None |
206 |
self.reset()
|
207 |
self.__dict__.update(kwargs)
|
208 |
|
209 |
|
210 |
def isDummy(self): |
211 |
return self.exist == Policy.PolicyState.DUMMY |
212 |
|
213 |
|
214 |
def setDummy(self,v=True): |
215 |
if(v):
|
216 |
self.exist = Policy.PolicyState.DUMMY
|
217 |
else:
|
218 |
self.exist = Policy.PolicyState.NOT_EXISTS
|
219 |
|
220 |
def name(self): |
221 |
return self.policyName |
222 |
|
223 |
|
224 |
def valid(self): |
225 |
return self.policyName == None or self.quantity == None or self.capacity == None or self.importLimit == None or self.exportLimit == None |
226 |
|
227 |
|
228 |
def setExists(self,v=True): |
229 |
if(v):
|
230 |
self.exist = Policy.PolicyState.EXISTS
|
231 |
else:
|
232 |
self.exist = Policy.PolicyState.NOT_EXISTS
|
233 |
|
234 |
def exists(self): |
235 |
return self.exist |
236 |
|
237 |
def __eq__(self, other): |
238 |
if isinstance(other, Policy): |
239 |
return self.policyName == other.policyName |
240 |
elif isinstance(other, basestring): |
241 |
return self.policyName == other |
242 |
else:
|
243 |
return False |
244 |
|
245 |
def __ne__(self, other): |
246 |
return not (self.__eq__(other)) |
247 |
|
248 |
|
249 |
def load(self): |
250 |
if(self.isDummy()): |
251 |
return True |
252 |
else:
|
253 |
return Policy.loadMany([self]) == [] |
254 |
|
255 |
|
256 |
def save(self): |
257 |
if(self.isDummy()): |
258 |
return True |
259 |
else:
|
260 |
return Policy.saveMany([self]) == [] |
261 |
|
262 |
|
263 |
class Resource(Config): |
264 |
|
265 |
ResourceState = enum('DIRTY', 'LOADED') |
266 |
|
267 |
@staticmethod
|
268 |
def copy(resource): |
269 |
return copy.copy(resource)
|
270 |
|
271 |
@staticmethod
|
272 |
def allDirty(resourceList): |
273 |
for r in resourceList: |
274 |
r.setDirty() |
275 |
|
276 |
# When a dummy policy is used, the policy is also loaded by get_quota
|
277 |
# if it is a normal policy only the resource is loaded but not the corresponding
|
278 |
@staticmethod
|
279 |
def loadMany(resourceList0,dirtyOnly=True): |
280 |
if(dirtyOnly):
|
281 |
resourceList = [r for r in resourceList0 if(r.isDirty())] |
282 |
else:
|
283 |
resourceList = resourceList0 |
284 |
#
|
285 |
(rl1,rl2) = split((lambda r: r.policy.isDummy()),resourceList)
|
286 |
#
|
287 |
iList1 = [(r.entity.entityName, r.resourceName, r.entity.entityKey) for r in rl1] |
288 |
if(iList1 == []):
|
289 |
oList1 = [] |
290 |
else:
|
291 |
oList1 = Resource.con().get_quota(context=Resource.Context, get_quota=iList1) |
292 |
for e, res, q, c, il, el, p, i, e, r1, r2, f in oList1: |
293 |
res1 = find((lambda r: r.resourceName == res), rl1)
|
294 |
res1.imported = i |
295 |
res1.exported = e |
296 |
res1.returned = r1 |
297 |
res1.released = r2 |
298 |
res1.flags = f |
299 |
res1.policy.quantity = q |
300 |
res1.policy.capacity = c |
301 |
res1.policy.importLimit = il |
302 |
res1.policy.exportLimit = el |
303 |
res1.state = Resource.ResourceState.LOADED |
304 |
#
|
305 |
iList2 = [(r.entity.entityName,r.resourceName,r.entity.entityKey) for r in rl2] |
306 |
if(iList2 == []):
|
307 |
oList2 = [] |
308 |
else:
|
309 |
oList2 = Resource.con().get_holding(context=Resource.Context,get_holding=iList2) |
310 |
for e,res,p,im,ex,ret,rel,f in oList2: |
311 |
res1 = find((lambda r: r.resourceName == res), rl2)
|
312 |
res1.imported = im |
313 |
res1.exported = ex |
314 |
res1.returned = ret |
315 |
res1.released = rel |
316 |
res1.flags = f |
317 |
res1.state = Resource.ResourceState.LOADED |
318 |
#
|
319 |
rejectedList = [r for r in resourceList if(r.resourceName not in oList1 and r.resourceName not in oList2)] |
320 |
return rejectedList
|
321 |
|
322 |
# set_holding or set_quota (if dummy)
|
323 |
@staticmethod
|
324 |
def saveMany(resourceList0,dirtyOnly=True): |
325 |
if(dirtyOnly):
|
326 |
resourceList = [r for r in resourceList0 if(r.isDirty())] |
327 |
else:
|
328 |
resourceList = resourceList0 |
329 |
#
|
330 |
(rl1, rl2) = split((lambda r: not r.policy.isDummy()), resourceList) |
331 |
#
|
332 |
if(rl1 == []):
|
333 |
ol1 = [] |
334 |
else:
|
335 |
il1 = [(r.entity.entityName, r.resourceName, r.entity.entityKey,r.policy.quantity, |
336 |
r.policy.capacity,r.policy.importLimit,r.policy.ExportLimit,Resource.Flags) for r in rl1] |
337 |
ol1 = Resource.con().set_quota(context=Resource.Context,set_quota=il1) |
338 |
|
339 |
if(rl2 == []):
|
340 |
ol2 = [] |
341 |
else:
|
342 |
il2 = [(r.entity.entityName,r.resourceName,r.entity.entityKey,r.policy.policyName) for r in rl2] |
343 |
ol2 = Resource.con().set_holding(context=Resource.Context,set_holding=il2) |
344 |
|
345 |
rejectedList = [] |
346 |
|
347 |
|
348 |
#TODO:
|
349 |
|
350 |
# 1. set_holding
|
351 |
# 2. rejected lists
|
352 |
|
353 |
if(rl2 == []):
|
354 |
ol2 = [] |
355 |
else:
|
356 |
ol2 = [] |
357 |
#
|
358 |
#
|
359 |
#TODO
|
360 |
|
361 |
|
362 |
def isDirty(self): |
363 |
return self.state == Resource.ResourceState.DIRTY |
364 |
|
365 |
def setDirty(self,val=True): |
366 |
if(val):
|
367 |
self.state = Resource.ResourceState.DIRTY
|
368 |
else:
|
369 |
self.state = Resource.ResourceState.LOADED
|
370 |
|
371 |
def set(self,**kwargs): |
372 |
self.__dict__.update(kwargs)
|
373 |
self.setDirty()
|
374 |
|
375 |
def __init__(self,name,entity): |
376 |
self.resourceName = name
|
377 |
self.entity = entity
|
378 |
self.policy = None |
379 |
self.imported = 0 |
380 |
self.exported = 0 |
381 |
self.returned = 0 |
382 |
self.released = 0 |
383 |
self.flags = 0 |
384 |
self.state = Resource.ResourceState.DIRTY
|
385 |
self.setPolicy(Policy.newDummy())
|
386 |
|
387 |
def __eq__(self, other): |
388 |
if isinstance(other, Resource): |
389 |
return self.resourceName == other.resourceName |
390 |
elif isinstance(other, basestring): |
391 |
return self.resourceName == other |
392 |
else:
|
393 |
return False |
394 |
|
395 |
def __ne__(self, other): |
396 |
return not (self.__eq__(other)) |
397 |
|
398 |
|
399 |
def name(self): |
400 |
return self.resourceName |
401 |
|
402 |
|
403 |
def policy(self, query=False): |
404 |
if(query):
|
405 |
self.load()
|
406 |
return self.policy |
407 |
|
408 |
|
409 |
def setPolicy(self, policy): |
410 |
self.policy = policy
|
411 |
self.setDirty(True) |
412 |
|
413 |
def setFromPolicy(self): |
414 |
self.set(quantity=self.policy.quantity,capacity=self.policy.capacity) |
415 |
|
416 |
def quantity(self, query=False): |
417 |
if(query):
|
418 |
self.load()
|
419 |
#FIXME: Is this correct ?
|
420 |
return self.policy.quantity |
421 |
|
422 |
|
423 |
def load(self,dirtyOnly=True): |
424 |
if(not self.policy.isDummy()): |
425 |
self.policy.load()
|
426 |
return Resource.loadMany([self],dirtyOnly) == [] |
427 |
|
428 |
def save(self,dirtyOnly=True): |
429 |
return Resource.saveMany([self],dirtyOnly) == [] |
430 |
|
431 |
|
432 |
class Commission(Config): |
433 |
CommissionState = enum('NOT_ISSUED', 'PENDING', 'ACCEPTED', 'REJECTED') |
434 |
|
435 |
@staticmethod
|
436 |
def saveAll(comList): |
437 |
inputList = [c.serial for c in comList if(c.isPending())] |
438 |
rejectedList = Commission.con().accept_commission(context=Commission.Context, |
439 |
clientKey=Client.clientKey, |
440 |
serials=inputList, reason='ACCEPT')
|
441 |
for c in inputList: |
442 |
c.state = Commission.CommissionState.ACCEPTED |
443 |
#TODO: not implemented yet because the API does not support this.
|
444 |
return [c for c in comList if(c not in inputList)] |
445 |
|
446 |
@staticmethod
|
447 |
def denyAll(comList): |
448 |
inputList = [c.serial for c in comList if(c.isPending())] |
449 |
rejectedList = Commission.con().accept_commission(context=Commission.Context, |
450 |
clientKey=Client.clientKey, |
451 |
serials=inputList, reason='REJECT')
|
452 |
for c in inputList: |
453 |
c.state = Commission.CommissionState.REJECTED |
454 |
#TODO: not implemented yet because the API does not support this.
|
455 |
return [c for c in comList if(c not in inputList)] |
456 |
|
457 |
def __init__(self, target): |
458 |
self.clientKey = Client.clientKey
|
459 |
self.serial = None |
460 |
self.state = Commission.CommissionState.NOT_ISSUED
|
461 |
self.resources_quant = []
|
462 |
self.target = target
|
463 |
|
464 |
def __eq__(self, other): |
465 |
if isinstance(other, Commission): |
466 |
return self.serial == other.serial |
467 |
elif isinstance(other, int): |
468 |
return self.serial == other |
469 |
else:
|
470 |
return False |
471 |
|
472 |
def __ne__(self, other): |
473 |
return not (self.__eq__(other)) |
474 |
|
475 |
|
476 |
def inverse(self): |
477 |
ret = copy.copy(self)
|
478 |
ret.resources_quant = [(r,-q) for r,q in ret.resources_quant] |
479 |
return ret
|
480 |
|
481 |
def canChange(self): |
482 |
return self.state == Commission.CommissionState.NOT_ISSUED |
483 |
|
484 |
|
485 |
def isPending(self): |
486 |
return self.state == Commission.CommissionState.PENDING |
487 |
|
488 |
|
489 |
def issue(self): |
490 |
prov = [(r.entity.entityName, r.resourceName, q) for r, q in self.resources_quant] |
491 |
self.serial = Commission.con().issue_commission(context=Commission.Context,
|
492 |
target=self.target.entityName,
|
493 |
clientKey=Client.clientKey, |
494 |
owner=self.target.parent.entityName,
|
495 |
ownerKey=self.target.parent.entityKey,
|
496 |
provisions=prov) |
497 |
self.state = Commission.CommissionState.PENDING
|
498 |
return True |
499 |
|
500 |
|
501 |
def accept(self): |
502 |
return Commission.saveAll([self]) == [] |
503 |
|
504 |
def reject(self): |
505 |
return Commission.denyAll([self]) == [] |
506 |
|
507 |
#TODO: assert that resource.entity is the same as self.entity !!
|
508 |
|
509 |
|
510 |
def addResource(self, resource, quantity): |
511 |
cexn(self.state != Commission.CommissionState.NOT_ISSUED,
|
512 |
"Attempted to add a resource to a commission that has been issued.")
|
513 |
cexn(resource in [r for r, q in self.resources_quant], |
514 |
"Resource {0} already exists in commission.", resource.resourceName)
|
515 |
cexn(resource.quantity() < quantity, |
516 |
"Insufficient quantity: Resource {0} quantity is {1} but {2} is required.",
|
517 |
resource.resourceName, resource.quantity(), quantity) |
518 |
self.resources_quant.append((resource, quantity))
|
519 |
return True |
520 |
|
521 |
|
522 |
class Entity(Config): |
523 |
# static field (in some sense --- if it is assigned it will create a new binding)
|
524 |
EntityState = enum('NOT_EXISTS', 'EXISTS') |
525 |
|
526 |
allEntities = {} |
527 |
|
528 |
@staticmethod
|
529 |
def getClass(className,name="", key="", parent=None): |
530 |
e = Entity.allEntities.get(name) |
531 |
if(e == None): |
532 |
e = locals()[className]()
|
533 |
if(name == "system" or name == ""): |
534 |
e.set("system", "", None) |
535 |
else:
|
536 |
cexn(parent == None, "Entity.get of a non-existent entity with name {0} and no parent.", name) |
537 |
#cexn(not isinstance(parent, Entity), "Entity.get parent of {0} is not an Entity!", name)
|
538 |
e.set(name, key, parent) |
539 |
Entity.allEntities[name] = e |
540 |
|
541 |
return e
|
542 |
|
543 |
@staticmethod
|
544 |
def get(name="", key="", parent=None): |
545 |
Entity.get("Entity",name,key,parent)
|
546 |
|
547 |
|
548 |
@staticmethod
|
549 |
def list(): |
550 |
return [v for k, v in Entity.allEntities.iteritems()] |
551 |
|
552 |
@staticmethod
|
553 |
def split(entityList, rejectedList, op): |
554 |
(a, b) = split((lambda e: e.entityName not in rejectedList), entityList) |
555 |
if(rejectedList != []):
|
556 |
printf("Rejected entities (call to {0}): {1}", op, rejectedList)
|
557 |
return (a, b)
|
558 |
|
559 |
@staticmethod
|
560 |
def saveMany(entityList): |
561 |
inputList = [(e.entityName, e.parent.entityName, e.entityKey, e.parent.entityKey) for e in entityList] |
562 |
printf("Creating entities: {0}", inputList)
|
563 |
rejectedList = Entity.con().create_entity(context=Entity.Context, create_entity=inputList) |
564 |
(ok, notok) = Entity.split(entityList, rejectedList, "create")
|
565 |
printf("\n")
|
566 |
for e in ok: |
567 |
e.state = Entity.EntityState.EXISTS |
568 |
for e in notok: |
569 |
e.state = Entity.EntityState.NOT_EXISTS |
570 |
return notok
|
571 |
|
572 |
@staticmethod
|
573 |
def deleteMany(entityList): |
574 |
inputList = [(e.entityName, e.entityKey) for e in entityList] |
575 |
printf("Releasing entities: {0}", inputList)
|
576 |
rejectedList = Entity.con().release_entity(context=Entity.Context, release_entity=inputList) |
577 |
(ok, notok) = Entity.split(entityList, rejectedList, "release")
|
578 |
printf("\n")
|
579 |
for e in ok: |
580 |
e.state = Entity.EntityState.NOT_EXISTS |
581 |
for e in notok: |
582 |
e.state = Entity.EntityState.EXISTS |
583 |
return notok
|
584 |
|
585 |
@staticmethod
|
586 |
def checkMany(entityList): |
587 |
inputList = [(e.entityName, e.entityKey) for e in entityList] |
588 |
printf("Get entities: {0}", inputList)
|
589 |
acceptedList = Entity.con().get_entity(context=Entity.Context, get_entity=inputList) |
590 |
rejectedList = [e.entityName for e in entityList if e.entityName not in [n for n, k in acceptedList]] |
591 |
(ok, notok) = Entity.split(entityList, rejectedList, "get_entity")
|
592 |
printf("\n")
|
593 |
for name,parentName in acceptedList: |
594 |
e = find((lambda e: e.entityName == name),entityList)
|
595 |
if(parentName != e.parent.entityName):
|
596 |
exn("Parent of {0} is {1} and not {2}.",e.entityName,parentName,e.parent.parentName)
|
597 |
for e in ok: |
598 |
e.state = Entity.EntityState.EXISTS |
599 |
for e in notok: |
600 |
e.state = Entity.EntityState.NOT_EXISTS |
601 |
return notok
|
602 |
|
603 |
#release entity implies that each ENTITY in the system has a unique name
|
604 |
#therefore we don't have to check for equality recursively but we do it anyway.
|
605 |
def __eq__(self, other): |
606 |
if isinstance(other, Entity): |
607 |
return self.entityName == other.entityName and (self.parent == other.parent) |
608 |
elif isinstance(other, basestring): |
609 |
return self.entityName == other |
610 |
else:
|
611 |
return False |
612 |
|
613 |
def __ne__(self, other): |
614 |
return not (self.__eq__(other)) |
615 |
|
616 |
def __init__(self): |
617 |
self.set(None, None, None) |
618 |
self._commissions = []
|
619 |
self._resources = []
|
620 |
|
621 |
def _check(self): |
622 |
# cexn(self != Entity.allEntities.get(self.entityName),"Entity {0} does not exist in global dict",self.entityName)
|
623 |
pass
|
624 |
|
625 |
def getChildren(self): |
626 |
list = Entity.con().list_entities(context=Entity.Context,entity=self.entityName,key=self.entityKey) |
627 |
return [Entity.get(e,"",self) for e in list] |
628 |
|
629 |
def reset(self): |
630 |
self.set(None, None, None) |
631 |
|
632 |
def set(self, name, password, parent): |
633 |
self.entityName = name
|
634 |
self.entityKey = password
|
635 |
self.parent = parent
|
636 |
self.state = Entity.EntityState.NOT_EXISTS
|
637 |
|
638 |
def exists(self, query=False): |
639 |
self._check()
|
640 |
if(query):
|
641 |
self.checkMany([self]) |
642 |
return self.state != self.EntityState.NOT_EXISTS |
643 |
|
644 |
def create(self, query=False): |
645 |
self._check()
|
646 |
if(not self.exists(query)): |
647 |
self.saveMany([self]) |
648 |
return self.exists() |
649 |
|
650 |
def release(self, query=False): |
651 |
self._check()
|
652 |
if(self.exists(query)): |
653 |
self.deleteMany([self]) |
654 |
return not self.exists() |
655 |
|
656 |
def addResourceWith(self,name,**kwargs): |
657 |
p = Policy.newDummy(quantity=0,capacity=10) |
658 |
return self.addResource(name,p) |
659 |
|
660 |
# Resource-related API
|
661 |
def addResource(self,name,policy=None): |
662 |
r1 = Resource(name,self)
|
663 |
if(isinstance(policy,Policy)): |
664 |
r1.policy = policy |
665 |
self._resources.append(r1)
|
666 |
return r1
|
667 |
|
668 |
def markAllResourcesAsDirty(self): |
669 |
Resource.allDirty(self._resources)
|
670 |
|
671 |
# save dirty only
|
672 |
def saveResources(self,all=False): |
673 |
Resource.saveMany(self._resources,not all) |
674 |
|
675 |
def getResource(self,name ,query=False): |
676 |
r1 = self.getResources(query)
|
677 |
return find((lambda r: r.resourceName == name),r1) |
678 |
|
679 |
# list and load resources
|
680 |
def getResources(self, query=False): |
681 |
self._check()
|
682 |
if(query):
|
683 |
resourceList = Entity.con().list_resources(context=Entity.Context, |
684 |
entity=self.entityName,
|
685 |
key=self.entityKey)
|
686 |
ret = [] |
687 |
for r in resourceList: |
688 |
r1 = Resource(r,self)
|
689 |
ret.append(r1) |
690 |
Resource.loadMany(ret) |
691 |
self_resources = ret + [r for r in self._resources if(r not in ret)] |
692 |
|
693 |
return self._resources |
694 |
|
695 |
# Commission-related API
|
696 |
# self = target entity
|
697 |
def addCommission(self): |
698 |
q = Commission(self)
|
699 |
self._commissions.append(q)
|
700 |
return q
|
701 |
|
702 |
def getCommissions(self): |
703 |
return self._commissions |
704 |
|
705 |
def issueAllCommissions(self): |
706 |
valid = [c for c in self.commissions() if(c.canChange())] |
707 |
for c in valid: |
708 |
c.issue() |
709 |
return valid
|
710 |
|
711 |
def commitAllCommissions(self, accept=True): |
712 |
self.issueAll()
|
713 |
valid = [c for c in self.commissions() if(c.isPending())] |
714 |
if(accept):
|
715 |
return Commission.saveAll(valid) == []
|
716 |
else:
|
717 |
return Commission.denyAll(valid) == []
|
718 |
|
719 |
|
720 |
def clearFinished(self): |
721 |
self.commissions = [c for c in self.commissions() if(c.canChange())] |
722 |
|
723 |
#########################################################################################################
|
724 |
|
725 |
class ResourceHolder(Entity): |
726 |
|
727 |
root = Entity.get("pgerakios", "key1",Entity.get()) |
728 |
resourceNames = ["pithos","cyclades.vm","cyclades.cpu","cyclades.mem"] |
729 |
|
730 |
def __init__(self): |
731 |
super(Entity,self).__init__() |
732 |
self.commission = Commission(self) |
733 |
for r in ResourceHolder.resourceNames: |
734 |
self.addResource(r)
|
735 |
|
736 |
def newCommission(self): |
737 |
self.commission = Commission(self) |
738 |
return self.commission |
739 |
|
740 |
def loadResources(self): |
741 |
self.getResource(True) |
742 |
|
743 |
def commit(self): |
744 |
self.issue()
|
745 |
return self.commission.accept() |
746 |
|
747 |
def reject(self): |
748 |
self.issue()
|
749 |
return self.commission.reject() |
750 |
|
751 |
def release(self): |
752 |
if(not self.commission.canChange()): |
753 |
exn("The joinGroup commission is not finalized! Nothing to do.")
|
754 |
# commit the inverse stuff (send stuff back to groups)
|
755 |
self.commission = self.commission.inverse() |
756 |
b = self.commit()
|
757 |
self.newCommission()
|
758 |
# Remove entity
|
759 |
return b and super(ResourceHolder,self).release() |
760 |
|
761 |
class Group(ResourceHolder): |
762 |
|
763 |
groupRoot = Entity.getClass("Group","group","group",ResourceHolder.root) |
764 |
systemGroupName = "system"
|
765 |
systemGroupKey = "system"
|
766 |
|
767 |
@staticmethod
|
768 |
def getSystemGroup(self): |
769 |
return Group.get(Group.systemGroupName,Group.systemGroupKey)
|
770 |
|
771 |
@staticmethod
|
772 |
def listGroups(): |
773 |
return Group.groupRoot.getChildren()
|
774 |
|
775 |
@staticmethod
|
776 |
def get(name,key): |
777 |
ret = Entity.getClass("Group",name,key,Group.groupRoot)
|
778 |
if(name == Group.systemGroupName):
|
779 |
ret.makeSystem() |
780 |
elif(ret.exists(True) == False): |
781 |
ret.drawResources() |
782 |
return ret
|
783 |
|
784 |
def __init__(self): |
785 |
super(ResourceHolder,self).__init__() |
786 |
self.users = []
|
787 |
self.userResourcePolicies = {}
|
788 |
self.initializedSystem = False |
789 |
|
790 |
# load policies for groups
|
791 |
self.loadGroupResourcePolicies()
|
792 |
# load policies for users
|
793 |
self.loadUserResourcePolicies()
|
794 |
|
795 |
def loadGroupResourcePolicies(self): |
796 |
for r in self.getResources(): |
797 |
r.policy.load() |
798 |
|
799 |
def loadUserResourcePolicies(self): |
800 |
for r in self.resourceNames: |
801 |
self.userResourcePolicies[r] = Policy.get("{0}.{1}".format(self.entityName,r)) |
802 |
|
803 |
|
804 |
def getUserPolicyFor(self,resourceName): |
805 |
return self.userResourcePolicies[resourceName] |
806 |
|
807 |
def getUserPolicies(self): |
808 |
return self.userResourcePolicies |
809 |
|
810 |
def makeSystem(self): |
811 |
if(self.initializedSystem): |
812 |
return
|
813 |
#TODO: create system resources here
|
814 |
self.initializedSystem = True |
815 |
|
816 |
|
817 |
def drawResources(self): |
818 |
for r in self.getResources(): |
819 |
self.commission.addResource(r,r.policy.quantity)
|
820 |
#
|
821 |
self.commission.commit()
|
822 |
|
823 |
def savePolicyQuantities(self,**kwargs): |
824 |
res = self.getResources()
|
825 |
policies = [] |
826 |
for name,quantity in kwargs: |
827 |
r = self.getResource(name)
|
828 |
r.policy.quantity = quantity |
829 |
policies.append(r) |
830 |
Policy.save(policies) |
831 |
|
832 |
|
833 |
class User(ResourceHolder): |
834 |
|
835 |
userRoot = Entity.getClass("User","user","user",ResourceHolder.root) |
836 |
|
837 |
@staticmethod
|
838 |
def listUsers(): |
839 |
return User.userRoot.getChildren()
|
840 |
|
841 |
@staticmethod
|
842 |
def get(name,key): |
843 |
return Entity.getClass("User",name,key,User.userRoot) |
844 |
|
845 |
def __init__(self): |
846 |
super(ResourceHolder,self).__init__(None) |
847 |
self.groups = []
|
848 |
self.loadPolicy()
|
849 |
|
850 |
|
851 |
def reload(self): |
852 |
# order does matter!
|
853 |
self.clearFinished()
|
854 |
self.reject()
|
855 |
self.loadResources()
|
856 |
self.loadPolicies()
|
857 |
|
858 |
def loadPolices(self): |
859 |
dict = {} |
860 |
for g in self.groups: |
861 |
for r in self.resourceNames: |
862 |
p = g.getUserPolicyFor(r.name) |
863 |
if(dict[r.name] == None): |
864 |
dict[r.name] = Policy.copy(p)
|
865 |
else:
|
866 |
dict[r.name] = Policy.union(dict[r.name],p) |
867 |
|
868 |
# Change user policy to dummy !!! its a copy of the group policy so
|
869 |
# we can modify its fields
|
870 |
for r in self.getResources(): |
871 |
dict[r.name].setDummy(True) |
872 |
r.setPolicy(dict[r.name])
|
873 |
## FIXME: THIS IS NOT CORRECT
|
874 |
r.setFromPolicy() |
875 |
|
876 |
|
877 |
def joinGroup(self,group): |
878 |
self.groups.append(group)
|
879 |
self.groups.users.append(self) |
880 |
#
|
881 |
for r in self.getResources(): |
882 |
groupUserPolicy = group.getUserPolicyFor(r.resourceName) |
883 |
self.commission.addResource(r,groupUserPolicy.quantity)
|
884 |
self.commit()
|
885 |
|
886 |
|
887 |
# Main program
|
888 |
|
889 |
try:
|
890 |
|
891 |
# Group1
|
892 |
group1 = Group.get("group1","group1") |
893 |
|
894 |
#["pithos","cyclades.vm","cyclades.cpu","cyclades.mem"]
|
895 |
group1.savePolicyQuantities('pithos'=10,'cyclades.vm'=2,'cyclades.mem'=3) |
896 |
|
897 |
|
898 |
user1 = User.get("prodromos", "key1") |
899 |
user1.joinGroup(group1) |
900 |
|
901 |
finally:
|
902 |
for e in Entity.list(): |
903 |
if(e.entityName != "system" and e.entityName != "pgerakios"): |
904 |
e.release() |
905 |
|
906 |
|
907 |
|
908 |
|
909 |
|
910 |
printf("Hello world!")
|
911 |
|
912 |
exit(0) |
913 |
|
914 |
|
915 |
# Main program
|
916 |
root = Entity.get() |
917 |
#TODO: implement Entity.get recursively !! using get_entity !!!!
|
918 |
# TODO: correct Entity.checkAll
|
919 |
pgerakios = Entity.get("pgerakios", "key1", root) |
920 |
pgerakios.create() |
921 |
|
922 |
try:
|
923 |
# Transfer resources
|
924 |
e = Entity.get(rand_string(), "key1", pgerakios)
|
925 |
e.create() |
926 |
|
927 |
p = Policy.newDummy(quantity=0,capacity=10) |
928 |
r1 = e.addResource("CPU",p)
|
929 |
|
930 |
r2 =e.addResourceWith("MEMORY",quantity=0,capacity=25) |
931 |
rl1 = e.getResources(False)
|
932 |
for r in rl1: |
933 |
printf("Resources of e before : {0}", r.resourceName)
|
934 |
|
935 |
e.saveResources() |
936 |
rl2 = e.getResources(True)
|
937 |
|
938 |
for r in rl2: |
939 |
printf("r is {0}",r)
|
940 |
printf("dict of r : {0}", r.__dict__)
|
941 |
printf("Resources of e after : {0}", r.resourceName)
|
942 |
|
943 |
|
944 |
e1 = Entity.get(rand_string(), "key1", pgerakios)
|
945 |
e1.create() |
946 |
rl3 = e1.getResources(True)
|
947 |
q= e1.addCommission() |
948 |
q.addResource(r1,3)
|
949 |
q.addResource(r1,4)
|
950 |
e1.commitAllCommissions(False)
|
951 |
rl4 = e1.getResources(True)
|
952 |
|
953 |
for r in rl3: |
954 |
printf("Resources of e1 before : {0}", r.resourceName)
|
955 |
for r in rl4: |
956 |
printf("Resources of e1 after : {0}", r.resourceName)
|
957 |
|
958 |
finally:
|
959 |
for e in Entity.list(): |
960 |
if(e.entityName != "system" and e.entityName != "pgerakios"): |
961 |
e.release() |
962 |
|
963 |
|
964 |
|
965 |
|
966 |
|
967 |
|
968 |
|
969 |
|
970 |
|
971 |
|
972 |
|
973 |
|