#!/usr/local/bin/python import sys import re import os from optparse import OptionParser from federation.remote_service import service_caller from federation import topdl class constraint: def __init__(self, required=False, accepts=None, provides=None): self.required = required self.accepts = accepts or [] self.provides = provides or [] def __str__(self): return "%s:%s:%s" % (self.required, ",".join(self.provides), ",".join(self.accepts)) def add_to_map(exp, mark): valid_marks = ('stub', 'transit') nn, r, p, a = exp.split(":") p = p.split(",") a = a.split(",") mark[nn] = constraint(r == 'required', p, a) def annotate_topo(top, mark): def make_new_name(names): i = 0 n = "mark%d" % i while n in names: i += 1 n = "mark%d" % i names.add(n) return n snames = set([ s.name for s in top.substrates ]) for e in top.elements: for n in e.name: if n in mark: if all([ not i.get_attribute('export') for i in e.interface]): con = mark[n] inames = set([x.name for x in e.interface]) sn = make_new_name(snames) ii = make_new_name(inames) s = topdl.Substrate(name=sn) i = topdl.Interface(substrate=sn, name=ii, element=e, attribute=[ topdl.Attribute(attribute='composition_point', value='True'), topdl.Attribute(attribute='required', value = "%s" % con.required), topdl.Attribute(attribute='provides', value=",".join(con.provides)), topdl.Attribute(attribute='accepts', value=",".join(con.accepts)), ] ) e.interface.append(i) top.substrates.append(s) top.incorporate_elements() def remote_ns2topdl(uri, desc, cert): req = { 'description' : { 'ns2description': desc }, } try: r = service_caller('Ns2Topdl')(uri, req, cert) except: return None if r.has_key('Ns2TopdlResponseBody'): r = r['Ns2TopdlResponseBody'] ed = r.get('experimentdescription', None) if 'topdldescription' in ed: return topdl.Topology(**ed['topdldescription']) else: return None else: return None const_re = re.compile("\s*#\s*COMPOSITION:\s*([^:]+:[^:]+:.*)") parser = OptionParser() parser.add_option('--url', dest='url', default="http://localhost:13235", help='url of ns2 to topdl service') parser.add_option('--certfile', dest='cert', default=None, help='Certificate to use as identity') opts, args = parser.parse_args() if opts.cert: cert = opts.cert elif os.access(os.path.expanduser("~/.ssl/emulab.pem"), os.R_OK): cert = os.path.expanduser("~/.ssl/emulab.pem") else: cert = None for fn in args: marks = { } contents = "" try: f = open(fn, "r") for l in f: contents += l m = const_re.search(l) if m: add_to_map(re.sub('\s', '', m.group(1)), marks) except EnvironmentError, e: print >>sys.stderr, "Error on %S: %s" % (fn, e) print marks top = remote_ns2topdl(opts.url, contents, cert) if top: annotate_topo(top, marks) print topdl.topology_to_xml(top) else: sys.exit("Topology conversion failed on %s" % fn)