source: fedd/fedd_client.py @ cfabc40

axis_examplecompt_changesinfo-opsversion-1.30version-2.00version-3.01version-3.02
Last change on this file since cfabc40 was cfabc40, checked in by Ted Faber <faber@…>, 15 years ago

error strings in output

  • Property mode set to 100755
File size: 22.1 KB
Line 
1#!/usr/local/bin/python
2
3import sys
4import os
5import pwd
6
7from fedd_services import *
8from fedd_internal_services import *
9
10from M2Crypto import SSL, X509
11from M2Crypto.m2xmlrpclib import SSL_Transport
12import M2Crypto.httpslib
13
14from xmlrpclib import ServerProxy, Error, dumps, loads
15from ZSI import SoapWriter
16from ZSI.TC import QName, String, URI, AnyElement, UNBOUNDED, Any
17from ZSI.wstools.Namespaces import SOAP
18from ZSI.fault import FaultType, Detail
19
20import xmlrpclib
21
22from fedd_util import fedid, fedd_ssl_context, pack_soap, unpack_soap, \
23        pack_id, unpack_id, encapsulate_binaries, decapsulate_binaries, \
24        service_caller
25from service_error import *
26
27from optparse import OptionParser, OptionValueError
28
29import parse_detail
30
31# Turn off the matching of hostname to certificate ID
32SSL.Connection.clientPostConnectionCheck = None
33
34class IDFormatException(RuntimeError): pass
35
36class access_method:
37    """Encapsulates an access method generically."""
38    (type_ssh, type_x509, type_pgp) = ('sshPubkey', 'X509', 'pgpPubkey')
39    default_type = type_ssh
40    def __init__(self, buf=None, type=None, file=None):
41        self.buf = buf
42
43        if type != None: self.type = type
44        else: self.type = access_method.default_type
45
46        if file != None:
47            self.readfile(file)
48   
49    def readfile(self, file, type=None):
50        f = open(file, "r")
51        self.buf = f.read();
52        f.close()
53        if type == None:
54            if self.type == None:
55                self.type = access_method.default_type
56        else:
57            self.type = type;
58   
59class node_desc:
60    def __init__(self, image, hardware, count=1):
61        if getattr(image, "__iter__", None) == None:
62            if image == None: self.image = [ ]
63            else: self.image = [ image ]
64        else:
65            self.image = image
66
67        if getattr(hardware, "__iter__", None) == None: 
68            if hardware == None: self.hardware = [ ]
69            else: self.hardware = [ hardware ]
70        else:
71            self.hardware = hardware
72        if count != None: self.count = int(count)
73        else: self.count = 1
74
75class fedd_client_opts(OptionParser):
76    """Encapsulate option processing in this class, rather than in main"""
77    def __init__(self):
78        OptionParser.__init__(self, usage="%prog [opts] (--help for details)",
79                version="0.1")
80
81        self.add_option("-c","--cert", action="store", dest="cert",
82                type="string", help="my certificate file")
83        self.add_option("-d", "--debug", action="count", dest="debug", 
84                default=0, help="Set debug.  Repeat for more information")
85        self.add_option("-s", "--serializeOnly", action="store_true", 
86                dest="serialize_only", default=False,
87                help="Print the SOAP request that would be sent and exit")
88        self.add_option("-T","--trusted", action="store", dest="trusted",
89                type="string", help="Trusted certificates (required)")
90        self.add_option("-u", "--url", action="store", dest="url",
91                type="string",default="https://localhost:23235", 
92                help="URL to connect to (default %default)")
93        self.add_option("-x","--transport", action="store", type="choice",
94                choices=("xmlrpc", "soap"), default="soap",
95                help="Transport for request (xmlrpc|soap) (Default: %default)")
96        self.add_option("--trace", action="store_const", dest="tracefile", 
97                const=sys.stderr, help="Print SOAP exchange to stderr")
98
99class fedd_create_opts(fedd_client_opts):
100    def __init__(self, access_keys, add_key_callback=None, 
101            add_cert_callback=None):
102        fedd_client_opts.__init__(self)
103        self.add_option("-e", "--experiment_cert", dest="out_certfile",
104                type="string", help="output certificate file")
105        self.add_option("-E", "--experiment_name", dest="exp_name",
106                type="string", help="output certificate file")
107        self.add_option("-F","--useFedid", action="store_true",
108                dest="use_fedid", default=False,
109                help="Use a fedid derived from my certificate as user identity")
110        self.add_option("-f", "--file", dest="file", 
111                help="experiment description file")
112        if add_key_callback:
113            self.add_option("-k", "--sshKey", action="callback", type="string", 
114                    callback=add_key_callback, callback_args=(access_keys,),
115                    help="ssh key for access (can be supplied more than once")
116        if add_cert_callback:
117            self.add_option("-K", "--x509Key", action="callback",
118                    type="string", callback=add_cert_callback,
119                    callback_args=(access_keys,),
120                    help="X509 certificate for access " + \
121                        "(can be supplied more than once")
122        self.add_option("-m", "--master", dest="master",
123                help="Master testbed in the federation")
124        self.add_option("-U", "--username", action="store", dest="user",
125                type="string", help="Use this username instead of the uid")
126
127class fedd_split_opts(fedd_create_opts):
128    def __init__(self, access_keys, add_key_callback=None, 
129            add_cert_callback=None):
130        fedd_create_opts.__init__(self, access_keys, add_key_callback,
131                add_cert_callback)
132        self.add_option('-t','--fedkit', action='store_true', dest='fedkit',
133                default=False,
134                help="get output suitable for federation kit install")
135
136
137class fedd_access_opts(fedd_create_opts):
138    def __init__(self, access_keys, node_descs, add_key_callback=None, 
139            add_cert_callback=None, add_node_callback=None):
140        fedd_create_opts.__init__(self, access_keys, add_key_callback,
141                add_cert_callback)
142        self.add_option("-a","--anonymous", action="store_true",
143                dest="anonymous", default=False,
144                help="Do not include a user in the request")
145        self.add_option("-l","--label", action="store", dest="label",
146                type="string", help="Label for output")
147        if add_node_callback:
148            self.add_option("-n", "--node", action="callback", type="string", 
149                    callback=add_node_callback, callback_args=(node_descs,),
150                    help="Node description: image:hardware[:count]")
151        self.add_option("-p", "--project", action="store", dest="project", 
152                type="string",
153                help="Use a project request with this project name")
154        self.add_option("-t", "--testbed", action="store", dest="testbed",
155                type="string",
156                help="Testbed identifier (URI) to contact (required)")
157
158class fedd_exp_data_opts(fedd_client_opts):
159    def __init__(self):
160        fedd_client_opts.__init__(self)
161        self.add_option("-e", "--experiment_cert", dest="exp_certfile",
162                type="string", help="output certificate file")
163        self.add_option("-E", "--experiment_name", dest="exp_name",
164                type="string", help="output certificate file")
165
166def exit_with_fault(dict, out=sys.stderr):
167    """ Print an error message and exit.
168
169    The dictionary contains the FeddFaultBody elements."""
170    codestr = ""
171
172    if dict.has_key('errstr'):
173        codestr = "Error: %s" % dict['errstr']
174
175    if dict.has_key('code'):
176        if len(codestr) > 0 : 
177            codestr += " (%d)" % dict['code']
178        else:
179            codestr = "Error Code: %d" % dict['code']
180
181    print>>out, codestr
182    print>>out, "Description: %s" % dict['desc']
183    sys.exit(dict.get('code', 20))
184# Base class that will do a the SOAP/XMLRPC exchange for a request.
185class fedd_rpc:
186    class RPCException:
187        def __init__(self, fb):
188            self.desc = fb.get('desc', None)
189            self.code = fb.get('code', -1)
190            self.errstr = fb.get('errstr', None)
191
192    def __init__(self, pre): 
193        """
194        Specialize the class for the pre method
195        """
196        self.RequestMessage = globals()["%sRequestMessage" % pre]
197        self.ResponseMessage = globals()["%sResponseMessage" % pre]
198        self.RequestBody="%sRequestBody" % pre
199        self.ResponseBody="%sResponseBody" % pre
200        self.method = pre
201
202        method_call = getattr(feddServiceLocator().getfeddPortType(),
203                self.method, None)
204        if method_call:
205            # The pre method is a fedd external service
206            self.caller = service_caller(self.method, 'getfeddPortType', 
207                    feddServiceLocator, self.RequestMessage, self.RequestBody)
208        else:
209            # The pre method is a fedd internal service
210            self.caller = service_caller(self.method, 
211                    'getfeddInternalPortType', feddInternalServiceLocator,
212                    self.RequestMessage, self.RequestBody)
213
214        self.RPCException = fedd_rpc.RPCException
215
216
217    def add_ssh_key(self, option, opt_str, value, parser, access_keys):
218        try:
219            access_keys.append(access_method(file=value,
220                type=access_method.type_ssh))
221        except IOError, (errno, strerror):
222            raise OptionValueError("Cannot generate sshPubkey from %s: "\
223                    "%s (%d)" % (value,strerror,errno))
224
225    def add_x509_cert(self, option, opt_str, value, parser, access_keys):
226        try:
227            access_keys.append(access_method(file=value,
228                type=access_method.type_x509))
229        except IOError, (errno, strerror):
230            raise OptionValueError("Cannot read x509 cert from %s: %s (%d)" %
231                    (value,strerror,errno))
232    def add_node_desc(self, option, opt_str, value, parser, node_descs):
233        def none_if_zero(x):
234            if len(x) > 0: return x
235            else: return None
236
237        params = map(none_if_zero, value.split(":"));
238       
239        if len(params) < 4 and len(params) > 1:
240            node_descs.append(node_desc(*params))
241        else:
242            raise OptionValueError("Bad node description: %s" % value)
243
244    def get_user_info(self, access_keys):
245        pw = pwd.getpwuid(os.getuid());
246        try_cert=None
247        user = None
248
249        if pw != None:
250            user = pw[0]
251            try_cert = "%s/.ssl/emulab.pem" % pw[5];
252            if not os.access(try_cert, os.R_OK):
253                try_cert = None
254            if len(access_keys) == 0:
255                for k in ["%s/.ssh/id_rsa.pub", "%s/.ssh/id_dsa.pub", 
256                        "%s/.ssh/identity.pub"]:
257                    try_key = k % pw[5];
258                    if os.access(try_key, os.R_OK):
259                        access_keys.append(access_method(file=try_key,
260                            type=access_method.type_ssh))
261                        break
262        return (user, try_cert)
263
264    def do_rpc(self, req_dict, url, transport, cert, trusted, tracefile=None,
265            serialize_only=False):
266        """
267        The work of sending and parsing the RPC as either XMLRPC or SOAP
268        """
269
270        context = None
271        while context == None:
272            try:
273                context = fedd_ssl_context(cert, trusted)
274            except SSL.SSLError, e:
275                # Yes, doing this on message type is not ideal.  The string
276                # comes from OpenSSL, so check there is this stops working.
277                if str(e) == "bad decrypt": 
278                    print >>sys.stderr, "Bad Passphrase given."
279                else: raise
280
281        if transport == "soap":
282            if serialize_only:
283                sw = SoapWriter()
284                sw.serialize(req)
285                print str(sw)
286                sys.exit(0)
287            else:
288                try:
289                    resp = self.caller.call_soap_service(url, req_dict, 
290                            context=context, tracefile=tracefile)
291                except service_error, e:
292                    raise self.RPCException( {\
293                            'code': e.code, 
294                            'desc': e.desc, 
295                            'errstr': e.code_string()\
296                        })
297        elif transport == "xmlrpc":
298            if serialize_only:
299                ser = dumps((req_dict,))
300                print ser
301                sys.exit(0)
302            else:
303                try:
304                    resp = self.caller.call_xmlrpc_service(url, req_dict, 
305                            context=context, tracefile=tracefile)
306                except service_error, e:
307                    raise self.RPCException( {\
308                            'code': e.code, 
309                            'desc': e.desc, 
310                            'errstr': e.code_string()\
311                        })
312
313        else:
314            raise RuntimeError("Unknown RPC transport: %s" % transport)
315
316        if resp.has_key(self.ResponseBody):
317            return resp[self.ResponseBody]
318        else:
319            raise RuntimeError("No body in response??")
320
321# Querying experiment data follows the same control flow regardless of the
322# specific data retrieved.  This class encapsulates that control flow.
323class exp_data(fedd_rpc):
324    def __init__(self, op): 
325        """
326        Specialize the class for the type of data requested (op)
327        """
328
329        fedd_rpc.__init__(self, op)
330        if op =='Vtopo':
331            self.key="vtopo"
332            self.xml='experiment'
333        elif op == 'Vis':
334            self.key="vis"
335            self.xml='vis'
336        elif op == 'Info': pass
337        else:
338            raise TypeError("Bad op: %s" % op)
339
340    def print_xml(self, d, out=sys.stdout):
341        """
342        Print the retrieved data is a simple xml representation of the dict.
343        """
344        str = "<%s>\n" % self.xml
345        for t in ('node', 'lan'):
346            if d.has_key(t): 
347                for x in d[t]:
348                    str += "<%s>" % t
349                    for k in x.keys():
350                        str += "<%s>%s</%s>" % (k, x[k],k)
351                    str += "</%s>\n" % t
352        str+= "</%s>" % self.xml
353        print >>out, str
354
355    def __call__(self):
356        """
357        The control flow.  Compose the request and print the response.
358        """
359        # Process the options using the customized option parser defined above
360        parser = fedd_exp_data_opts()
361
362        (opts, args) = parser.parse_args()
363
364        if opts.trusted != None:
365            if ( not os.access(opts.trusted, os.R_OK) ) :
366                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
367        else:
368            parser.error("--trusted is required")
369
370        if opts.debug > 0: opts.tracefile=sys.stderr
371
372        if opts.cert != None: cert = opts.cert
373
374        if cert == None:
375            sys.exit("No certificate given (--cert) or found")
376
377        if os.access(cert, os.R_OK):
378            fid = fedid(file=cert)
379        else:
380            sys.exit("Cannot read certificate (%s)" % cert)
381
382        if opts.exp_name and opts.exp_certfile:
383            sys.exit("Only one of --experiment_cert and " +\
384                    "--experiment_name permitted");
385
386        if opts.exp_certfile:
387            exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
388
389        if opts.exp_name:
390            exp_id = { 'localname' : opts.exp_name }
391
392        req = { 'experiment': exp_id }
393
394        try:
395            resp_dict = self.do_rpc(req,
396                    opts.url, opts.transport, cert, opts.trusted, 
397                    serialize_only=opts.serialize_only,
398                    tracefile=opts.tracefile)
399        except self.RPCException, e:
400            exit_with_fault(\
401                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
402        except RuntimeError, e:
403            print e
404            sys.exit("Error processing RPC: %s" % e)
405
406        if getattr(self, 'key', None):
407            try:
408                if resp_dict.has_key(self.key):
409                    self.print_xml(resp_dict[self.key])
410            except RuntimeError, e:
411                sys.exit("Bad response. %s" % e.message)
412        else:
413            print resp_dict
414
415class terminate(fedd_rpc):
416    def __init__(self): 
417        """
418        Termination request
419        """
420
421        fedd_rpc.__init__(self, "Terminate")
422
423    def __call__(self):
424        """
425        The control flow.  Compose the request and print the response.
426        """
427        # Process the options using the customized option parser defined above
428        parser = fedd_exp_data_opts()
429
430        (opts, args) = parser.parse_args()
431
432        if opts.trusted != None:
433            if ( not os.access(opts.trusted, os.R_OK) ) :
434                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
435        else:
436            parser.error("--trusted is required")
437
438        if opts.debug > 0: opts.tracefile=sys.stderr
439
440        if opts.cert != None: cert = opts.cert
441
442        if cert == None:
443            sys.exit("No certificate given (--cert) or found")
444
445        if os.access(cert, os.R_OK):
446            fid = fedid(file=cert)
447        else:
448            sys.exit("Cannot read certificate (%s)" % cert)
449
450        if opts.exp_name and opts.exp_certfile:
451            sys.exit("Only one of --experiment_cert and " +\
452                    "--experiment_name permitted");
453
454        if opts.exp_certfile:
455            exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
456
457        if opts.exp_name:
458            exp_id = { 'localname' : opts.exp_name }
459
460        req = { 'experiment': exp_id }
461
462        try:
463            resp_dict = self.do_rpc(req,
464                    opts.url, opts.transport, cert, opts.trusted, 
465                    serialize_only=opts.serialize_only,
466                    tracefile=opts.tracefile)
467        except self.RPCException, e:
468            exit_with_fault(\
469                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
470        except RuntimeError, e:
471            print e
472            sys.exit("Error processing RPC: %s" % e)
473
474        eid = resp_dict.get('experimentID', None)
475        if eid:
476            for id in eid:
477                for k in id.keys():
478                    if k == 'fedid': print "%s: %s" % (k,fedid(bits=id[k]))
479                    else: print "%s: %s" % (k, id[k])
480
481class create(fedd_rpc):
482    def __init__(self): 
483        fedd_rpc.__init__(self, "Create")
484    def __call__(self):
485        access_keys = []
486        # Process the options using the customized option parser defined above
487        parser = fedd_create_opts(access_keys, self.add_ssh_key,
488                self.add_x509_cert)
489
490        (opts, args) = parser.parse_args()
491
492        if opts.trusted != None:
493            if ( not os.access(opts.trusted, os.R_OK) ) :
494                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
495        else:
496            parser.error("--trusted is required")
497
498        if opts.debug > 0: opts.tracefile=sys.stderr
499
500        (user, cert) = self.get_user_info(access_keys)
501
502        if opts.user: user = opts.user
503
504        if opts.cert != None: cert = opts.cert
505
506        if cert == None:
507            sys.exit("No certificate given (--cert) or found")
508
509        if os.access(cert, os.R_OK):
510            fid = fedid(file=cert)
511            if opts.use_fedid == True:
512                user = fid
513        else:
514            sys.exit("Cannot read certificate (%s)" % cert)
515
516        if opts.file:
517            exp_desc = ""
518            try:
519                f = open(opts.file, 'r')
520                for line in f:
521                    exp_desc += line
522                f.close()
523            except IOError:
524                sys.exit("Cannot read description file (%s)" %opts.file)
525        else:
526            sys.exit("Must specify an experiment description (--file)")
527
528        if not opts.master:
529            sys.exit("Must specify a master testbed (--master)")
530
531        out_certfile = opts.out_certfile
532
533        msg = {
534                'experimentdescription': { 'ns2description': exp_desc },
535                'master': opts.master,
536                'user' : [ {\
537                        'userID': pack_id(user), \
538                        'access': [ { a.type: a.buf } for a in access_keys]\
539                        } ]
540                }
541
542        if opts.exp_name:
543            msg['experimentID'] = { 'localname': opts.exp_name }
544
545        if opts.debug > 1: print >>sys.stderr, msg
546
547        try:
548            resp_dict = self.do_rpc(msg, 
549                    opts.url, opts.transport, cert, opts.trusted, 
550                    serialize_only=opts.serialize_only,
551                    tracefile=opts.tracefile)
552        except self.RPCException, e:
553            exit_with_fault(\
554                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
555        except RuntimeError, e:
556            sys.exit("Error processing RPC: %s" % e)
557
558        if opts.debug > 1: print >>sys.stderr, resp_dict
559
560        ea = resp_dict.get('experimentAccess', None)
561        if out_certfile and ea and ea.has_key('X509'):
562            try:
563                f = open(out_certfile, "w")
564                print >>f, ea['X509']
565                f.close()
566            except IOError:
567                sys.exit('Could not write to %s' %  out_certfile)
568        eid = resp_dict.get('experimentID', None)
569        if eid:
570            for id in eid:
571                for k in id.keys():
572                    print "%s: %s" % (k, id[k])
573
574class split(fedd_rpc):
575    def __init__(self): 
576        fedd_rpc.__init__(self, "Ns2Split")
577    def __call__(self):
578        access_keys = []
579        # Process the options using the customized option parser defined above
580        parser = fedd_split_opts(access_keys, self.add_ssh_key,
581                self.add_x509_cert)
582
583        (opts, args) = parser.parse_args()
584
585        if opts.trusted != None:
586            if ( not os.access(opts.trusted, os.R_OK) ) :
587                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
588        else:
589            parser.error("--trusted is required")
590
591        if opts.debug > 0: opts.tracefile=sys.stderr
592
593        if opts.cert != None: cert = opts.cert
594        else: cert = None
595
596        if cert == None:
597            sys.exit("No certificate given (--cert) or found")
598
599        if os.access(cert, os.R_OK):
600            fid = fedid(file=cert)
601            if opts.use_fedid == True:
602                user = fid
603        else:
604            sys.exit("Cannot read certificate (%s)" % cert)
605
606        if opts.file:
607            exp_desc = ""
608            try:
609                f = open(opts.file, 'r')
610                for line in f:
611                    exp_desc += line
612                f.close()
613            except IOError:
614                sys.exit("Cannot read description file (%s)" %opts.file)
615        else:
616            sys.exit("Must specify an experiment description (--file)")
617
618        if not opts.master:
619            sys.exit("Must specify a master testbed (--master)")
620
621        out_certfile = opts.out_certfile
622
623        msg = {
624                'description': { 'ns2description': exp_desc },
625                'master': opts.master,
626                'include_fedkit': opts.fedkit,
627                }
628
629        if opts.debug > 1: print >>sys.stderr, msg
630
631        try:
632            resp_dict = self.do_rpc(msg, 
633                    opts.url, opts.transport, cert, opts.trusted, 
634                    serialize_only=opts.serialize_only,
635                    tracefile=opts.tracefile)
636        except self.RPCException, e:
637            exit_with_fault(\
638                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
639        except RuntimeError, e:
640            sys.exit("Error processing RPC: %s" % e)
641
642        if opts.debug > 1: print >>sys.stderr, resp_dict
643
644        out = resp_dict.get('output', None)
645
646        for line in out.splitlines():
647            print "%s" % line
648
649class access(fedd_rpc):
650    def __init__(self):
651        fedd_rpc.__init__(self, "RequestAccess")
652
653    def print_response_as_testbed(self, resp, label, out=sys.stdout):
654        """Print the response as input to the splitter script"""
655
656        e = resp['emulab']
657        p = e['project']
658        fields = { 
659                "Boss": e['boss'],
660                "OpsNode": e['ops'],
661                "Domain": e['domain'],
662                "FileServer": e['fileServer'],
663                "EventServer": e['eventServer'],
664                "Project": unpack_id(p['name'])
665                }
666        if (label != None): print >> out, "[%s]" % label
667
668        for l, v in fields.iteritems():
669            print >>out, "%s: %s" % (l, v)
670
671        for u in p['user']:
672            print >>out, "User: %s" % unpack_id(u['userID'])
673
674        for a in e['fedAttr']:
675            print >>out, "%s: %s" % (a['attribute'], a['value'])
676
677    def __call__(self):
678        access_keys = []
679        node_descs = []
680        proj = None
681
682        # Process the options using the customized option parser defined above
683        parser = fedd_access_opts(access_keys, node_descs, self.add_ssh_key,
684                self.add_x509_cert, self.add_node_desc)
685
686        (opts, args) = parser.parse_args()
687
688        if opts.testbed == None:
689            parser.error("--testbed is required")
690
691        if opts.trusted != None:
692            if ( not os.access(opts.trusted, os.R_OK) ) :
693                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
694        else:
695            parser.error("--trusted is required")
696
697        if opts.debug > 0: opts.tracefile=sys.stderr
698
699        (user, cert) = self.get_user_info(access_keys)
700
701        if opts.user: user = opts.user
702
703        if opts.cert != None: cert = opts.cert
704
705        if cert == None:
706            sys.exit("No certificate given (--cert) or found")
707
708        if os.access(cert, os.R_OK):
709            fid = fedid(file=cert)
710            if opts.use_fedid == True:
711                user = fid
712        else:
713            sys.exit("Cannot read certificate (%s)" % cert)
714
715        msg = {
716                'allocID': pack_id('test alloc'),
717                'destinationTestbed': pack_id(opts.testbed),
718                'serviceAccess' : [ { a.type: a.buf } for a in access_keys ],
719                'createAccess' : [ { a.type: a.buf } for a in access_keys ],
720                }
721
722        if len(node_descs) > 0:
723            msg['resources'] = { 
724                    'node': [ 
725                        { 
726                            'image':  n.image ,
727                            'hardware':  n.hardware,
728                            'count': n.count,
729                        } for n in node_descs],
730                    }
731
732        if opts.project != None:
733            if not opts.anonymous and user != None:
734                msg['project'] = {
735                        'name': pack_id(opts.project),
736                        'user': [ { 'userID': pack_id(user) } ],
737                        }
738            else:
739                msg['project'] = { 'name': pack_id(opts.project) }
740        else:
741            if not opts.anonymous and user != None:
742                msg['user'] = [ { 'userID': pack_id(user) } ]
743            else:
744                msg['user'] = [];
745
746        if opts.debug > 1: print >>sys.stderr, msg
747
748        try:
749            resp_dict = self.do_rpc(msg, 
750                    opts.url, opts.transport, cert, opts.trusted, 
751                    serialize_only=opts.serialize_only,
752                    tracefile=opts.tracefile)
753        except self.RPCException, e:
754            exit_with_fault(\
755                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
756        except RuntimeError, e:
757            sys.exit("Error processing RPC: %s" % e.message)
758
759        if opts.debug > 1: print >>sys.stderr, resp_dict
760        self.print_response_as_testbed(resp_dict, opts.label)
761
762cmds = {\
763        'create': create(),\
764        'split': split(),\
765        'access': access(),\
766        'vtopo': exp_data('Vtopo'),\
767        'vis': exp_data('Vis'),\
768        'info': exp_data('Info'),\
769        'terminate': terminate(),\
770    }
771
772operation = cmds.get(sys.argv[1], None)
773if operation:
774    del sys.argv[1]
775    operation()
776else:
777    sys.exit("Bad command: %s.  Valid ones are: %s" % \
778            (sys.argv[1], ", ".join(cmds.keys())))
779
Note: See TracBrowser for help on using the repository browser.