Changeset 1f356d3
- Timestamp:
- Dec 1, 2010 3:37:18 PM (14 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master
- Children:
- 5c3d542
- Parents:
- c324ad3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/fedd_image.py
rc324ad3 r1f356d3 39 39 self.add_option("--file", dest="file", 40 40 help="experiment description file") 41 42 def gen_dot_topo(t, labels, dotfile): 41 self.add_option("--group", dest="group", default=None, 42 help="Group nodes by this attribute") 43 44 def make_subgraph(topelems, attr): 45 """ 46 Take a list of topdl elements (Computers and Substrates ) and partition 47 them into groups based on the value of the given attribute. All computers 48 with the same value for the attribute are in a subgraph. A substrate is in 49 the subgraph if all its interfaces are, and in the "default" subgraph if 50 not. 51 """ 52 53 def add_to_map(m, a, v): 54 """ 55 Add this value to the list in m[a] if that list exists, or create it. 56 """ 57 if a in m: m[a].append(v) 58 else: m[a] = [ v] 59 60 sg = { } 61 for e in topelems: 62 if isinstance(e, topdl.Computer): 63 add_to_map(sg, e.get_attribute(attr) or 'default', e) 64 elif isinstance(e, topdl.Substrate): 65 # A little hairy. Make a set of the values of the given attribute 66 # for all the elements in the substrate's interfaces. If that set 67 # has one element, put the substrate in that subgraph. Otherwise 68 # put it in default. 69 atts = set([i.element.get_attribute(attr) or 'default' \ 70 for i in e.interfaces]) 71 72 if len(atts) == 1: add_to_map(sg, atts.pop(), e) 73 else: add_to_map(sg, 'default', e) 74 75 return sg 76 77 def gen_dot_topo(t, labels, dotfile, sg_attr=None): 43 78 """ 44 79 Write a dot description of the topology in t, a topdl.Topology to the open … … 48 83 """ 49 84 85 50 86 # The routine draws a circle for substrates with more than 2 interfaces 51 87 # connected to it, so this makes lists of each of those. … … 53 89 links = [ s for s in t.substrates if len(s.interfaces) == 2] 54 90 55 # Output the nodes. Deal with the possibility that there's no name, but 56 # that's unlikely. 57 for i, n in enumerate(t.elements): 58 if n.name: 59 print >>dotfile, '\t"%s" [shape=box,style=filled,\\' % n.name 60 else: 61 print >>dotfile, \ 62 '\t"unnamed_node%d" [shape=box,style=filled,\\' % i 63 print >>dotfile, '\t\tcolor=black,fillcolor="#60f8c0",regular=1]' 64 65 # Encode the lans and the links 91 # Break into subgraphs by the attribute of one's given 92 if sg_attr: sg = make_subgraph(t.elements + lans, sg_attr) 93 else: sg = { 'default': t.elements + lans } 94 95 96 # Construct subgraphs featurning nodes from those graphs 97 for sn, nodes in sg.items(): 98 # Output the computers and lans in subgraphs, if necessary. Subgraphs 99 # treated as clusters are designated by "cluster" starting the name. 100 # (The default subgraph is not treated as a cluster. 101 if sn != 'default': 102 print >>dotfile, 'subgraph "cluster-%s" {' % sn 103 print >>dotfile, 'label="%s"' % sn 104 else: 105 print >>dotfile, 'subgraph "%s" {' % sn 106 print >>dotfile, 'color="#08c0f8"' 107 print >>dotfile, 'clusterrank="local"' 108 109 # For each node in the subgraph, output its representation 110 for i, n in enumerate(nodes): 111 if isinstance(n, topdl.Computer): 112 if n.name: 113 print >>dotfile, '\t"%s" [shape=box,style=filled,\\' % \ 114 n.name 115 else: 116 print >>dotfile, \ 117 '\t"unnamed_node%d" [shape=box,style=filled,\\' % i 118 print >>dotfile, \ 119 '\t\tcolor=black,fillcolor="#60f8c0",regular=1]' 120 elif isinstance(n, topdl.Substrate): 121 print >>dotfile, '\t"%s" [shape=ellipse, style=filled,\\' % \ 122 n.name 123 print >>dotfile,'\t\tcolor=black,fillcolor="#80c0f8",regular=1]' 124 print >>dotfile, '}' 125 126 # Pull the edges out ot the lans and links 66 127 for l in lans: 67 print >>dotfile, '\t"%s" [shape=ellipse, style=filled,\\' % l.name68 print >>dotfile,'\t\tcolor=black,fillcolor="#80c0f8",regular=1]'69 128 for i in l.interfaces: 70 129 ip = i.get_attribute('ip4_address') … … 90 149 (s.element.name, d.element.name) 91 150 92 def gen_image(top, file, fmt, neato, labels, pix=None ):151 def gen_image(top, file, fmt, neato, labels, pix=None, sg_attr=None): 93 152 """ 94 153 Create a dot formatted input file from the topdl.Topology in top and run … … 109 168 # Look for neato if the executable is unspecified. 110 169 if not neato: 111 for f in ['/usr/bin/neato', '/usr/local/bin/neato', 112 '/usr/bin/dot', '/usr/local/bin/dot']: 170 # If a subgraph attribute has been specified, prefer dot to neato. dot 171 # is more "natural" looking graphs, but neato segregates better. 172 if sg_attr: 173 search_list = ['/usr/bin/dot', '/usr/local/bin/dot', 174 '/usr/bin/neato', '/usr/local/bin/neato'] 175 else: 176 search_list = ['/usr/bin/neato', '/usr/local/bin/neato', 177 '/usr/bin/dot', '/usr/local/bin/dot'] 178 179 for f in search_list: 113 180 if os.access(f, os.X_OK): 114 181 neato = f … … 141 208 % (size, size, dpi) 142 209 else: 143 print >>dotfile, '\tgraph [size="%i,%i", ratio=fill ];' \210 print >>dotfile, '\tgraph [size="%i,%i", ratio=fill, clusterrank="local"compound="true"];' \ 144 211 % (size, size) 145 212 … … 150 217 print >>dotfile, '\tnode [label=""];' 151 218 152 gen_dot_topo(top, labels, dotfile )219 gen_dot_topo(top, labels, dotfile, sg_attr=sg_attr) 153 220 print >>dotfile, "}" 154 221 dotfile.close() … … 311 378 if not opts.serialize_only: 312 379 try: 313 if gen_image(top, file, fmt, opts.neato, opts.labels, opts.pixels) !=0: 380 if gen_image(top, file, fmt, opts.neato, opts.labels, opts.pixels, 381 opts.group) !=0: 314 382 sys.exit("Error rendering graph (subcommand returned non-0)") 315 383 except EnvironmentError, e:
Note: See TracChangeset
for help on using the changeset viewer.