Statistics
| Branch: | Tag: | Revision:

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