Changeset d0ae12d


Ignore:
Timestamp:
Aug 21, 2008 11:07:49 AM (16 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
Children:
6546868
Parents:
7add1a3
Message:

generate visualization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_create_experiment.py

    r7add1a3 rd0ae12d  
    77from M2Crypto.SSL.SSLServer import SSLServer
    88import M2Crypto.httpslib
     9
     10import xml.parsers.expat
    911
    1012import re
     
    3133            cert_file=None,
    3234            cert_pwd=None,
     35            debug=False,
    3336            muxmax=2,
    3437            project_user = "faber",
     
    5356        self.cert_file = cert_file
    5457        self.cert_pwd = cert_pwd
     58        self.debug = debug
    5559        self.muxmax = muxmax
    5660        self.project_user = project_user
     
    113117        scp a file to the remote host.
    114118        """
    115        
    116         rv = call([self.scp_exec, file, "%s@%s:%s" % (user, host, dest)])
    117         if rv == 0:
     119
     120        scp_cmd = [self.scp_exec, file, "%s@%s:%s" % (user, host, dest)]
     121        if not self.debug:
     122            rv = call(scp_cmd)
     123        else:
     124            print "debug: %s" % " ".join(scp_cmd)
     125            rv = 0
     126
     127        return rv == 0
     128
     129    def ssh_cmd(self, user, host, cmd, wname=None, timeout=0):
     130        sh_str = "%s %s@%s %s" % (self.ssh_exec, user, host, cmd)
     131
     132        if not self.debug:
     133            # This should be done more carefully
     134            sub = Popen(sh_str, shell=True)
     135            return sub.wait() == 0
     136        else:
     137            print "debug: %s" % sh_str
    118138            return True
    119         else:
    120             # XXX
    121             print >>sys.stdout, "Failed to scp %s to %s@%s" % (file, user, host)
    122             return False
    123 
    124     def ssh_cmd(self, user, host, cmd, wname=None, timeout=0):
    125         # This should be done more carefully
    126         sub = Popen("%s %s@%s %s" % (self.ssh_exec, user, host, cmd),
    127                 shell=True)
    128         return sub.wait() == 0
    129139
    130140    def ship_scripts(self, host, user, dest_dir):
     
    160170        pid = tbparams[tb]['project']
    161171        # XXX
    162         # base_confs = ( "hosts", "vtopo.xml", "viz.xml")
    163         base_confs = ( "hosts", "vtopo.xml")
     172        base_confs = ( "hosts", "vtopo.xml", "viz.xml")
    164173        tclfile = "%s.%s.tcl" % (eid, tb)
    165174        expinfo_exec = "/usr/testbed/bin/expinfo"
     
    317326                            % (self.ssh_keygen, rv))
    318327
    319     def genviz(self, topo_file, viz_file): pass
     328    def genviz(self, topo_file, viz_file):
     329        """
     330        Generate the visualization file from the topology file
     331        """
     332
     333        class topo_parse:
     334            """
     335            Parse the vtopo file into a set of lans, links and nodes.
     336            """
     337            def __init__(self):
     338                self.links = {}         # Each link is a list of at most 2 nodes
     339                self.lans = {}          # Lans have more than 2 nodes
     340                self.nodes = {}         # The nodes in the experiment
     341                self.lan = {}           # The current link/len being collected
     342                self.in_lan = False     # Is the conatining element lan?
     343                self.in_node = False    # Is the conatining element node?
     344                self.chars = None       # Last set of marked-up chars
     345
     346            def start_element(self, name, attrs):
     347                """
     348                New element started.  Set flags and clear lan
     349                """
     350                if name == "node":
     351                    self.in_node = True
     352                elif name == "lan":
     353                    self.in_lan = True
     354                    self.lan.clear()
     355           
     356            def end_element(self, name):
     357                """
     358                End of element.  Collect data if appropriate
     359
     360                If a node or lan is ending, create an entry in nodes or
     361                lans/links.  If a vname/vnode in a node or lan is ending,
     362                capture its name.  If a lan is ending, add the node to the
     363                evolving link or lan.
     364                """
     365                if name == "node":
     366                    self.in_node = False
     367                if self.in_node and name == "vname":
     368                    self.nodes[self.chars] = "node"
     369                if self.in_lan:
     370                    if name != "lan":
     371                        if name == 'vname' or name == 'vnode':
     372                            self.lan[name] = self.chars
     373                    else:
     374                        self.in_lan = False
     375                        vname = self.lan['vname']
     376                        links = self.links.get(vname, [])
     377                        if len(links) == 2:
     378                            # This link needs to be a lan instead
     379                            self.nodes[vname] = "lan"
     380                            self.lans[vname] = \
     381                                    [ l for l in links, self.lan['vnode'] ]
     382                            del self.links[vname]
     383                            self.lan = {}
     384                            return
     385                        lans = self.lans.get(vname, [])
     386                        if len(lans) > 0:
     387                            lans.append(self.lan['vnode'])
     388                            self.lan = {}
     389                            return
     390                        if not vname in self.links:
     391                            self.links[vname] = []
     392                        self.links[vname].append(self.lan['vnode'])
     393                        self.lan = {}
     394                        return
     395
     396            def found_chars(self, data):
     397                """
     398                Capture marked up chars for later
     399                """
     400                self.chars = data
     401
     402        neato = "/usr/local/bin/neato"
     403        # These are used to parse neato output and to create the visualization
     404        # file.
     405        vis_re = re.compile('^\s*"?([\w\-]+)"?\s+\[.*pos="(\d+),(\d+)"')
     406        vis_fmt = "<node><name>%s</name><x>%s</x><y>%s</y><type>" + \
     407                "%s</type></node>"
     408        try:
     409            df, dotname = tempfile.mkstemp()
     410            dotfile = os.fdopen(df, 'w')
     411            infile = open(topo_file, 'r')
     412            out = open(viz_file, "w")
     413        except IOError:
     414            raise service_error(service_error.internal,
     415                    "Failed to open file in genviz")
     416
     417        # Parse the topology file using XML tools
     418        tp = topo_parse();
     419        parser = xml.parsers.expat.ParserCreate()
     420        parser.StartElementHandler = tp.start_element
     421        parser.EndElementHandler = tp.end_element
     422        parser.CharacterDataHandler = tp.found_chars
     423
     424        parser.ParseFile(infile)
     425
     426        # Generate a dot/neato input file from the links, nodes and lans
     427        try:
     428            print >>dotfile, "graph G {"
     429            for n in tp.nodes.keys():
     430                print >>dotfile, '\t"%s"' % n
     431            for l in tp.links.keys():
     432                print >>dotfile, " -- ".join(tp.links[l])
     433            for l in tp.lans.keys():
     434                for n in tp.lans[l]:
     435                    print >>dotfile, '\t "%s" -- "%s"' % (n,l)
     436            print >>dotfile, "}"
     437            dotfile.close()
     438        except IOError:
     439            raise service_error(service_error.internal, "Cannot write dot file")
     440
     441        # Use dot to create a visualization
     442        dot = Popen([neato, '-Gstart=rand', '-Gepsilon=0.005', '-Gmaxiter=2000',
     443                '-Gpack=true', dotname], stdout=PIPE)
     444
     445        # Translate dot to emulab format
     446        try:
     447            print >>out, "<vis>"
     448            for line in dot.stdout:
     449                m = vis_re.match(line)
     450                if m:
     451                    n, x, y = (m.group(1), m.group(2), m.group(3))
     452                    if tp.nodes.has_key(n):
     453                        print >>out, vis_fmt % (n, x, y, tp.nodes[n])
     454            print >>out, "</vis>"
     455            out.close()
     456        except IOError:
     457            raise service_error(service_error.internal,
     458                    "Failed to write visualization file")
     459        rv = dot.wait()
     460        os.remove(dotname)
     461        return rv == 0
     462
    320463
    321464    def get_access(self, tb, nodes, user, tbparam):
     
    778921        fail_soft = False
    779922        # XXX
    780         startem = True
     923        startem = False
    781924
    782925        try:
     
    851994                        "Bad tcl parse? %s" % line)
    852995
     996        self.genviz(self.tmpdir + "/vtopo.xml", self.tmpdir + "/viz.xml")
    853997        if not startem: return True
    854998
     
    8931037   
    8941038    parser = OptionParser()
     1039    parser.add_option('-d', '--debug', dest='debug', default=False,
     1040            action='store_true', help='print actions rather than take them')
    8951041    parser.add_option('-f', '--file', dest='tcl', help='tcl file to parse')
    8961042    opts, args  = parser.parse_args()
     
    9071053
    9081054    obj = fedd_create_experiment_local(
     1055            debug=opts.debug,
    9091056            scripts_dir="/users/faber/testbed/federation",
    9101057            cert_file="./fedd_client.pem", cert_pwd="faber",
Note: See TracChangeset for help on using the changeset viewer.