Changeset 593e901


Ignore:
Timestamp:
Mar 5, 2010 1:59:26 PM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-3.01, version-3.02
Children:
73e0a61
Parents:
c5b28bf
Message:

Checkpoint working federation w/PG (w/o routing yet...)

Location:
fedd/federation
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/emulab_access.py

    rc5b28bf r593e901  
    986986            peer = info.get('peer', "")
    987987            ldomain = self.domain;
     988            ssh_port = info.get('ssh_port', 22)
    988989
    989990            mexp = info.get('masterexperiment',"")
     
    10011002                if active == 'True':
    10021003                    print >>f, "active: True"
     1004                    print >>f, "ssh_port: %s" % ssh_port
    10031005                    if type in ('control', 'both'):
    10041006                        for s in [s for s in services \
  • fedd/federation/experiment_control.py

    rc5b28bf r593e901  
    13971397                        },
    13981398                        {
     1399                            'name': 'ssh_port',
     1400                            'key': 'fedid:%s/%s-port' % (expid, myname),
     1401                            'store': self.store_url,
     1402                            'type': 'output',
     1403                        },
     1404                        {
    13991405                            'name': 'peer',
    14001406                            'key': 'fedid:%s/%s' % (expid, desthost),
     1407                            'store': self.store_url,
     1408                            'type': 'input',
     1409                        },
     1410                        {
     1411                            'name': 'ssh_port',
     1412                            'key': 'fedid:%s/%s-port' % (expid, desthost),
    14011413                            'store': self.store_url,
    14021414                            'type': 'input',
     
    14091421                for h in (myname, desthost):
    14101422                    self.auth.set_attribute(aid, 'fedid:%s/%s' % (expid, h))
     1423                    self.auth.set_attribute(aid, 'fedid:%s/%s-port' % \
     1424                            (expid, h))
    14111425            else:
    14121426                self.log.error("No aid for %s in new_portal_node" % st)
  • fedd/federation/protogeni_access.py

    rc5b28bf r593e901  
    760760                if active == 'True':
    761761                    print >>f, "active: True"
     762                    print >>f, "ssh_port: %s" % ssh_port
    762763                    if type in ('control', 'both'):
    763764                        for s in [s for s in services \
     
    777778                print >>f, "ssh_privkey: /usr/local/federation/etc/%s" % \
    778779                        secretkey_base
    779                 print >>f, "ssh_port: %s" % ssh_port
    780780                f.close()
    781781            except IOError, e:
     
    10361036            # generation off longer.
    10371037            self.import_store_info(certfile, connInfo)
    1038             self.generate_portal_configs(topo, pubkey_base,
    1039                     secretkey_base, tmpdir, master, ename, connInfo,
    1040                     services)
     1038            #self.generate_portal_configs(topo, pubkey_base,
     1039                    #secretkey_base, tmpdir, master, ename, connInfo,
     1040                    #services)
    10411041            rspec = self.generate_rspec(topo, "%s/%s/" \
    10421042                    % (self.staging_dir, ename), master, connInfo)
     
    10471047                    cm_url=self.cm_url)
    10481048            rv = starter(self, aid, user, rspec, pubkey_base, secretkey_base,
     1049                    master, ename,
    10491050                    "%s/%s" % (self.staging_dir, ename), tmpdir, cf, cpw,
    1050                     certfile, topo, connInfo)
     1051                    certfile, topo, connInfo, services)
    10511052        except service_error, e:
    10521053            err = e
  • fedd/federation/proxy_protogeni_segment.py

    rc5b28bf r593e901  
    4949
    5050    def pg_call(self, url, method, params, context):
     51        max_retries = 5
     52        retries = 0
     53
    5154        s = service_caller(method, request_body_name="", strict=False)
    5255        self.log.debug("Calling %s %s" % (url, method))
    5356        if not self.debug:
    54             r = s.call_xmlrpc_service(url, params, context=context)
    55             if r.get('code', -1) != 0:
    56                 raise self.ProtoGENIError(op=method,
    57                         code=r.get('code', 'unknown'),
    58                         output=r.get('output', 'No output'))
    59             else:
    60                 return r.get('value', None)
     57            while retries < max_retries:
     58                r = s.call_xmlrpc_service(url, params, context=context)
     59                code = r.get('code', -1)
     60                if code == 0:
     61                    # Success leaves the loop here
     62                    return r.get('value', None)
     63                elif code == 14 and retries +1 < max_retries:
     64                    # Busy resource
     65                    retries+= 1
     66                    self.log.info("Resource busy, retrying in 30 secs")
     67                    time.sleep(30)
     68                else:
     69                    # NB: out of retries falls through to here
     70                    raise self.ProtoGENIError(op=method,
     71                            code=r.get('code', 'unknown'),
     72                            output=r.get('output', 'No output'))
    6173        else:
    6274            if method in self.debug_fail:
     
    8092    # interfaces in 'interfaces'.  I love having XML parser code lying around.
    8193    def manifest_to_dict(self, manifest):
    82         if self.debug: return { }
     94        if self.debug:
     95            self.log.debug("Returning null manifest dict")
     96            return { }
    8397
    8498        # The class allows us to keep a little state - the dict under
     
    118132        p.Parse(manifest)
    119133        return mp.d
     134
     135
     136    def generate_portal_configs(self, parent, topo, pubkey_base,
     137            secretkey_base, tmpdir, master, leid, connInfo, services, nodes):
     138
     139        def conninfo_to_dict(key, info):
     140            """
     141            Make a cpoy of the connection information about key, and flatten it
     142            into a single dict by parsing out any feddAttrs.
     143            """
     144
     145            rv = None
     146            for i in info:
     147                if key == i.get('portal', "") or \
     148                        key in [e.get('element', "") \
     149                        for e in i.get('member', [])]:
     150                    rv = i.copy()
     151                    break
     152
     153            else:
     154                return rv
     155
     156            if 'fedAttr' in rv:
     157                for a in rv['fedAttr']:
     158                    attr = a.get('attribute', "")
     159                    val = a.get('value', "")
     160                    if attr and attr not in rv:
     161                        rv[attr] = val
     162                del rv['fedAttr']
     163            return rv
     164
     165        # XXX: un hardcode this
     166        def client_null(f, s):
     167            print >>f, "Service: %s" % s['name']
     168
     169        def client_smb(f, s):
     170            print >>f, "Service: %s" % s['name']
     171            smbshare = None
     172            smbuser = None
     173            smbproj = None
     174            for a in s.get('fedAttr', []):
     175                if a.get('attribute', '') == 'SMBSHARE':
     176                    smbshare = a.get('value', None)
     177                elif a.get('attribute', '') == 'SMBUSER':
     178                    smbuser = a.get('value', None)
     179                elif a.get('attribute', '') == 'SMBPROJ':
     180                    smbproj = a.get('value', None)
     181
     182            if all((smbshare, smbuser, smbproj)):
     183                print >>f, "SMBshare: %s" % smbshare
     184                print >>f, "ProjectUser: %s" % smbuser
     185                print >>f, "ProjectName: %s" % smbproj
     186
     187        client_service_out = {
     188                'SMB': client_smb,
     189                'tmcd': client_null,
     190                'seer': client_null,
     191                'userconfig': client_null,
     192            }
     193        # XXX: end un hardcode this
     194
     195
     196        seer_out = False
     197        client_out = False
     198        for e in [ e for e in topo.elements \
     199                if isinstance(e, topdl.Computer) and e.get_attribute('portal')]:
     200            myname = e.name[0]
     201            type = e.get_attribute('portal_type')
     202
     203            info = conninfo_to_dict(myname, connInfo)
     204
     205            if not info:
     206                raise service_error(service_error.req,
     207                        "No connectivity info for %s" % myname)
     208
     209            # Translate to physical name (ProtoGENI doesn't have DNS)
     210            physname = nodes.get(myname, {'hostname': myname})['hostname']
     211            peer = info.get('peer', "")
     212            ldomain = parent.domain;
     213
     214            mexp = info.get('masterexperiment',"")
     215            mproj, meid = mexp.split("/", 1)
     216            mdomain = info.get('masterdomain',"")
     217            muser = info.get('masteruser','root')
     218            smbshare = info.get('smbshare', 'USERS')
     219            ssh_port = info.get('ssh_port', '22')
     220
     221            active = info.get('active', 'False')
     222
     223            cfn = "%s/%s.gw.conf" % (tmpdir, myname.lower())
     224            tunnelconfig = parent.attrs.has_key('TunnelCfg')
     225            try:
     226                f = open(cfn, "w")
     227                if active == 'True':
     228                    print >>f, "active: True"
     229                    print >>f, "ssh_port: %s" % ssh_port
     230                    if type in ('control', 'both'):
     231                        for s in [s for s in services \
     232                                if s.get('name', "") in parent.imports]:
     233                            p = urlparse(s.get('server', 'http://localhost'))
     234                            print >>f, 'port: remote:%s:%s:%s' % \
     235                                    (p.port, p.hostname, p.port)
     236
     237                if tunnelconfig:
     238                    print >>f, "tunnelip: %s" % tunnelconfig
     239                # XXX: send this an fedattr
     240                #print >>f, "seercontrol: control.%s.%s%s" % \
     241                        #(meid.lower(), mproj.lower(), mdomain)
     242                print >>f, "peer: %s" % peer.lower()
     243                print >>f, "ssh_pubkey: /usr/local/federation/etc/%s" % \
     244                        pubkey_base
     245                print >>f, "ssh_privkey: /usr/local/federation/etc/%s" % \
     246                        secretkey_base
     247                f.close()
     248            except IOError, e:
     249                raise service_error(service_error.internal,
     250                        "Can't write protal config %s: %s" % (cfn, e))
     251           
     252            # XXX: This little seer config file needs to go away.
     253            if not seer_out:
     254                try:
     255                    seerfn = "%s/seer.conf" % tmpdir
     256                    f = open(seerfn, "w")
     257                    if not master:
     258                        print >>f, "ControlNode: control.%s.%s%s" % \
     259                            (meid.lower(), mproj.lower(), mdomain)
     260                    print >>f, "ExperimentID: %s" % mexp
     261                    f.close()
     262                except IOError, e:
     263                    raise service_error(service_error.internal,
     264                            "Can't write seer.conf: %s" %e)
     265                seer_out = True
     266
     267            if not client_out and type in ('control', 'both'):
     268                try:
     269                    f = open("%s/client.conf" % tmpdir, "w")
     270                    print >>f, "ControlGateway: %s" % physname.lower()
     271                    for s in services:
     272                        if s.get('name',"") in parent.imports and \
     273                                s.get('visibility','') == 'import':
     274                            client_service_out[s['name']](f, s)
     275                    # Does seer need this?
     276                    # print >>f, "ExperimentID: %s/%s" % (mproj, meid)
     277                    f.close()
     278                except IOError, e:
     279                    raise service_error(service_error.internal,
     280                            "Cannot write client.conf: %s" %s)
     281                client_out = True
    120282
    121283
     
    153315                    surl = p.get('store', None)
    154316                    if surl and k:
    155                         req = { 'name': k, 'value': self.ssh_port }
     317                        req = { 'name': k, 'value': ssh_port }
    156318                        self.call_SetValue(surl, req, cf)
    157319                    else:
     
    211373                    print >>script, "%s %s@%s:%s %s/etc" % \
    212374                            (scp, user, host, sshd_config, fed_dir)
     375                # Look in tmpdir to get the names.  They've all been copied
     376                # into the (remote) staging dir
    213377                if os.access("%s/%s.gw.conf" % (tmpdir, vname), os.R_OK):
    214378                    print >>script, "%s %s@%s:%s/%s.gw.conf %s/etc" % \
     
    240404        for n in nodes:
    241405            t = Thread(target=self.ssh_cmd, args=(user, n,
    242                     "sudo /bin/sh ./%s.startup" % n))
     406                    "sudo /bin/sh ./%s.startup &" % n))
    243407            t.start()
    244408            threads.append(t)
     
    253417
    254418
    255     def __call__(self, parent, aid, user, rspec, pubkey, secretkey,
    256             stagingdir, tmpdir, certfile, certpw, export_certfile, topo,
    257             connInfo, timeout=0):
     419    def __call__(self, parent, aid, user, rspec, pubkey, secretkey, master,
     420            ename, stagingdir, tmpdir, certfile, certpw, export_certfile, topo,
     421            connInfo, services, timeout=0):
    258422        """
    259423        Start a sub-experiment on a federant.
     
    302466        if not self.ssh_cmd(user, host, "sh -x %s" % scriptbase):
    303467            return False
    304 
    305         # Copy software to the staging machine
    306         for d in (tmpdir, lsoftdir):
    307             if os.path.isdir(d):
    308                 for f in os.listdir(d):
    309                     if not os.path.isdir("%s/%s" % (d, f)):
    310                         if not self.scp_file("%s/%s" % (d, f),
    311                                 user, host, "%s/%s" % (stagingdir, f)):
    312                             self.log.error("Scp failed")
    313                             return False
    314468
    315469        try:
     
    384538        except self.ProtoGENIError, e:
    385539            raise service_error(service_error.federant,
    386                     "ProtoGENI: %s" % e)
     540                    "ProtoGENI: %s %s" % (e.code, e))
    387541
    388542        # With manifest in hand, we can export the portal node names.
    389543        nodes = self.manifest_to_dict(manifest)
     544        print nodes
    390545        self.export_store_info(export_certfile, nodes, parent.ssh_port,
    391546                connInfo)
     547        self.generate_portal_configs(parent, topo, pubkey, secretkey, tmpdir,
     548                master, ename, connInfo, services, nodes)
     549
     550        # Copy software to the staging machine (done after generation to copy
     551        # those, too)
     552        for d in (tmpdir, lsoftdir):
     553            if os.path.isdir(d):
     554                for f in os.listdir(d):
     555                    if not os.path.isdir("%s/%s" % (d, f)):
     556                        if not self.scp_file("%s/%s" % (d, f),
     557                                user, host, "%s/%s" % (stagingdir, f)):
     558                            self.log.error("Scp failed")
     559                            return False
     560
    392561
    393562        # Now we wait for the nodes to start on PG
     
    403572                if status == 'notready':
    404573                    time.sleep(30)
    405         except Self.ProtoGENIError, e:
     574        except self.ProtoGENIError, e:
    406575            raise service_error(service_error.federant,
    407                     "ProtoGENI: %s" % e)
     576                    "ProtoGENI: %s %s" % (e.code, e))
    408577
    409578        if status == 'failed':
Note: See TracChangeset for help on using the changeset viewer.