source: fedd/fedd_create.py @ e2ff75d

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

Add support for user-supplied testbed mappings

  • Property mode set to 100755
File size: 5.8 KB
RevLine 
[d743d60]1#!/usr/local/bin/python
2
3import sys
[b10375f]4import re
[d743d60]5
6from federation.remote_service import service_caller
7from federation.client_lib import client_opts, exit_with_fault, RPCException, \
8        wrangle_standard_options, do_rpc, get_experiment_names, save_certfile
9
10class fedd_create_opts(client_opts):
11    """
12    Extra options that create needs.  Help entries should explain them.
13    """
14    def __init__(self):
15        client_opts.__init__(self)
16        self.add_option("--experiment_cert", dest="out_certfile",
17                type="string", help="output certificate file")
18        self.add_option("--experiment_name", dest="exp_name",
19                type="string", help="Suggested experiment name")
20        self.add_option("--file", dest="file", 
21                help="experiment description file")
22        self.add_option("--project", action="store", dest="project", 
23                type="string",
24                help="Project to export from master")
25        self.add_option("--master", dest="master",
26                help="Master testbed in the federation (pseudo project export)")
27        self.add_option("--service", dest="service", action="append",
28                type="string", default=[],
29                help="Service description name:exporters:importers:attrs")
[fd07c48]30        self.add_option("--map", dest="map", action="append",
31                type="string", default=[],
32                help="Explicit map from testbed label to URI - " + \
33                        "deter:https://users.isi.deterlab/net:13232")
[d743d60]34
35def parse_service(svc):
36    """
37    Pasre a service entry into a hash representing a service entry in a
38    message.  The format is:
39        svc_name:exporter(s):importer(s):attr=val,attr=val
40    The svc_name is teh service name, exporter is the exporting testbeds
41    (comma-separated) importer is the importing testbeds (if any) and the rest
42    are attr=val pairs that will become attributes of the service.  These
43    include parameters and other such stuff.
44    """
45
46    terms = svc.split(':')
47    svcd = { }
48    if len(terms) < 2 or len(terms[0]) == 0 or len(terms[1]) == 0:
49        sys.exit("Bad service description '%s': Not enough terms" % svc)
50   
51    svcd['name'] = terms[0]
52    svcd['export'] = terms[1].split(",")
53    if len(terms) > 2 and len(terms[2]) > 0:
54        svcd['import'] = terms[2].split(",")
55    if len(terms) > 3 and len(terms[3]) > 0:
56        svcd['fedAttr'] = [ ]
[0de1b94]57        for t in terms[3].split(";"):
[d743d60]58            i = t.find("=")
59            if i != -1 :
60                svcd['fedAttr'].append(
61                        {'attribute': t[0:i], 'value': t[i+1:]})
62            else:
63                sys.exit("Bad service attribute '%s': no equals sign" % t)
64    return svcd
65
66def project_export_service(master, project):
67    """
68    Output the dict representation of a project_export service for this project
69    and master.
70    """
71    return {
72            'name': 'project_export', 
73            'export': [master], 
74            'importall': True,
75            'fedAttr': [ 
76                { 'attribute': 'project', 'value': project },
77                ],
78            }
79
80# Main line
[b10375f]81service_re = re.compile('^\\s*#\\s*SERVICE:\\s*([\\S]+)')
[d743d60]82parser = fedd_create_opts()
83(opts, args) = parser.parse_args()
84
85
86cert, fid = wrangle_standard_options(opts)
87
88if opts.file:
89    try:
[b10375f]90        lines = [ line for line in open(opts.file, 'r')]
91        exp_desc = "".join(lines)
[d743d60]92    except EnvironmentError:
93        sys.exit("Cannot read description file (%s)" %opts.file)
94else:
95    sys.exit("Must specify an experiment description (--file)")
96
97out_certfile = opts.out_certfile
98
99# Fill in services
100svcs = []
101if opts.master and opts.project:
102    svcs.append(project_export_service(opts.master, opts.project))
103svcs.extend([ parse_service(s) for s in opts.service])
[b10375f]104# Parse all the strings that we can pull out of the file using the service_re.
105svcs.extend([parse_service(service_re.match(l).group(1)) \
106        for l in lines if service_re.match(l)])
107
[fd07c48]108# Create a testbed map if one is specified
109tbmap = { }
110for m in opts.map:
111    i = m.find(":")
112    if i != -1: tbmap[m[0:i]] = m[i+1:]
113    else: sys.exit("Bad mapping argument: %s" %m )
114
115
[d743d60]116if not svcs:
117    print >>sys.stderr, "Warning:Neither master/project nor services requested"
118
119
120msg = { }
121
122if opts.exp_name:
123    msg['experimentID'] = { 'localname': opts.exp_name }
124
125if opts.debug > 1: print >>sys.stderr, msg
126
127try:
128    resp_dict = do_rpc(msg, 
129            opts.url, opts.transport, cert, opts.trusted, 
130            serialize_only=opts.serialize_only,
131            tracefile=opts.tracefile,
132            caller=service_caller('New'), responseBody="NewResponseBody")
133except RPCException, e:
134    exit_with_fault(e)
135except RuntimeError, e:
136    sys.exit("Error processing RPC: %s" % e)
137
138if opts.debug > 1: print >>sys.stderr, resp_dict
139
140try:
141    save_certfile(opts.out_certfile, resp_dict.get('experimentAccess', None))
142except EnvironmentError, e:
143    sys.exit('Could not write to %s: %s' %  (opts.out_certfile, e))
144
145e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None))
146if not e_fedid and not e_local and opts.serialize_only:
147    e_local = "serialize"
148
149msg = { 'experimentdescription': { 'ns2description': exp_desc }, }
150
151if svcs:
152    msg['service'] = svcs
153
154if e_fedid:
155    msg['experimentID'] = { 'fedid': e_fedid }
156elif e_local:
157    msg['experimentID'] = { 'localname': e_local }
158else:
159    sys.exit("New did not return an experiment ID??")
160
[fd07c48]161if tbmap:
162    msg['testbedmap'] = [ { 'testbed': t, 'uri': u } for t, u in tbmap.items() ]
163
[d743d60]164if opts.debug > 1: print >>sys.stderr, msg
165
166try:
167    resp_dict = do_rpc(msg, 
168            opts.url, opts.transport, cert, opts.trusted, 
169            serialize_only=opts.serialize_only,
170            tracefile=opts.tracefile,
171            caller=service_caller('Create'), responseBody="CreateResponseBody")
172except RPCException, e:
173    exit_with_fault(e)
174except RuntimeError, e:
175    sys.exit("Error processing RPC: %s" % e)
176
177if opts.debug > 1: print >>sys.stderr, resp_dict
178
179e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None))
180st = resp_dict.get('experimentStatus', None)
181
182if e_local: print "localname: %s" % e_local
183if e_fedid: print "fedid: %s" % e_fedid
184if st: print "status: %s" % st
185
Note: See TracBrowser for help on using the repository browser.