source: fedd/federation/proxy_protogeni_segment.py @ c2c153b

axis_examplecompt_changesinfo-opsversion-3.01version-3.02
Last change on this file since c2c153b was 0b799e0, checked in by Ted Faber <faber@…>, 14 years ago

stage an ssh identity properly

  • Property mode set to 100644
File size: 21.4 KB
Line 
1#!/usr/local/bin/python
2
3import sys, os
4import re
5
6import tempfile
7import subprocess
8import logging 
9import time
10import random
11import string
12import signal
13
14import xml.parsers.expat
15from threading import Thread
16
17from proxy_segment import proxy_segment
18from service_error import service_error
19from remote_service import service_caller
20from util import fedd_ssl_context
21
22import topdl
23
24class segment_base(proxy_segment):
25    class ProtoGENIError(Exception): 
26        def __init__(self, op, code, output):
27            Exception.__init__(self, output)
28            self.op = op
29            self.code = code
30            self.output = output
31
32    def __init__(self, log=None, keyfile=None, debug=False, 
33            ch_url=None, sa_url=None, cm_url=None):
34        proxy_segment.__init__(self, log=log, keyfile=keyfile, debug=debug)
35
36        self.ProtoGENIError = start_segment.ProtoGENIError
37        self.ch_url = ch_url
38        self.sa_url = sa_url
39        self.cm_url = cm_url
40
41        self.call_SetValue = service_caller('SetValue')
42
43        self.debug_fail = ['Resolve']
44        self.debug_response = {
45                'RedeemTicket': ("XML blob1", "XML blob2"),
46                'SliceStatus': { 'status': 'ready' },
47            }
48
49
50    def pg_call(self, url, method, params, context):
51        max_retries = 5
52        retries = 0
53
54        s = service_caller(method, request_body_name="", strict=False)
55        self.log.debug("Calling %s %s" % (url, method))
56        if not self.debug:
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'))
73        else:
74            if method in self.debug_fail:
75                raise self.ProtoGENIError(op=method, code='unknown',
76                        output='No output')
77            elif self.debug_response.has_key(method):
78                return self.debug_response[method]
79            else:
80                return "%s XML blob" % method
81
82
83class start_segment(segment_base):
84    def __init__(self, log=None, keyfile=None, debug=False, 
85            ch_url=None, sa_url=None, cm_url=None):
86        segment_base.__init__(self, log=log, keyfile=keyfile, debug=debug,
87                ch_url=cm_url, sa_url=sa_url, cm_url=cm_url)
88
89
90    # Turn the manifest into a dict were each virtual nodename (i.e. the topdl
91    # name) has an entry with the allocated machine in hostname and the
92    # interfaces in 'interfaces'.  I love having XML parser code lying around.
93    def manifest_to_dict(self, manifest, ignore_debug=False):
94        if self.debug and not ignore_debug: 
95            self.log.debug("Returning null manifest dict")
96            return { }
97
98        # The class allows us to keep a little state - the dict under
99        # consteruction and the current entry in that dict for the interface
100        # element code.
101        class manifest_parser:
102            def __init__(self):
103                self.d = { }
104                self.current_key=None
105
106            # If the element is a node, create a dict entry for it.  If it's an
107            # interface inside a node, add an entry in the interfaces list with
108            # the virtual name and component id.
109            def start_element(self, name, attrs):
110                if name == 'node':
111                    self.current_key = attrs.get('virtual_id',"")
112                    if self.current_key:
113                        self.d[self.current_key] = {
114                                'hostname': attrs.get('hostname', None),
115                                'interfaces': { }
116                                }
117                elif name == 'interface' and self.current_key:
118                    self.d[self.current_key]['interfaces']\
119                            [attrs.get('virtual_id','')] = \
120                            attrs.get('component_id', None)
121            #  When a node is finished, clear current_key
122            def end_element(self, name):
123                if name == 'node': self.current_key = None
124
125
126        mp = manifest_parser()
127        p = xml.parsers.expat.ParserCreate()
128        # These are bound to the class we just created
129        p.StartElementHandler = mp.start_element
130        p.EndElementHandler = mp.end_element
131
132        p.Parse(manifest)
133        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
282
283
284
285    def export_store_info(self, cf, nodes, ssh_port, connInfo):
286        """
287        For the export requests in the connection info, install the peer names
288        at the experiment controller via SetValue calls.
289        """
290
291        for c in connInfo:
292            for p in [ p for p in c.get('parameter', []) \
293                    if p.get('type', '') == 'output']:
294
295                if p.get('name', '') == 'peer':
296                    k = p.get('key', None)
297                    surl = p.get('store', None)
298                    if surl and k and k.index('/') != -1:
299                        if self.debug:
300                            req = { 'name': k, 'value': 'debug' }
301                            self.call_SetValue(surl, req, cf)
302                        else:
303                            value = nodes.get(k[k.index('/')+1:], 
304                                    {}).get('hostname',"")
305                            if value:
306                                req = { 'name': k, 'value': value }
307                                self.call_SetValue(surl, req, cf)
308                            else:
309                                self.log.error("No hostname for %s" % \
310                                        k[k.index('/'):])
311                    else:
312                        self.log.error("Bad export request: %s" % p)
313                elif p.get('name', '') == 'ssh_port':
314                    k = p.get('key', None)
315                    surl = p.get('store', None)
316                    if surl and k:
317                        req = { 'name': k, 'value': ssh_port }
318                        self.call_SetValue(surl, req, cf)
319                    else:
320                        self.log.error("Bad export request: %s" % p)
321                else:
322
323                    self.log.error("Unknown export parameter: %s" % \
324                            p.get('name'))
325                    continue
326
327    def configure_nodes(self, topo, nodes, user, host, sshd, sshd_config,
328            gate_cmd, node_cmd, pubkey, secretkey, stagingdir, tmpdir):
329
330        fed_dir = "/usr/local/federation"
331        ssh = "/usr/bin/ssh -n -i .ssh/id_rsa -o 'ForwardX11 no' -o 'StrictHostKeyChecking no' "
332        scp = "/usr/bin/scp -i .ssh/id_rsa -o 'ForwardX11 no' -o 'StrictHostKeyChecking no' "
333        ifconfig = "/sbin/ifconfig"
334        tar = "/bin/tar"
335
336        for e in [ e for e in topo.elements if isinstance(e, topdl.Computer)]:
337            vname = e.name[0]
338            node = nodes.get(vname, {})
339            pname = node.get('hostname', None)
340            if pname:
341                script = open("%s/%s.startup" %(tmpdir, pname), "w")
342                # Reset the interfaces to the ones in the topo file
343                for i in [ i for i in e.interface \
344                        if not i.get_attribute('portal')]:
345                    pinf = node['interfaces'].get(i.name, None)
346                    addr = i.get_attribute('ip4_address') 
347                    netmask = i.get_attribute('ip4_netmask') or '255.255.255.0'
348                    if pinf and addr:
349                        print >>script, \
350                                "%s %s %s netmask %s"  % \
351                                (ifconfig, pinf, addr, netmask)
352                    else:
353                        self.log.error("Missing interface or address for %s" \
354                                % i.name)
355                   
356                for s in e.software:
357                    # XXX: Just tarfiles for now
358                    if not (s.location and s.install):
359                        continue
360                    s_base = s.location.rpartition('/')[2]
361                    print >>script, "%s %s@%s:%s/%s ." % \
362                            (scp, user, host, stagingdir, s_base)
363                    print >>script, \
364                            "%s -C %s -xzf %s" % (tar, s.install, s_base)
365                for f in ('hosts', pubkey, secretkey, 'client.conf', 
366                        'userconf', 'seer.conf'):
367                    print >>script, "%s %s@%s:%s/%s %s/etc" % \
368                            (scp, user, host, stagingdir, f, fed_dir)
369                if sshd:
370                    print >>script, "%s %s@%s:%s %s/bin" % \
371                            (scp, user, host, sshd, fed_dir)
372                if sshd_config:
373                    print >>script, "%s %s@%s:%s %s/etc" % \
374                            (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
377                if os.access("%s/%s.gw.conf" % (tmpdir, vname), os.R_OK):
378                    print >>script, "%s %s@%s:%s/%s.gw.conf %s/etc" % \
379                            (scp, user, host, stagingdir, vname, fed_dir)
380
381
382                # Start commands
383                if e.get_attribute('portal') and gate_cmd:
384                    # Portals never have a user-specified start command
385                    print >>script, gate_cmd
386                elif node_cmd:
387                    # XXX: debug
388                    print >>script, "sudo perl -I%s/lib %s/bin/import_key.pl /users/%s/.ssh/authorized_keys /root/.ssh/authorized_keys" % (fed_dir, fed_dir, user)
389                    # XXX: debug
390                    # start routing on nodes
391                    print >>script, "sudo perl %s/bin/protogeni_routing.pl" % \
392                            fed_dir
393                    if e.get_attribute('startup'):
394                        print >>script, "%s \\$USER '%s'" % \
395                                (node_cmd, e.get_attribute('startup'))
396                    else:
397                        print >>script, node_cmd
398                script.close()
399                if not self.scp_file("%s/%s.startup" % (tmpdir, pname), 
400                        user, pname):
401                    self.log.error("Could not copy script to %s" % pname)
402            else:
403                self.log.error("Unmapped node: %s" % vname)
404
405    def start_node(self, user, host, node):
406        # Place an identity on the node so that the copying can succeed
407        self.ssh_cmd(user, host, "scp .ssh/id_rsa %s:.ssh" % node)
408        self.ssh_cmd(user, node, "sudo /bin/sh ./%s.startup &" % node)
409
410    def start_nodes(self, user, host, nodes):
411        threads = [ ]
412        for n in nodes:
413            t = Thread(target=self.start_node, args=(user, host, n))
414            t.start()
415            threads.append(t)
416
417        done = [not t.isAlive() for t in threads]
418        while not all(done):
419            self.log.info("Waiting for threads %s" % done)
420            time.sleep(10)
421            done = [not t.isAlive() for t in threads]
422
423
424
425
426    def __call__(self, parent, aid, user, rspec, pubkey, secretkey, master,
427            ename, stagingdir, tmpdir, certfile, certpw, export_certfile, topo,
428            connInfo, services, timeout=0):
429        """
430        Start a sub-experiment on a federant.
431
432        Get the current state, modify or create as appropriate, ship data
433        and configs and start the experiment.  There are small ordering
434        differences based on the initial state of the sub-experiment.
435        """
436
437        def random_slicename(user):
438            slicename = user
439            for i in range(0,5):
440                slicename += random.choice(string.ascii_letters)
441            return slicename
442
443        host = parent.staging_host
444        ctxt = fedd_ssl_context(my_cert=certfile, password=certpw)
445        # Local software dir
446        lsoftdir = "%s/software" % tmpdir
447
448        # Open up a temporary file to contain a script for setting up the
449        # filespace for the new experiment.
450        self.log.info("[start_segment]: creating script file")
451        try:
452            sf, scriptname = tempfile.mkstemp()
453            scriptfile = os.fdopen(sf, 'w')
454        except IOError:
455            return False
456
457        scriptbase = os.path.basename(scriptname)
458
459        # Script the filesystem changes
460        print >>scriptfile, "/bin/rm -rf %s" % stagingdir
461        print >>scriptfile, 'mkdir -p %s' % stagingdir
462        print >>scriptfile, "rm -f %s" % scriptbase
463        scriptfile.close()
464
465        # Move the script to the remote machine
466        # XXX: could collide tempfile names on the remote host
467        if self.scp_file(scriptname, user, host, scriptbase):
468            os.remove(scriptname)
469        else:
470            return False
471
472        # Execute the script (and the script's last line deletes it)
473        if not self.ssh_cmd(user, host, "sh -x %s" % scriptbase):
474            return False
475
476        try:
477            gcred = self.pg_call(self.sa_url, 'GetCredential', {}, ctxt)
478        except self.ProtoGENIError, e:
479            raise service_error(service_error.federant,
480                    "ProtoGENI: %s" % e)
481        # Find a slicename not in use
482        slicename = "fabereGpgL"
483        while True:
484            slicename = random_slicename(user)
485            try:
486                param = {
487                        'credential': gcred, 
488                        'hrn': slicename,
489                        'type': 'Slice'
490                        }
491                self.pg_call(self.sa_url, 'Resolve', param, ctxt)
492            except self.ProtoGENIError, e:
493                print e
494                break
495
496        self.log.info("Creating %s" % slicename)
497        f = open("./rspec", "w")
498        print >>f, "%s" % rspec
499        f.close()
500        # Create the slice and allocate resources.  If any of this stuff fails,
501        # the allocations will time out on PG in short order, so we just raise
502        # the service_error.
503        try:
504            param = {
505                    'credential': gcred, 
506                    'hrn': slicename,
507                    'type': 'Slice'
508                    }
509            slice_cred = self.pg_call(self.sa_url, 'Register', param, ctxt)
510            f = open("./slice_cred", "w")
511            print >>f, slice_cred
512            f.close()
513            # Populate the ssh keys (let PG format them)
514            param = {
515                    'credential': gcred, 
516                    }
517            keys =  self.pg_call(self.sa_url, 'GetKeys', param, ctxt)
518            # Grab and redeem a ticket
519            param = {
520                    'credential': slice_cred, 
521                    'rspec': rspec,
522                    }
523            ticket = self.pg_call(self.cm_url, 'GetTicket', param, ctxt)
524            f = open("./ticket", "w")
525            print >>f, ticket
526            f.close()
527            param = { 
528                    'credential': slice_cred, 
529                    'keys': keys,
530                    'ticket': ticket,
531                    }
532            sliver_cred, manifest = self.pg_call(self.cm_url, 
533                    'RedeemTicket', param, ctxt)
534            f = open("./sliver_cred", "w")
535            print >>f, sliver_cred
536            f.close()
537            f = open("./manifest", "w")
538            print >>f, manifest
539            f.close()
540            # start 'em up
541            param = { 
542                    'credential': sliver_cred,
543                    }
544            self.pg_call(self.cm_url, 'StartSliver', param, ctxt)
545        except self.ProtoGENIError, e:
546            raise service_error(service_error.federant,
547                    "ProtoGENI: %s %s" % (e.code, e))
548
549        # With manifest in hand, we can export the portal node names.
550        nodes = self.manifest_to_dict(manifest, ignore_debug=True)
551        self.export_store_info(export_certfile, nodes, parent.ssh_port,
552                connInfo)
553        self.generate_portal_configs(parent, topo, pubkey, secretkey, tmpdir, 
554                master, ename, connInfo, services, nodes)
555
556        # Copy software to the staging machine (done after generation to copy
557        # those, too)
558        for d in (tmpdir, lsoftdir):
559            if os.path.isdir(d):
560                for f in os.listdir(d):
561                    if not os.path.isdir("%s/%s" % (d, f)):
562                        if not self.scp_file("%s/%s" % (d, f), 
563                                user, host, "%s/%s" % (stagingdir, f)):
564                            self.log.error("Scp failed")
565                            return False
566
567
568        # Now we wait for the nodes to start on PG
569        status = 'notready'
570        try:
571            while status == 'notready':
572                param = { 
573                        'credential': slice_cred
574                        }
575                r = self.pg_call(self.cm_url, 'SliceStatus', param, ctxt)
576                print r
577                status = r.get('status', 'notready')
578                if status == 'notready':
579                    time.sleep(30)
580        except self.ProtoGENIError, e:
581            raise service_error(service_error.federant,
582                    "ProtoGENI: %s %s" % (e.code, e))
583
584        if status == 'failed':
585            self.log.error('Sliver failed to start on ProtoGENI')
586            try:
587                param = { 
588                        'credential': slice_cred
589                        }
590                self.pg_call(self.cm_url, 'DeleteSliver', param, ctxt)
591            except self.ProtoGENIError, e:
592                raise service_error(service_error.federant,
593                    "ProtoGENI: %s" % e)
594            return False
595        else:
596            parent.state_lock.acquire()
597            parent.allocation[aid]['slice_name'] = slicename
598            parent.allocation[aid]['slice_credential'] = slice_cred
599            parent.allocation[aid]['sliver_credential'] = sliver_cred
600            parent.allocation[aid]['manifest'] = manifest
601            parent.allocation[aid]['certfile'] = certfile
602            parent.allocation[aid]['certpw'] = certpw
603            parent.write_state()
604            parent.state_lock.release()
605
606        # The startcmds for portals and standard nodes (the Master Slave
607        # distinction is going away)
608        gate_cmd = parent.attrs.get('SlaveConnectorStartCmd', '/bin/true')
609        node_cmd = parent.attrs.get('SlaveNodeStartCmd', 'bin/true')
610
611        # Now we have configuration to do for ProtoGENI
612        self.configure_nodes(topo, nodes, user, parent.staging_host,
613                parent.sshd, parent.sshd_config, gate_cmd, node_cmd, 
614                pubkey, secretkey, stagingdir, tmpdir)
615
616        self.start_nodes(user, parent.staging_host, 
617                [ n['hostname'] for n in nodes.values()])
618
619        # Everything has gone OK.
620        return True
621
622class stop_segment(segment_base):
623    def __init__(self, log=None, keyfile=None, debug=False, 
624            ch_url=None, sa_url=None, cm_url=None):
625        segment_base.__init__(self, log=log, keyfile=keyfile, debug=debug,
626                ch_url=cm_url, sa_url=sa_url, cm_url=cm_url)
627
628    def __call__(self, parent, user, stagingdir, slice_cred, certfile, certpw):
629        """
630        Stop a sub experiment by calling swapexp on the federant
631        """
632        host = parent.staging_host
633        rv = False
634        try:
635            # Clean out tar files: we've gone over quota in the past
636            if stagingdir:
637                self.ssh_cmd(user, host, "rm -rf %s" % stagingdir)
638            if slice_cred:
639                self.log.error('Removing Sliver on ProtoGENI')
640                ctxt = fedd_ssl_context(my_cert=certfile, password=certpw)
641                try:
642                    param = { 
643                            'credential': slice_cred
644                            }
645                    self.pg_call(self.cm_url, 'DeleteSlice', param, ctxt)
646                except self.ProtoGENIError, e:
647                    raise service_error(service_error.federant,
648                        "ProtoGENI: %s" % e)
649            return True
650        except self.ssh_cmd_timeout:
651            rv = False
652        return rv
653
654class renew_segment(segment_base):
655    def __init__(self, log=None, debug=False, keyfile=None,
656            ch_url=None, sa_url=None, cm_url=None):
657        segment_base.__init__(self, log=log, keyfile=keyfile, debug=debug,
658                ch_url=cm_url, sa_url=sa_url, cm_url=cm_url)
659
660    def __call__(self, name, scred, interval, certfile, certpw):
661        ctxt = fedd_ssl_context(my_cert=certfile, password=certpw)
662        try:
663            expiration = time.strftime("%Y%m%dT%H:%M:%S",
664                    time.gmtime(time.time() + interval))
665            cred = self.pg_call(self.sa_url, 'GetCredential', {}, ctxt)
666
667            param = {
668                    'credential': scred,
669                    'expiration': expiration
670                    }
671            r = self.pg_call(self.sa_url, 'RenewSlice', param, ctxt)
672            param = {
673                    'credential': cred,
674                    'hrn': name,
675                    'type': 'Slice',
676                    }
677            slice = self.pg_call(self.sa_url, 'Resolve', param, ctxt)
678            uuid = slice.get('uuid', None)
679            if uuid == None:
680                sys.exit('No uuid for %s' % slicename)
681
682            print 'Calling GetCredential (uuid)'
683            param = {
684                    'credential': cred,
685                    'uuid': uuid,
686                    'type': 'Slice',
687                    }
688            new_scred = self.pg_call(self.sa_url, 'GetCredential', param, ctxt)
689            f = open('./new_slice_cred', 'w')
690            print >>f, new_scred
691            f.close()
692
693        except self.ProtoGENIError, e:
694            self.log.error("Failed to extend slice %s: %s" % (name, e))
695            return None
696        try:
697            print 'Calling RenewSlice (CM)'
698            param = {
699                    'credential': new_scred,
700                    }
701            r = self.pg_call(self.cm_url, 'RenewSlice', param, ctxt)
702        except self.ProtoGENIError, e:
703            self.log.warn("Failed to renew sliver for %s: %s" % (name, e))
704
705        return new_scred
706   
Note: See TracBrowser for help on using the repository browser.