xentaur

changeset 56:308b524d9a70

Многочисленные изменения
Перевод на ОО-модель


Various changes
Transit to OO-model
Real devices can be configured
Interfaces names
Cross bridges
author igor
date Sat Nov 10 19:58:39 2007 +0200 (2007-11-10)
parents ec48cf129028
children 548bd71dc5fb
files examples/example1.py xendomain.py xentaur.py
line diff
     1.1 --- a/examples/example1.py	Thu Oct 25 22:24:38 2007 +0300
     1.2 +++ b/examples/example1.py	Sat Nov 10 19:58:39 2007 +0200
     1.3 @@ -1,7 +1,7 @@
     1.4  import os
     1.5  domain=os.environ['xendomain']
     1.6  
     1.7 -network='netw'
     1.8 +network='example1'
     1.9  
    1.10  domains =       [ 'qua1',   'qua2',   'dyn3',     'qua4',   'qua5',   'dyn6',    'cisco1', 'linux1', 'windows1', 'mac1' ]
    1.11  domain_types =  [ 'quagga', 'quagga', 'xenomips', 'quagga', 'quagga', 'xenomips','cisco',  'linux',  'windows', 'macosx' ]
     2.1 --- a/xendomain.py	Thu Oct 25 22:24:38 2007 +0300
     2.2 +++ b/xendomain.py	Sat Nov 10 19:58:39 2007 +0200
     2.3 @@ -54,6 +54,13 @@
     2.4  #builder='linux'
     2.5  cpu_cap = 10
     2.6  
     2.7 +for br in bridges:
     2.8 +    if not br in vbridges_table.keys():
     2.9 +        vbridges_table[br]=[]
    2.10 +
    2.11 +for domain in domains:
    2.12 +    if not domain in connection_table.keys():
    2.13 +        connection_table[domain]='true'
    2.14  
    2.15  vbridges = vbridges_table[name]
    2.16  
     3.1 --- a/xentaur.py	Thu Oct 25 22:24:38 2007 +0300
     3.2 +++ b/xentaur.py	Sat Nov 10 19:58:39 2007 +0200
     3.3 @@ -8,8 +8,13 @@
     3.4  sys.path.append('/etc/xen')
     3.5  sys.path.append(xentaur_path)
     3.6  
     3.7 -network='snrs_ipsec_rsa_1'
     3.8 -domain='qua1'
     3.9 +#network='snrs_ipsec_rsa_1'
    3.10 +node_object={}
    3.11 +link_object={}
    3.12 +bridge_object={}
    3.13 +
    3.14 +network='icnd2'
    3.15 +domain='sw1'
    3.16  from xendomain import *
    3.17  
    3.18  bridges_turned_down=[]
    3.19 @@ -43,14 +48,15 @@
    3.20  
    3.21  def start_bridges():
    3.22      unbound_bridges=set(bridges)-set(real_bridges)
    3.23 -    create_unbound_bridges="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
    3.24 -    create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
    3.25 -    create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
    3.26 +    script=""
    3.27 +    script="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
    3.28 +    script+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
    3.29 +    script+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
    3.30  
    3.31      print """#!/bin/sh
    3.32  # create unbound bridges
    3.33 -%(create_unbound_bridges)s
    3.34 -""" % {'create_unbound_bridges' : create_unbound_bridges}
    3.35 +%s
    3.36 +""" % (script)
    3.37  
    3.38  def start_domain(domain):
    3.39      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"
    3.40 @@ -91,20 +97,74 @@
    3.41      stop_all(1)
    3.42      start_all()
    3.43  
    3.44 +####################################################
    3.45 +
    3.46 +def create_objects():
    3.47 +    create_node_objects()
    3.48 +    create_bridge_objects()
    3.49 +    create_link_objects()
    3.50 +
    3.51 +def create_node_objects():
    3.52 +    for dom in domains:
    3.53 +        node_object[dom]=Node(dom)
    3.54 +
    3.55 +def create_bridge_objects():
    3.56 +    for bridge in bridges:
    3.57 +        bridge_object[bridge]=Bridge(bridge)
    3.58 +
    3.59 +def create_link_objects():
    3.60 +
    3.61 +    for node, bridges_raw in vbridges_table.iteritems():
    3.62 +        interface=0
    3.63 +        j=0
    3.64 +        for this_bridge in bridges_raw:
    3.65 +            int_label=""
    3.66 +            if this_bridge.find(':') != -1:
    3.67 +                res = this_bridge.split(':')
    3.68 +                this_bridge= res[0]
    3.69 +                bridges_raw[j] = this_bridge
    3.70 +                int_label  = res[1]
    3.71 +            if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
    3.72 +                name="%s %s %s" % (node,interface,this_bridge)
    3.73 +                link_object[name]=Link(name,node,interface,this_bridge,int_label)
    3.74 +                interface+=1
    3.75 +        vbridges_table[node]=bridges_raw
    3.76 +
    3.77 +    for node, bridges_raw in bridge_bridge_table.iteritems():
    3.78 +        interface=0
    3.79 +        j=0
    3.80 +        for this_bridge in bridges_raw:
    3.81 +            int_label=""
    3.82 +            if this_bridge.find(':') != -1:
    3.83 +                res = this_bridge.split(':')
    3.84 +                this_bridge= res[0]
    3.85 +                bridges_raw[j] = this_bridge
    3.86 +                int_label  = res[1]
    3.87 +            if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
    3.88 +                name="%s %s %s" % (node,interface,this_bridge)
    3.89 +                link_object[name]=Link(name,node,interface,this_bridge,int_label)
    3.90 +                interface+=1
    3.91 +        bridge_bridge_table[node]=bridges_raw
    3.92 +
    3.93 +    for node,interface,bridge in temporary_links:
    3.94 +        name="%s %s %s" % (node,interface,bridge)
    3.95 +        link_object[name]=Link(name,node,interface,this_bridge)
    3.96 +
    3.97 +    for node,interface,bridge in broken_links:
    3.98 +        name="%s %s %s" % (node,interface,bridge)
    3.99 +        link_object[name]=Link(name,node,interface,this_bridge)
   3.100 +
   3.101 +
   3.102 +####################################################
   3.103 +
   3.104  def screen():
   3.105 -    N=1
   3.106 +    wait_seconds=5
   3.107      screens=[]
   3.108      for domain in domains:
   3.109 -        screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do sudo xm console "+domain+" ; echo Retrying in 5 seconds...; sleep 5; done'")
   3.110 -        N+=1
   3.111 +        screens.append("screen -t %s %s sh -c 'while true; do %s ; echo Retrying in %s secods...; sleep %s ; clear; done'" %
   3.112 +                                 (domain,domains.index(domain),node_object[domain].console_string(),wait_seconds,wait_seconds))
   3.113      screenlist="\n".join(screens)
   3.114  
   3.115 -#
   3.116 -# Previous terminal acccess commands:
   3.117 -#        ip="192.168.80."+str(200+N)
   3.118 -#        screens.append("screen -t "+domain+"   "+str(N)+" sh -c 'while true; do ssh root@"+ip+" ; done'")
   3.119 -#
   3.120 -
   3.121      hardstatus='hardstatus string "%{rk}Xentaur%{bk}@%H %{gk}%c %{yk}%d.%m %{wk}%?%-Lw%?%{bw}%n*%f%t%?(%u)%?%{wk}%?%+Lw%?"'
   3.122     
   3.123      f=open(screenrc, "w");
   3.124 @@ -119,25 +179,6 @@
   3.125      f.close()
   3.126      print "# GNU Screen config file is written to: %s" % screenrc
   3.127  
   3.128 -def graph_node(node):
   3.129 -    i=0
   3.130 -    domain_type={}
   3.131 -    for domain in domains:
   3.132 -        domain_type[domain]=domain_types[i]
   3.133 -        i+=1
   3.134 -    return node+" [label=\"  "+node+"\",shapefile=\"shapes/all/"+domain_type[node]+".png\",fontcolor=black,fontsize=16]"
   3.135 -
   3.136 -def graph_bridge(bridge):
   3.137 -    if bridge in hidden_bridges:
   3.138 -        return ""
   3.139 -    if bridge in real_bridges:
   3.140 -        return "%s [shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (bridge)
   3.141 -    elif bridge in bridges_turned_down:
   3.142 -        return "%s [shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (bridge)
   3.143 -    else:
   3.144 -        return "%s [shape=none,shapefile=\"shapes/all/switch.png\"]" % (bridge)
   3.145 -
   3.146 -
   3.147  def graph():
   3.148      nodelist=""
   3.149      bridgelist=""
   3.150 @@ -145,50 +186,12 @@
   3.151      physicallist=""
   3.152      networklist=""
   3.153  
   3.154 -    nodelist=";\n    ".join(map(graph_node,nodes))
   3.155 +    nodelist=";\n    ".join(map(lambda node: node_object[node].graphviz_string(),nodes))
   3.156      if nodelist: nodelist += ";"
   3.157 -
   3.158 -    bridgelist=";\n    ".join(map(graph_bridge,bridges))
   3.159 +    bridgelist=";\n    ".join(map(lambda bridge: bridge_object[bridge].graphviz_string(),bridges))
   3.160      if bridgelist: bridgelist += ";"
   3.161 -
   3.162 -    links=[]
   3.163 -    for host, bridges_raw in vbridges_table.iteritems():
   3.164 -        i=0
   3.165 -        for this_bridge in bridges_raw:
   3.166 -            if this_bridge in hidden_bridges or not this_bridge:
   3.167 -                continue 
   3.168 -            if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   3.169 -                links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(bridges_raw.index(this_bridge))+"/0\"]")
   3.170 -                i+=1
   3.171 -
   3.172 -    for link in temporary_links:
   3.173 -        links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",color=blue,len=10,w=5,weight=5]")
   3.174 -
   3.175 -    for link in broken_links:
   3.176 -        links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",style=dashed]")
   3.177 -
   3.178 -
   3.179 -    # bridge-bridge links
   3.180 -    for host, bridges_raw in bridge_bridge_table.iteritems():
   3.181 -        i=0
   3.182 -        for this_bridge in bridges_raw:
   3.183 -            if this_bridge in hidden_bridges or not this_bridge:
   3.184 -                continue 
   3.185 -            if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   3.186 -                links.append(host+" -- "+this_bridge)
   3.187 -                i+=1
   3.188 -
   3.189 -
   3.190 -
   3.191 -    linklist=";\n    ".join(links)
   3.192 -
   3.193 -    graph_dot = {
   3.194 -            'nodelist'      : nodelist,
   3.195 -            'bridgelist'    : bridgelist,
   3.196 -            'linklist'      : linklist,
   3.197 -            'physicallist'  : physicallist,
   3.198 -            'networklist'   : networklist,
   3.199 -          }
   3.200 +    linklist=";\n    ".join(map(lambda link: link_object[link].graphviz_string(),link_object.keys()))
   3.201 +    if linklist: linklist += ";"
   3.202  
   3.203      f = open(network+".dot", "w");
   3.204      f.write ("""
   3.205 @@ -196,33 +199,31 @@
   3.206      edge [len=1.25];
   3.207      splines=true;
   3.208  // nodes
   3.209 -
   3.210 -    node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
   3.211 -    %(nodelist)s
   3.212 +//    node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
   3.213 +    %s
   3.214  
   3.215  // bridges
   3.216 -
   3.217 -    node [shape=none,shapefile="shapes/all/switch.png"];
   3.218 -    %(bridgelist)s
   3.219 +//    node [shape=none,shapefile="shapes/all/switch.png"];
   3.220 +    %s
   3.221  
   3.222  // physical
   3.223 -
   3.224      node [shape=rectangle,color=blue];
   3.225 -    %(physicallist)s
   3.226 +    %s
   3.227  
   3.228  // networks (not bridges, not physical)
   3.229      node [shape=rectangle,color=green];
   3.230 -    %(networklist)s
   3.231 +    %s
   3.232  
   3.233  // links (between nodes and bridges)
   3.234 -    %(linklist)s
   3.235 +    %s
   3.236  
   3.237  };
   3.238 -""" % graph_dot)
   3.239 +""" % (nodelist, bridgelist, physicallist, networklist, linklist))
   3.240      f.close()
   3.241      run_command("neato -Tpng -o %s.png %s.dot "%(network,network))
   3.242      run_command("neato -Tjpg -o %s.jpg %s.dot "%(network,network))
   3.243      run_command("neato -Tsvg -o %s.svg %s.dot "%(network,network))
   3.244 +    run_command("neato -Tcmapx -o %s.cmapx -NURL=http://google.com %s.dot "%(network,network))
   3.245      print "# Network map is written to files: %s.{png,svg,jpg,dot}" % network
   3.246  
   3.247  def autoredraw():
   3.248 @@ -233,7 +234,6 @@
   3.249      ipshell = IPShellEmbed()
   3.250      ipshell()
   3.251  
   3.252 -
   3.253  def show_usage():
   3.254      print """Usage:
   3.255      xentaur <command> [<argument>]
   3.256 @@ -282,20 +282,79 @@
   3.257      def dump_start(self,filter=""):
   3.258          dump_start(self.name,filter)
   3.259  
   3.260 +    def is_hidden(self):
   3.261 +        return self.name in hidden_bridges
   3.262 +    def is_real(self):
   3.263 +        return self.name in real_bridges
   3.264 +    def is_turned_down(self):
   3.265 +        return self.name in bridges_turned_down
   3.266 +    def is_cross(self):
   3.267 +        return self.name in cross_bridges
   3.268  
   3.269 -class Domain:
   3.270 +    def graphviz_string(self):
   3.271 +        if self.is_hidden():
   3.272 +            return ""
   3.273 +        elif self.is_cross():
   3.274 +            return "%s [shape=circle,height=0.03,color=black,fillcolor=black,style=filled,label=\"\"]" % (self.name)
   3.275 +        elif self.is_real():
   3.276 +            return "%s [color=white,shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (self.name)
   3.277 +        elif self.is_turned_down():
   3.278 +            return "%s [color=white,shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (self.name)
   3.279 +        else:
   3.280 +            return "%s [color=white,shape=none,shapefile=\"shapes/all/switch.png\"]" % (self.name)
   3.281 +
   3.282 +
   3.283 +class Node:
   3.284      def __init__ (self,name):
   3.285          self.name=name
   3.286 +        self.type=domain_types[domains.index(name)]
   3.287      def start(self):
   3.288          return ""
   3.289      def stop(self):
   3.290          return ""
   3.291      def start_commandline(self):
   3.292          return ""
   3.293 -    def graphviz(self):
   3.294 -        return ""
   3.295      def get_domain_id(self):
   3.296          return get_domain_id(self.name)
   3.297 +    def graphviz_string(self):
   3.298 +        return self.name+" [color=white,shape=plaintext,label=\"  "+self.name+"\",shapefile=\"shapes/all/"+\
   3.299 +        domain_types[domains.index(self.name)]+".png\",fontcolor=black,fontsize=16,target=\"http://google.com\"]"
   3.300 +    def console_string(self):
   3.301 +        if self.type == 'quagga' or self.type == 'xenomips':
   3.302 +            return "sudo xm console "+self.name
   3.303 +        elif self.name in real_bridges or self.name in real_nodes:
   3.304 +            return "echo Press enter to connect; read line; "+connection_table[self.name]
   3.305 +
   3.306 +
   3.307 +class Link:
   3.308 +    def __init__ (self,name,node,interface,bridge,label=""):
   3.309 +        self.name=name
   3.310 +        self.node=node
   3.311 +        self.interface=interface
   3.312 +        self.bridge=bridge
   3.313 +        self.label=label
   3.314 +
   3.315 +    def is_temporary(self):
   3.316 +        return [self.node,self.interface,self.bridge] in temporary_links
   3.317 +
   3.318 +    def is_broken(self):
   3.319 +        return ([self.node,self.interface,self.bridge] in broken_links)
   3.320 +
   3.321 +    def graphviz_string(self):
   3.322 +        if self.is_temporary():
   3.323 +            return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",color=blue,len=10,w=5,weight=5]"
   3.324 +        if self.is_broken():
   3.325 +            return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",style=dashed]"
   3.326 +
   3.327 +        ip="\\n.%s.%s" % (bridges.index(self.bridge)+1, domains.index(self.node)+1) 
   3.328 +        if domain_types[domains.index(self.node)] == 'xenomips':
   3.329 +            int_name="fa"+str(self.interface)+"/0"
   3.330 +        else:
   3.331 +            int_name="eth"+str(self.interface)
   3.332 +        if self.label != "":
   3.333 +            int_name = self.label
   3.334 +        return self.node+" -- "+self.bridge+" [taillabel=\""+int_name+ip+"\",fontsize=14,fontname=fixed]"
   3.335 +
   3.336  
   3.337  #-----------------------------------------------------------------------
   3.338  # DOMAINS
   3.339 @@ -620,6 +679,9 @@
   3.340  
   3.341  nodes=domains
   3.342  
   3.343 +create_objects()
   3.344 +
   3.345 +
   3.346  if len(sys.argv) == 2:
   3.347      if sys.argv[1] == 'start-all':
   3.348          start_all()