source: fedd/fedd_create.py @ 0de1b94

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

Let service parameters have commas in them, separate fields by ;

  • Property mode set to 100755
File size: 5.3 KB
Line 
1#!/usr/local/bin/python
2
3import sys
4import re
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")
30
31def parse_service(svc):
32    """
33    Pasre a service entry into a hash representing a service entry in a
34    message.  The format is:
35        svc_name:exporter(s):importer(s):attr=val,attr=val
36    The svc_name is teh service name, exporter is the exporting testbeds
37    (comma-separated) importer is the importing testbeds (if any) and the rest
38    are attr=val pairs that will become attributes of the service.  These
39    include parameters and other such stuff.
40    """
41
42    terms = svc.split(':')
43    svcd = { }
44    if len(terms) < 2 or len(terms[0]) == 0 or len(terms[1]) == 0:
45        sys.exit("Bad service description '%s': Not enough terms" % svc)
46   
47    svcd['name'] = terms[0]
48    svcd['export'] = terms[1].split(",")
49    if len(terms) > 2 and len(terms[2]) > 0:
50        svcd['import'] = terms[2].split(",")
51    if len(terms) > 3 and len(terms[3]) > 0:
52        svcd['fedAttr'] = [ ]
53        for t in terms[3].split(";"):
54            i = t.find("=")
55            if i != -1 :
56                svcd['fedAttr'].append(
57                        {'attribute': t[0:i], 'value': t[i+1:]})
58            else:
59                sys.exit("Bad service attribute '%s': no equals sign" % t)
60    return svcd
61
62def project_export_service(master, project):
63    """
64    Output the dict representation of a project_export service for this project
65    and master.
66    """
67    return {
68            'name': 'project_export', 
69            'export': [master], 
70            'importall': True,
71            'fedAttr': [ 
72                { 'attribute': 'project', 'value': project },
73                ],
74            }
75
76# Main line
77service_re = re.compile('^\\s*#\\s*SERVICE:\\s*([\\S]+)')
78parser = fedd_create_opts()
79(opts, args) = parser.parse_args()
80
81
82cert, fid = wrangle_standard_options(opts)
83
84if opts.file:
85    try:
86        lines = [ line for line in open(opts.file, 'r')]
87        exp_desc = "".join(lines)
88    except EnvironmentError:
89        sys.exit("Cannot read description file (%s)" %opts.file)
90else:
91    sys.exit("Must specify an experiment description (--file)")
92
93out_certfile = opts.out_certfile
94
95# Fill in services
96svcs = []
97if opts.master and opts.project:
98    svcs.append(project_export_service(opts.master, opts.project))
99svcs.extend([ parse_service(s) for s in opts.service])
100# Parse all the strings that we can pull out of the file using the service_re.
101svcs.extend([parse_service(service_re.match(l).group(1)) \
102        for l in lines if service_re.match(l)])
103
104if not svcs:
105    print >>sys.stderr, "Warning:Neither master/project nor services requested"
106
107
108msg = { }
109
110if opts.exp_name:
111    msg['experimentID'] = { 'localname': opts.exp_name }
112
113if opts.debug > 1: print >>sys.stderr, msg
114
115try:
116    resp_dict = do_rpc(msg, 
117            opts.url, opts.transport, cert, opts.trusted, 
118            serialize_only=opts.serialize_only,
119            tracefile=opts.tracefile,
120            caller=service_caller('New'), responseBody="NewResponseBody")
121except RPCException, e:
122    exit_with_fault(e)
123except RuntimeError, e:
124    sys.exit("Error processing RPC: %s" % e)
125
126if opts.debug > 1: print >>sys.stderr, resp_dict
127
128try:
129    save_certfile(opts.out_certfile, resp_dict.get('experimentAccess', None))
130except EnvironmentError, e:
131    sys.exit('Could not write to %s: %s' %  (opts.out_certfile, e))
132
133e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None))
134if not e_fedid and not e_local and opts.serialize_only:
135    e_local = "serialize"
136
137msg = { 'experimentdescription': { 'ns2description': exp_desc }, }
138
139if svcs:
140    msg['service'] = svcs
141
142if e_fedid:
143    msg['experimentID'] = { 'fedid': e_fedid }
144elif e_local:
145    msg['experimentID'] = { 'localname': e_local }
146else:
147    sys.exit("New did not return an experiment ID??")
148
149if opts.debug > 1: print >>sys.stderr, msg
150
151try:
152    resp_dict = do_rpc(msg, 
153            opts.url, opts.transport, cert, opts.trusted, 
154            serialize_only=opts.serialize_only,
155            tracefile=opts.tracefile,
156            caller=service_caller('Create'), responseBody="CreateResponseBody")
157except RPCException, e:
158    exit_with_fault(e)
159except RuntimeError, e:
160    sys.exit("Error processing RPC: %s" % e)
161
162if opts.debug > 1: print >>sys.stderr, resp_dict
163
164e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None))
165st = resp_dict.get('experimentStatus', None)
166
167if e_local: print "localname: %s" % e_local
168if e_fedid: print "fedid: %s" % e_fedid
169if st: print "status: %s" % st
170
Note: See TracBrowser for help on using the repository browser.