Changeset 29d5f7c for fedd/federation


Ignore:
Timestamp:
Nov 18, 2011 6:43:19 PM (13 years ago)
Author:
Ted Faber <faber@…>
Branches:
compt_changes, info-ops, master
Children:
80b1e82
Parents:
2ac64d1a
Message:

More new Info stuff. Create, terminate, ftopo all work.

Location:
fedd/federation
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/emulab_access.py

    r2ac64d1a r29d5f7c  
    10161016        the response that may need to be replayed, and return the response.
    10171017        """
     1018        i = 0
    10181019        # Copy the assigned names into the return topology
    1019         embedding = [ ]
    1020         for n in starter.node:
    1021             embedding.append({
    1022                 'toponame': n,
    1023                 'physname': ["%s%s" %  (starter.node[n], self.domain)],
    1024                 })
     1020        for e in topo.elements:
     1021            if isinstance(e, topdl.Computer):
     1022                if not self.create_debug:
     1023                    if e.name in starter.node:
     1024                        e.localname.append("%s%s" % \
     1025                                (starter.node[e.name], self.domain))
     1026                        e.status = 'active'
     1027                else:
     1028                    # Simple debugging assignment
     1029                    e.localname.append("node%d%s" % (i, self.domain))
     1030                    e.status = 'active'
     1031                    e.operation.extend(('testop1', 'testop2'))
     1032                    i += 1
     1033
    10251034        # Grab the log (this is some anal locking, but better safe than
    10261035        # sorry)
     
    10361045                    'topdldescription': topo.clone().to_dict()
    10371046                    },
    1038                 'embedding': embedding,
    10391047                'proof': proof.to_dict(),
    10401048                }
  • fedd/federation/experiment_control.py

    r2ac64d1a r29d5f7c  
    3636from authorizer import abac_authorizer
    3737from thread_pool import thread_pool, pooled_thread
     38from experiment_info import experiment_info, allocation_info
    3839
    3940import topdl
     
    286287
    287288    @staticmethod
    288     def get_alloc_ids(state):
    289         """
    290         Pull the fedids of the identifiers of each allocation from the
    291         state.  Again, a dict dive that's best isolated.
    292 
    293         Used by read_store and read state
    294         """
    295 
    296         return [ f['allocID']['fedid']
    297                 for f in state.get('federant',[]) \
    298                     if f.has_key('allocID') and \
    299                         f['allocID'].has_key('fedid')]
     289    def get_alloc_ids(exp):
     290        """
     291        Used by read_store and read state.  This used to be worse.
     292        """
     293
     294        return [ a.allocID for a in exp.get_all_allocations() ]
     295
    300296
    301297    # Call while holding self.state_lock
     
    307303        """
    308304       
    309         def get_experiment_id(state):
    310             """
    311             Pull the fedid experimentID out of the saved state.  This is kind
    312             of a gross walk through the dict.
    313             """
    314 
    315             if state.has_key('experimentID'):
    316                 for e in state['experimentID']:
    317                     if e.has_key('fedid'):
    318                         return e['fedid']
    319                 else:
    320                     return None
    321             else:
    322                 return None
    323 
    324305        try:
    325306            f = open(self.state_filename, "r")
     
    337318            try:
    338319
    339                 eid = get_experiment_id(s)
     320                eid = s.fedid
    340321                if eid :
    341322                    if self.auth_type == 'legacy':
    342323                        # XXX: legacy
    343324                        # Give the owner rights to the experiment
    344                         self.auth.set_attribute(s['owner'], eid)
     325                        #self.auth.set_attribute(s['owner'], eid)
    345326                        # And holders of the eid as well
    346327                        self.auth.set_attribute(eid, eid)
     
    809790        if self.local_access.has_key(uri):
    810791            resp = self.local_access[uri].ReleaseAccess(\
    811                     { 'ReleaseAccessRequestBody' : {'allocID': aid},},
     792                    { 'ReleaseAccessRequestBody' :
     793                        {'allocID': {'fedid': aid}},},
    812794                    fedid(file=cert_file))
    813795            resp = { 'ReleaseAccessResponseBody': resp }
    814796        else:
    815             resp = self.call_ReleaseAccess(uri, {'allocID': aid},
     797            resp = self.call_ReleaseAccess(uri, {'allocID': {'fedid': aid} },
    816798                    cert_file, cert_pwd, self.trusted_certs)
    817799
     
    855837
    856838        def make_map(self, resp):
    857             for e in resp.get('embedding', []):
    858                 if 'toponame' in e and 'physname' in e:
    859                     self.node[e['toponame']] = e['physname'][0]
     839            if 'segmentdescription' not in resp  or \
     840                    'topdldescription' not in resp['segmentdescription']:
     841                self.log.warn('No topology returned from startsegment')
     842                return
     843
     844            top = topdl.Topology(
     845                    **resp['segmentdescription']['topdldescription'])
     846
     847            for e in top.elements:
     848                if isinstance(e, topdl.Computer):
     849                    self.node[e.name] = \
     850                            (e.localname, e.status, e.service, e.operation)
    860851
    861852        def __call__(self, uri, aid, topo, masters, attrs=None, connInfo=None):
     
    928919        def __call__(self, uri, aid ):
    929920            req = {
    930                     'allocID': aid ,
     921                    'allocID': {'fedid': aid },
    931922                }
    932923            try:
     
    10561047                # Remove the placeholder
    10571048                self.state_lock.acquire()
    1058                 self.state[eid]['experimentStatus'] = 'failed'
     1049                self.state[eid].status = 'failed'
    10591050                if self.state_filename: self.write_state()
    10601051                self.state_lock.release()
     
    10711062                return
    10721063        else:
    1073             # Walk through the successes and gather the virtual to physical
    1074             # mapping.
    1075             embedding = [ ]
     1064            # Walk through the successes and gather the proofs
    10761065            proofs = { }
    10771066            for s in starters:
    1078                 for k, v in s.node.items():
    1079                     embedding.append({
    1080                         'toponame': k,
    1081                         'physname': [ v],
    1082                         'testbed': s.testbed
    1083                         })
    10841067                if s.proof:
    10851068                    proofs[s.testbed] = s.proof
     1069
     1070            # Annotate the topology with embedding info
     1071            for e in top.elements:
     1072                if isinstance(e, topdl.Computer):
     1073                    for s in starters:
     1074                        ann = s.node.get(e.name, None)
     1075                        if ann is not None:
     1076                            e.localname.extend(ann[0])
     1077                            e.status = ann[1]
     1078                            e.service.extend(ann[2])
     1079                            e.operation.extend(ann[3])
     1080                            break
     1081
    10861082            log.info("[start_segment]: Experiment %s active" % eid)
    10871083
     
    10951091        # Insert the experiment into our state and update the disk copy.
    10961092        self.state_lock.acquire()
    1097         self.state[expid]['experimentStatus'] = 'active'
     1093        self.state[expid].status = 'active'
    10981094        self.state[eid] = self.state[expid]
    1099         self.state[eid]['experimentdescription']['topdldescription'] = \
    1100                 top.to_dict()
    1101         self.state[eid]['embedding'] = embedding
     1095        self.state[eid].top = top
    11021096        # Append startup proofs
    1103         for f in self.state[eid]['federant']:
    1104             if 'name' in f and 'localname' in f['name']:
    1105                 if f['name']['localname'] in proofs:
    1106                     f['proof'].append(proofs[f['name']['localname']])
     1097        for f in self.state[eid].get_all_allocations():
     1098            if f.tb in proofs:
     1099                f.proof.append(proofs[f.tb])
    11071100
    11081101        if self.state_filename: self.write_state()
     
    11351128
    11361129        if need_state_lock: self.state_lock.acquire()
    1137         self.state[expid]['auth'].update(attrs)
     1130        # XXX: really a no op?
     1131        #self.state[expid]['auth'].update(attrs)
    11381132        if self.state_filename: self.write_state()
    11391133        if need_state_lock: self.state_lock.release()
     
    11461140
    11471141        if need_state_lock: self.state_lock.acquire()
    1148         if expid in self.state and 'auth' in self.state[expid]:
    1149             for p, a in self.state[expid]['auth']:
    1150                 self.auth.unset_attribute(p, a)
    1151             self.state[expid]['auth'] = set()
     1142        # XXX: should be a no-op
     1143        #if expid in self.state and 'auth' in self.state[expid]:
     1144            #for p, a in self.state[expid]['auth']:
     1145                #self.auth.unset_attribute(p, a)
     1146            #self.state[expid]['auth'] = set()
    11521147        if self.state_filename: self.write_state()
    11531148        if need_state_lock: self.state_lock.release()
     
    11841179                if users_experiment:
    11851180                    self.state_lock.acquire()
    1186                     status = self.state[eid].get('experimentStatus', None)
     1181                    status = self.state[eid].status
    11871182                    if status and status == 'failed':
    11881183                        # remove the old access attributes
     
    12001195                eid += random.choice(string.ascii_letters)
    12011196            # Initial state
    1202             self.state[eid] = {
    1203                     'experimentID' : \
    1204                             [ { 'localname' : eid }, {'fedid': expid } ],
    1205                     'experimentStatus': state,
    1206                     'experimentAccess': { 'X509' : expcert },
    1207                     'owner': fid,
    1208                     'log' : [],
    1209                     'auth': set(),
    1210                 }
     1197            self.state[eid] = experiment_info(fedid=expid, localname=eid,
     1198                    identity=expcert)
    12111199            self.state[expid] = self.state[eid]
    12121200            if self.state_filename: self.write_state()
     
    12221210                    eid += random.choice(string.ascii_letters)
    12231211            # Initial state
    1224             self.state[eid] = {
    1225                     'experimentID' : \
    1226                             [ { 'localname' : eid }, {'fedid': expid } ],
    1227                     'experimentStatus': state,
    1228                     'experimentAccess': { 'X509' : expcert },
    1229                     'owner': fid,
    1230                     'log' : [],
    1231                     'auth': set(),
    1232                 }
     1212            self.state[eid] = experiment_info(fedid=expid, localname=eid,
     1213                    identity=expcert)
    12331214            self.state[expid] = self.state[eid]
    12341215            if self.state_filename: self.write_state()
     
    16681649        expid = eid = None
    16691650        self.state_lock.acquire()
    1670         if self.state.has_key(key):
    1671             self.state[key]['experimentStatus'] = "starting"
    1672             for e in self.state[key].get('experimentID',[]):
    1673                 if not expid and e.has_key('fedid'):
    1674                     expid = e['fedid']
    1675                 elif not eid and e.has_key('localname'):
    1676                     eid = e['localname']
    1677             if 'experimentAccess' in self.state[key] and \
    1678                     'X509' in self.state[key]['experimentAccess']:
    1679                 expcert = self.state[key]['experimentAccess']['X509']
    1680             else:
    1681                 expcert = None
     1651        if key in self.state:
     1652            exp = self.state[key]
     1653            exp.status = "starting"
     1654            expid = exp.fedid
     1655            eid = exp.localname
     1656            expcert = exp.identity
    16821657        self.state_lock.release()
    16831658
     
    19161891
    19171892        self.state_lock.acquire()
     1893        # XXX: this needs to be recalculated
    19181894        if self.state.has_key(key):
    19191895            if self.state[key].has_key('vtopo'):
     
    19611937
    19621938        self.state_lock.acquire()
     1939        # XXX: this needs to be recalculated
    19631940        if self.state.has_key(key):
    19641941            if self.state[key].has_key('vis'):
     
    19901967        response message.
    19911968        """
     1969        self.state_lock.acquire()
     1970        # XXX:
     1971        #self.state[eid]['vtopo'] = vtopo
     1972        #self.state[eid]['vis'] = vis
     1973        exp = self.state[eid]
     1974        exp.topology = top
    19921975        # save federant information
    19931976        for k in allocated.keys():
    1994             tbparams[k]['federant'] = {
    1995                     'name': [ { 'localname' : eid} ],
    1996                     'allocID' : tbparams[k]['allocID'],
    1997                     'uri': tbparams[k]['uri'],
    1998                     'proof': tbparams[k]['proof'],
    1999                 }
    2000 
    2001         self.state_lock.acquire()
    2002         self.state[eid]['vtopo'] = vtopo
    2003         self.state[eid]['vis'] = vis
    2004         self.state[eid]['experimentdescription'] = \
    2005                 { 'topdldescription': top.to_dict() }
    2006         self.state[eid]['federant'] = \
    2007                 [ tbparams[tb]['federant'] for tb in tbparams.keys() \
    2008                     if tbparams[tb].has_key('federant') ]
     1977            exp.add_allocation(
     1978                    allocation_info(
     1979                        tb=k,
     1980                        allocID=tbparams[k]['allocID'].get('fedid', None),
     1981                        uri=tbparams[k]['uri'],
     1982                        proof=tbparams[k]['proof'])
     1983                    )
     1984
    20091985        # Access proofs for the response message
    20101986        proofs = [copy.deepcopy(p) for k in tbparams.keys()\
    2011                     for p in tbparams[k]['federant']['proof']]
     1987                    for p in tbparams[k]['proof']]
    20121988        if self.state_filename:
    20131989            self.write_state()
     
    21542130        # to the main log file.
    21552131        alloc_log = logging.getLogger('fedd.experiment_control.%s' % eid)
    2156         alloc_collector = self.list_log(self.state[eid]['log'])
     2132        alloc_collector = self.list_log(self.state[eid].log)
    21572133        h = logging.StreamHandler(alloc_collector)
    21582134        # XXX: there should be a global one of these rather than repeating the
     
    21872163        rv = None
    21882164        self.state_lock.acquire()
    2189         if self.state.has_key(key):
    2190             if isinstance(self.state[key], dict):
    2191                 try:
    2192                     kl = [ f['fedid'] for f in \
    2193                             self.state[key]['experimentID']\
    2194                                 if f.has_key('fedid') ]
    2195                 except KeyError:
    2196                     self.state_lock.release()
    2197                     raise service_error(service_error.internal,
    2198                             "No fedid for experiment %s when getting "+\
    2199                                     "fedid(!?)" % key)
    2200                 if len(kl) == 1:
    2201                     rv = kl[0]
    2202                 else:
    2203                     self.state_lock.release()
    2204                     raise service_error(service_error.internal,
    2205                             "multiple fedids for experiment %s when " +\
    2206                                     "getting fedid(!?)" % key)
    2207             else:
    2208                 self.state_lock.release()
    2209                 raise service_error(service_error.internal,
    2210                         "Unexpected state for %s" % key)
     2165        if key in self.state:
     2166            rv = self.state[key].fedid
    22112167        self.state_lock.release()
    22122168        return rv
     
    22422198            return (None, None)
    22432199
    2244     def clean_info_response(self, rv, proof):
    2245         """
    2246         Remove the information in the experiment's state object that is not in
    2247         the info response.
    2248         """
    2249         # Remove the owner info (should always be there, but...)
    2250         if rv.has_key('owner'): del rv['owner']
    2251         if 'auth' in rv: del rv['auth']
    2252 
    2253         # Convert the log into the allocationLog parameter and remove the
    2254         # log entry (with defensive programming)
    2255         if rv.has_key('log'):
    2256             rv['allocationLog'] = "".join(rv['log'])
    2257             del rv['log']
    2258         else:
    2259             rv['allocationLog'] = ""
    2260 
    2261         if rv['experimentStatus'] != 'active':
    2262             if rv.has_key('federant'): del rv['federant']
    2263         else:
    2264             # remove the allocationID and uri info from each federant
    2265             for f in rv.get('federant', []):
    2266                 if f.has_key('allocID'): del f['allocID']
    2267                 if f.has_key('uri'): del f['uri']
    2268         rv['proof'] = proof.to_dict()
    2269 
    2270         return rv
    2271 
     2200   
    22722201    def get_info(self, req, fid):
    22732202        """
     
    22952224        proof = self.check_experiment_access(fid, key)
    22962225
    2297         # The state may be massaged by the service function that called
    2298         # get_info (e.g., encoded for XMLRPC transport) so send a copy of the
    2299         # state.
    23002226        self.state_lock.acquire()
    23012227        if self.state.has_key(key):
    2302             rv = copy.deepcopy(self.state[key])
     2228            rv = self.state[key].get_info()
    23032229        self.state_lock.release()
    23042230
    23052231        if rv:
    2306             return self.clean_info_response(rv, proof)
     2232            rv['proof'] = proof.to_dict()
     2233            return rv
    23072234        else:
    23082235            raise service_error(service_error.req, "No such experiment")
     
    23262253
    23272254            if self.state.has_key(key):
    2328                 e = copy.deepcopy(self.state[key])
    2329                 e = self.clean_info_response(e, proof)
     2255                e = self.state[key].get_info()
     2256                e['proof'] = proof.to_dict()
    23302257                rv['info'].append(e)
    23312258                rv['proof'].append(proof.to_dict())
     
    23402267        """
    23412268        self.state_lock.acquire()
    2342         status = fed_exp.get('experimentStatus', None)
     2269        status = fed_exp.status
    23432270
    23442271        if status:
     
    23642291        term_params = { }
    23652292        self.state_lock.acquire()
    2366         #  experimentID is a list of dicts that are self-describing
    2367         #  identifiers.  This finds all the fedids and localnames - the
    2368         #  keys of self.state - and puts them into ids, which is used to delete
    2369         #  the state after everything is swapped out.
    2370         for id in fed_exp.get('experimentID', []):
    2371             if 'fedid' in id:
    2372                 ids.append(id['fedid'])
    2373                 repo = "%s" % id['fedid']
    2374             if 'localname' in id: ids.append(id['localname'])
    2375 
    2376         # Get the experimentAccess - the principal for this experiment.  It
    2377         # is this principal to which credentials have been delegated, and
    2378         # as which the experiment controller must act.
    2379         if 'experimentAccess' in fed_exp and \
    2380                 'X509' in fed_exp['experimentAccess']:
    2381             expcert = fed_exp['experimentAccess']['X509']
    2382         else:
    2383             expcert = None
     2293        ids = [ x for x in (fed_exp.localname, fed_exp.fedid) if x is not None ]
     2294        expcert = fed_exp.identity
     2295        repo = "%s" % fed_exp.fedid
    23842296
    23852297        # Collect the allocation/segment ids into a dict keyed by the fedid
    2386         # of the allocation (or a monotonically increasing integer) that
    2387         # contains a tuple of uri, aid (which is a dict...)
    2388         for i, fed in enumerate(fed_exp.get('federant', [])):
    2389             try:
    2390                 uri = fed['uri']
    2391                 aid = fed['allocID']
    2392                 k = fed['allocID'].get('fedid', i)
    2393             except KeyError, e:
    2394                 continue
    2395             term_params[k] = (uri, aid)
     2298        # of the allocation that contains a tuple of uri, aid
     2299        for i, fed in enumerate(fed_exp.get_all_allocations()):
     2300            uri = fed.uri
     2301            aid = fed.allocID
     2302            term_params[aid] = (uri, aid)
    23962303        # Change the experiment state
    2397         fed_exp['experimentStatus'] = 'terminating'
     2304        fed_exp.status = 'terminating'
    23982305        if self.state_filename: self.write_state()
    23992306        self.state_lock.release()
  • fedd/federation/topdl.py

    r2ac64d1a r29d5f7c  
    168168                    for i in self.importer],'')
    169169        if self.param:
    170             rv += join('<param>%s</param>' % p.to_xml() \
     170            rv += join(['<param>%s</param>' % p.to_xml() \
    171171                    for p in self.param], '')
    172172        if self.description is not None:
     
    206206                localname = [ ln for ln in self.localname],
    207207                status = self.status,
    208                 service = [ s.clone() for s in self.service]
    209                 operation=[ op for op in operation])
     208                service = [ s.clone() for s in self.service],
     209                operation=[ op for op in self.operation])
    210210
    211211    def to_dict(self):
     
    238238                    for a in self.attribute], "")
    239239        if self.localname:
    240             rv += join('<localname>%s</localname>' % ln \
     240            rv += join(['<localname>%s</localname>' % ln \
    241241                    for ln in self.localname], '')
    242242        if self.status is not None:
     
    489489                interface=[x.clone() for x in self.interface],
    490490                attribute=[x.clone() for x in self.attribute],
    491                 localname =[ ln for for ln in self.localname],
     491                localname =[ ln for ln in self.localname],
    492492                status = self.status,
    493493                service = [s.clone() for s in self.service],
     
    539539                    for a in self.attribute], "")
    540540        if self.localname:
    541             rv += join('<localname>%s</localname>' % ln \
     541            rv += join(['<localname>%s</localname>' % ln \
    542542                    for ln in self.localname], '')
    543543        if self.status is not None:
     
    607607                    for a in self.attribute], "")
    608608        if self.localname:
    609             rv += join('<localname>%s</localname>' % ln \
     609            rv += join(['<localname>%s</localname>' % ln \
    610610                    for ln in self.localname], '')
    611611        if self.status is not None:
Note: See TracChangeset for help on using the changeset viewer.