# HG changeset patch # User igor # Date 1194717519 -7200 # Node ID 308b524d9a7047552bf7e9f192e5fdc4df434143 # Parent ec48cf129028265de39714245d0fc515d8c1bad6 Многочисленные изменения Перевод на ОО-модель Various changes Transit to OO-model Real devices can be configured Interfaces names Cross bridges diff -r ec48cf129028 -r 308b524d9a70 examples/example1.py --- a/examples/example1.py Thu Oct 25 22:24:38 2007 +0300 +++ b/examples/example1.py Sat Nov 10 19:58:39 2007 +0200 @@ -1,7 +1,7 @@ import os domain=os.environ['xendomain'] -network='netw' +network='example1' domains = [ 'qua1', 'qua2', 'dyn3', 'qua4', 'qua5', 'dyn6', 'cisco1', 'linux1', 'windows1', 'mac1' ] domain_types = [ 'quagga', 'quagga', 'xenomips', 'quagga', 'quagga', 'xenomips','cisco', 'linux', 'windows', 'macosx' ] diff -r ec48cf129028 -r 308b524d9a70 xendomain.py --- a/xendomain.py Thu Oct 25 22:24:38 2007 +0300 +++ b/xendomain.py Sat Nov 10 19:58:39 2007 +0200 @@ -54,6 +54,13 @@ #builder='linux' cpu_cap = 10 +for br in bridges: + if not br in vbridges_table.keys(): + vbridges_table[br]=[] + +for domain in domains: + if not domain in connection_table.keys(): + connection_table[domain]='true' vbridges = vbridges_table[name] diff -r ec48cf129028 -r 308b524d9a70 xentaur.py --- a/xentaur.py Thu Oct 25 22:24:38 2007 +0300 +++ b/xentaur.py Sat Nov 10 19:58:39 2007 +0200 @@ -8,8 +8,13 @@ sys.path.append('/etc/xen') sys.path.append(xentaur_path) -network='snrs_ipsec_rsa_1' -domain='qua1' +#network='snrs_ipsec_rsa_1' +node_object={} +link_object={} +bridge_object={} + +network='icnd2' +domain='sw1' from xendomain import * bridges_turned_down=[] @@ -43,14 +48,15 @@ def start_bridges(): unbound_bridges=set(bridges)-set(real_bridges) - create_unbound_bridges="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges)) - create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges)) - create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges)) + script="" + script="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges)) + script+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges)) + script+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges)) print """#!/bin/sh # create unbound bridges -%(create_unbound_bridges)s -""" % {'create_unbound_bridges' : create_unbound_bridges} +%s +""" % (script) def start_domain(domain): print "sudo xm create "+xentaur_path+"/xendomain.py "+" domain="+domain+" network="+network+" && sleep 1 && sudo xm sched-credit -d $(sudo xm list | grep "+domain+" | awk '{print $2}') -c 10 && sleep 1" @@ -91,20 +97,74 @@ stop_all(1) start_all() +#################################################### + +def create_objects(): + create_node_objects() + create_bridge_objects() + create_link_objects() + +def create_node_objects(): + for dom in domains: + node_object[dom]=Node(dom) + +def create_bridge_objects(): + for bridge in bridges: + bridge_object[bridge]=Bridge(bridge) + +def create_link_objects(): + + for node, bridges_raw in vbridges_table.iteritems(): + interface=0 + j=0 + for this_bridge in bridges_raw: + int_label="" + if this_bridge.find(':') != -1: + res = this_bridge.split(':') + this_bridge= res[0] + bridges_raw[j] = this_bridge + int_label = res[1] + if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links: + name="%s %s %s" % (node,interface,this_bridge) + link_object[name]=Link(name,node,interface,this_bridge,int_label) + interface+=1 + vbridges_table[node]=bridges_raw + + for node, bridges_raw in bridge_bridge_table.iteritems(): + interface=0 + j=0 + for this_bridge in bridges_raw: + int_label="" + if this_bridge.find(':') != -1: + res = this_bridge.split(':') + this_bridge= res[0] + bridges_raw[j] = this_bridge + int_label = res[1] + if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links: + name="%s %s %s" % (node,interface,this_bridge) + link_object[name]=Link(name,node,interface,this_bridge,int_label) + interface+=1 + bridge_bridge_table[node]=bridges_raw + + for node,interface,bridge in temporary_links: + name="%s %s %s" % (node,interface,bridge) + link_object[name]=Link(name,node,interface,this_bridge) + + for node,interface,bridge in broken_links: + name="%s %s %s" % (node,interface,bridge) + link_object[name]=Link(name,node,interface,this_bridge) + + +#################################################### + def screen(): - N=1 + wait_seconds=5 screens=[] for domain in domains: - screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do sudo xm console "+domain+" ; echo Retrying in 5 seconds...; sleep 5; done'") - N+=1 + screens.append("screen -t %s %s sh -c 'while true; do %s ; echo Retrying in %s secods...; sleep %s ; clear; done'" % + (domain,domains.index(domain),node_object[domain].console_string(),wait_seconds,wait_seconds)) screenlist="\n".join(screens) -# -# Previous terminal acccess commands: -# ip="192.168.80."+str(200+N) -# screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do ssh root@"+ip+" ; done'") -# - hardstatus='hardstatus string "%{rk}Xentaur%{bk}@%H %{gk}%c %{yk}%d.%m %{wk}%?%-Lw%?%{bw}%n*%f%t%?(%u)%?%{wk}%?%+Lw%?"' f=open(screenrc, "w"); @@ -119,25 +179,6 @@ f.close() print "# GNU Screen config file is written to: %s" % screenrc -def graph_node(node): - i=0 - domain_type={} - for domain in domains: - domain_type[domain]=domain_types[i] - i+=1 - return node+" [label=\" "+node+"\",shapefile=\"shapes/all/"+domain_type[node]+".png\",fontcolor=black,fontsize=16]" - -def graph_bridge(bridge): - if bridge in hidden_bridges: - return "" - if bridge in real_bridges: - return "%s [shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (bridge) - elif bridge in bridges_turned_down: - return "%s [shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (bridge) - else: - return "%s [shape=none,shapefile=\"shapes/all/switch.png\"]" % (bridge) - - def graph(): nodelist="" bridgelist="" @@ -145,50 +186,12 @@ physicallist="" networklist="" - nodelist=";\n ".join(map(graph_node,nodes)) + nodelist=";\n ".join(map(lambda node: node_object[node].graphviz_string(),nodes)) if nodelist: nodelist += ";" - - bridgelist=";\n ".join(map(graph_bridge,bridges)) + bridgelist=";\n ".join(map(lambda bridge: bridge_object[bridge].graphviz_string(),bridges)) if bridgelist: bridgelist += ";" - - links=[] - for host, bridges_raw in vbridges_table.iteritems(): - i=0 - for this_bridge in bridges_raw: - if this_bridge in hidden_bridges or not this_bridge: - continue - if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links: - links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(bridges_raw.index(this_bridge))+"/0\"]") - i+=1 - - for link in temporary_links: - links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",color=blue,len=10,w=5,weight=5]") - - for link in broken_links: - links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",style=dashed]") - - - # bridge-bridge links - for host, bridges_raw in bridge_bridge_table.iteritems(): - i=0 - for this_bridge in bridges_raw: - if this_bridge in hidden_bridges or not this_bridge: - continue - if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links: - links.append(host+" -- "+this_bridge) - i+=1 - - - - linklist=";\n ".join(links) - - graph_dot = { - 'nodelist' : nodelist, - 'bridgelist' : bridgelist, - 'linklist' : linklist, - 'physicallist' : physicallist, - 'networklist' : networklist, - } + linklist=";\n ".join(map(lambda link: link_object[link].graphviz_string(),link_object.keys())) + if linklist: linklist += ";" f = open(network+".dot", "w"); f.write (""" @@ -196,33 +199,31 @@ edge [len=1.25]; splines=true; // nodes - - node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"]; - %(nodelist)s +// node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"]; + %s // bridges - - node [shape=none,shapefile="shapes/all/switch.png"]; - %(bridgelist)s +// node [shape=none,shapefile="shapes/all/switch.png"]; + %s // physical - node [shape=rectangle,color=blue]; - %(physicallist)s + %s // networks (not bridges, not physical) node [shape=rectangle,color=green]; - %(networklist)s + %s // links (between nodes and bridges) - %(linklist)s + %s }; -""" % graph_dot) +""" % (nodelist, bridgelist, physicallist, networklist, linklist)) f.close() run_command("neato -Tpng -o %s.png %s.dot "%(network,network)) run_command("neato -Tjpg -o %s.jpg %s.dot "%(network,network)) run_command("neato -Tsvg -o %s.svg %s.dot "%(network,network)) + run_command("neato -Tcmapx -o %s.cmapx -NURL=http://google.com %s.dot "%(network,network)) print "# Network map is written to files: %s.{png,svg,jpg,dot}" % network def autoredraw(): @@ -233,7 +234,6 @@ ipshell = IPShellEmbed() ipshell() - def show_usage(): print """Usage: xentaur [] @@ -282,20 +282,79 @@ def dump_start(self,filter=""): dump_start(self.name,filter) + def is_hidden(self): + return self.name in hidden_bridges + def is_real(self): + return self.name in real_bridges + def is_turned_down(self): + return self.name in bridges_turned_down + def is_cross(self): + return self.name in cross_bridges -class Domain: + def graphviz_string(self): + if self.is_hidden(): + return "" + elif self.is_cross(): + return "%s [shape=circle,height=0.03,color=black,fillcolor=black,style=filled,label=\"\"]" % (self.name) + elif self.is_real(): + return "%s [color=white,shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (self.name) + elif self.is_turned_down(): + return "%s [color=white,shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (self.name) + else: + return "%s [color=white,shape=none,shapefile=\"shapes/all/switch.png\"]" % (self.name) + + +class Node: def __init__ (self,name): self.name=name + self.type=domain_types[domains.index(name)] def start(self): return "" def stop(self): return "" def start_commandline(self): return "" - def graphviz(self): - return "" def get_domain_id(self): return get_domain_id(self.name) + def graphviz_string(self): + return self.name+" [color=white,shape=plaintext,label=\" "+self.name+"\",shapefile=\"shapes/all/"+\ + domain_types[domains.index(self.name)]+".png\",fontcolor=black,fontsize=16,target=\"http://google.com\"]" + def console_string(self): + if self.type == 'quagga' or self.type == 'xenomips': + return "sudo xm console "+self.name + elif self.name in real_bridges or self.name in real_nodes: + return "echo Press enter to connect; read line; "+connection_table[self.name] + + +class Link: + def __init__ (self,name,node,interface,bridge,label=""): + self.name=name + self.node=node + self.interface=interface + self.bridge=bridge + self.label=label + + def is_temporary(self): + return [self.node,self.interface,self.bridge] in temporary_links + + def is_broken(self): + return ([self.node,self.interface,self.bridge] in broken_links) + + def graphviz_string(self): + if self.is_temporary(): + return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",color=blue,len=10,w=5,weight=5]" + if self.is_broken(): + return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",style=dashed]" + + ip="\\n.%s.%s" % (bridges.index(self.bridge)+1, domains.index(self.node)+1) + if domain_types[domains.index(self.node)] == 'xenomips': + int_name="fa"+str(self.interface)+"/0" + else: + int_name="eth"+str(self.interface) + if self.label != "": + int_name = self.label + return self.node+" -- "+self.bridge+" [taillabel=\""+int_name+ip+"\",fontsize=14,fontname=fixed]" + #----------------------------------------------------------------------- # DOMAINS @@ -620,6 +679,9 @@ nodes=domains +create_objects() + + if len(sys.argv) == 2: if sys.argv[1] == 'start-all': start_all()