xentaur

diff xentaur.py @ 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 e7b9761c03e8
line diff
     1.1 --- a/xentaur.py	Thu Oct 25 22:24:38 2007 +0300
     1.2 +++ b/xentaur.py	Sat Nov 10 19:58:39 2007 +0200
     1.3 @@ -8,8 +8,13 @@
     1.4  sys.path.append('/etc/xen')
     1.5  sys.path.append(xentaur_path)
     1.6  
     1.7 -network='snrs_ipsec_rsa_1'
     1.8 -domain='qua1'
     1.9 +#network='snrs_ipsec_rsa_1'
    1.10 +node_object={}
    1.11 +link_object={}
    1.12 +bridge_object={}
    1.13 +
    1.14 +network='icnd2'
    1.15 +domain='sw1'
    1.16  from xendomain import *
    1.17  
    1.18  bridges_turned_down=[]
    1.19 @@ -43,14 +48,15 @@
    1.20  
    1.21  def start_bridges():
    1.22      unbound_bridges=set(bridges)-set(real_bridges)
    1.23 -    create_unbound_bridges="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
    1.24 -    create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
    1.25 -    create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
    1.26 +    script=""
    1.27 +    script="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
    1.28 +    script+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
    1.29 +    script+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
    1.30  
    1.31      print """#!/bin/sh
    1.32  # create unbound bridges
    1.33 -%(create_unbound_bridges)s
    1.34 -""" % {'create_unbound_bridges' : create_unbound_bridges}
    1.35 +%s
    1.36 +""" % (script)
    1.37  
    1.38  def start_domain(domain):
    1.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"
    1.40 @@ -91,20 +97,74 @@
    1.41      stop_all(1)
    1.42      start_all()
    1.43  
    1.44 +####################################################
    1.45 +
    1.46 +def create_objects():
    1.47 +    create_node_objects()
    1.48 +    create_bridge_objects()
    1.49 +    create_link_objects()
    1.50 +
    1.51 +def create_node_objects():
    1.52 +    for dom in domains:
    1.53 +        node_object[dom]=Node(dom)
    1.54 +
    1.55 +def create_bridge_objects():
    1.56 +    for bridge in bridges:
    1.57 +        bridge_object[bridge]=Bridge(bridge)
    1.58 +
    1.59 +def create_link_objects():
    1.60 +
    1.61 +    for node, bridges_raw in vbridges_table.iteritems():
    1.62 +        interface=0
    1.63 +        j=0
    1.64 +        for this_bridge in bridges_raw:
    1.65 +            int_label=""
    1.66 +            if this_bridge.find(':') != -1:
    1.67 +                res = this_bridge.split(':')
    1.68 +                this_bridge= res[0]
    1.69 +                bridges_raw[j] = this_bridge
    1.70 +                int_label  = res[1]
    1.71 +            if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
    1.72 +                name="%s %s %s" % (node,interface,this_bridge)
    1.73 +                link_object[name]=Link(name,node,interface,this_bridge,int_label)
    1.74 +                interface+=1
    1.75 +        vbridges_table[node]=bridges_raw
    1.76 +
    1.77 +    for node, bridges_raw in bridge_bridge_table.iteritems():
    1.78 +        interface=0
    1.79 +        j=0
    1.80 +        for this_bridge in bridges_raw:
    1.81 +            int_label=""
    1.82 +            if this_bridge.find(':') != -1:
    1.83 +                res = this_bridge.split(':')
    1.84 +                this_bridge= res[0]
    1.85 +                bridges_raw[j] = this_bridge
    1.86 +                int_label  = res[1]
    1.87 +            if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
    1.88 +                name="%s %s %s" % (node,interface,this_bridge)
    1.89 +                link_object[name]=Link(name,node,interface,this_bridge,int_label)
    1.90 +                interface+=1
    1.91 +        bridge_bridge_table[node]=bridges_raw
    1.92 +
    1.93 +    for node,interface,bridge in temporary_links:
    1.94 +        name="%s %s %s" % (node,interface,bridge)
    1.95 +        link_object[name]=Link(name,node,interface,this_bridge)
    1.96 +
    1.97 +    for node,interface,bridge in broken_links:
    1.98 +        name="%s %s %s" % (node,interface,bridge)
    1.99 +        link_object[name]=Link(name,node,interface,this_bridge)
   1.100 +
   1.101 +
   1.102 +####################################################
   1.103 +
   1.104  def screen():
   1.105 -    N=1
   1.106 +    wait_seconds=5
   1.107      screens=[]
   1.108      for domain in domains:
   1.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'")
   1.110 -        N+=1
   1.111 +        screens.append("screen -t %s %s sh -c 'while true; do %s ; echo Retrying in %s secods...; sleep %s ; clear; done'" %
   1.112 +                                 (domain,domains.index(domain),node_object[domain].console_string(),wait_seconds,wait_seconds))
   1.113      screenlist="\n".join(screens)
   1.114  
   1.115 -#
   1.116 -# Previous terminal acccess commands:
   1.117 -#        ip="192.168.80."+str(200+N)
   1.118 -#        screens.append("screen -t "+domain+"   "+str(N)+" sh -c 'while true; do ssh root@"+ip+" ; done'")
   1.119 -#
   1.120 -
   1.121      hardstatus='hardstatus string "%{rk}Xentaur%{bk}@%H %{gk}%c %{yk}%d.%m %{wk}%?%-Lw%?%{bw}%n*%f%t%?(%u)%?%{wk}%?%+Lw%?"'
   1.122     
   1.123      f=open(screenrc, "w");
   1.124 @@ -119,25 +179,6 @@
   1.125      f.close()
   1.126      print "# GNU Screen config file is written to: %s" % screenrc
   1.127  
   1.128 -def graph_node(node):
   1.129 -    i=0
   1.130 -    domain_type={}
   1.131 -    for domain in domains:
   1.132 -        domain_type[domain]=domain_types[i]
   1.133 -        i+=1
   1.134 -    return node+" [label=\"  "+node+"\",shapefile=\"shapes/all/"+domain_type[node]+".png\",fontcolor=black,fontsize=16]"
   1.135 -
   1.136 -def graph_bridge(bridge):
   1.137 -    if bridge in hidden_bridges:
   1.138 -        return ""
   1.139 -    if bridge in real_bridges:
   1.140 -        return "%s [shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (bridge)
   1.141 -    elif bridge in bridges_turned_down:
   1.142 -        return "%s [shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (bridge)
   1.143 -    else:
   1.144 -        return "%s [shape=none,shapefile=\"shapes/all/switch.png\"]" % (bridge)
   1.145 -
   1.146 -
   1.147  def graph():
   1.148      nodelist=""
   1.149      bridgelist=""
   1.150 @@ -145,50 +186,12 @@
   1.151      physicallist=""
   1.152      networklist=""
   1.153  
   1.154 -    nodelist=";\n    ".join(map(graph_node,nodes))
   1.155 +    nodelist=";\n    ".join(map(lambda node: node_object[node].graphviz_string(),nodes))
   1.156      if nodelist: nodelist += ";"
   1.157 -
   1.158 -    bridgelist=";\n    ".join(map(graph_bridge,bridges))
   1.159 +    bridgelist=";\n    ".join(map(lambda bridge: bridge_object[bridge].graphviz_string(),bridges))
   1.160      if bridgelist: bridgelist += ";"
   1.161 -
   1.162 -    links=[]
   1.163 -    for host, bridges_raw in vbridges_table.iteritems():
   1.164 -        i=0
   1.165 -        for this_bridge in bridges_raw:
   1.166 -            if this_bridge in hidden_bridges or not this_bridge:
   1.167 -                continue 
   1.168 -            if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   1.169 -                links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(bridges_raw.index(this_bridge))+"/0\"]")
   1.170 -                i+=1
   1.171 -
   1.172 -    for link in temporary_links:
   1.173 -        links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",color=blue,len=10,w=5,weight=5]")
   1.174 -
   1.175 -    for link in broken_links:
   1.176 -        links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",style=dashed]")
   1.177 -
   1.178 -
   1.179 -    # bridge-bridge links
   1.180 -    for host, bridges_raw in bridge_bridge_table.iteritems():
   1.181 -        i=0
   1.182 -        for this_bridge in bridges_raw:
   1.183 -            if this_bridge in hidden_bridges or not this_bridge:
   1.184 -                continue 
   1.185 -            if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   1.186 -                links.append(host+" -- "+this_bridge)
   1.187 -                i+=1
   1.188 -
   1.189 -
   1.190 -
   1.191 -    linklist=";\n    ".join(links)
   1.192 -
   1.193 -    graph_dot = {
   1.194 -            'nodelist'      : nodelist,
   1.195 -            'bridgelist'    : bridgelist,
   1.196 -            'linklist'      : linklist,
   1.197 -            'physicallist'  : physicallist,
   1.198 -            'networklist'   : networklist,
   1.199 -          }
   1.200 +    linklist=";\n    ".join(map(lambda link: link_object[link].graphviz_string(),link_object.keys()))
   1.201 +    if linklist: linklist += ";"
   1.202  
   1.203      f = open(network+".dot", "w");
   1.204      f.write ("""
   1.205 @@ -196,33 +199,31 @@
   1.206      edge [len=1.25];
   1.207      splines=true;
   1.208  // nodes
   1.209 -
   1.210 -    node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
   1.211 -    %(nodelist)s
   1.212 +//    node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
   1.213 +    %s
   1.214  
   1.215  // bridges
   1.216 -
   1.217 -    node [shape=none,shapefile="shapes/all/switch.png"];
   1.218 -    %(bridgelist)s
   1.219 +//    node [shape=none,shapefile="shapes/all/switch.png"];
   1.220 +    %s
   1.221  
   1.222  // physical
   1.223 -
   1.224      node [shape=rectangle,color=blue];
   1.225 -    %(physicallist)s
   1.226 +    %s
   1.227  
   1.228  // networks (not bridges, not physical)
   1.229      node [shape=rectangle,color=green];
   1.230 -    %(networklist)s
   1.231 +    %s
   1.232  
   1.233  // links (between nodes and bridges)
   1.234 -    %(linklist)s
   1.235 +    %s
   1.236  
   1.237  };
   1.238 -""" % graph_dot)
   1.239 +""" % (nodelist, bridgelist, physicallist, networklist, linklist))
   1.240      f.close()
   1.241      run_command("neato -Tpng -o %s.png %s.dot "%(network,network))
   1.242      run_command("neato -Tjpg -o %s.jpg %s.dot "%(network,network))
   1.243      run_command("neato -Tsvg -o %s.svg %s.dot "%(network,network))
   1.244 +    run_command("neato -Tcmapx -o %s.cmapx -NURL=http://google.com %s.dot "%(network,network))
   1.245      print "# Network map is written to files: %s.{png,svg,jpg,dot}" % network
   1.246  
   1.247  def autoredraw():
   1.248 @@ -233,7 +234,6 @@
   1.249      ipshell = IPShellEmbed()
   1.250      ipshell()
   1.251  
   1.252 -
   1.253  def show_usage():
   1.254      print """Usage:
   1.255      xentaur <command> [<argument>]
   1.256 @@ -282,20 +282,79 @@
   1.257      def dump_start(self,filter=""):
   1.258          dump_start(self.name,filter)
   1.259  
   1.260 +    def is_hidden(self):
   1.261 +        return self.name in hidden_bridges
   1.262 +    def is_real(self):
   1.263 +        return self.name in real_bridges
   1.264 +    def is_turned_down(self):
   1.265 +        return self.name in bridges_turned_down
   1.266 +    def is_cross(self):
   1.267 +        return self.name in cross_bridges
   1.268  
   1.269 -class Domain:
   1.270 +    def graphviz_string(self):
   1.271 +        if self.is_hidden():
   1.272 +            return ""
   1.273 +        elif self.is_cross():
   1.274 +            return "%s [shape=circle,height=0.03,color=black,fillcolor=black,style=filled,label=\"\"]" % (self.name)
   1.275 +        elif self.is_real():
   1.276 +            return "%s [color=white,shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (self.name)
   1.277 +        elif self.is_turned_down():
   1.278 +            return "%s [color=white,shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (self.name)
   1.279 +        else:
   1.280 +            return "%s [color=white,shape=none,shapefile=\"shapes/all/switch.png\"]" % (self.name)
   1.281 +
   1.282 +
   1.283 +class Node:
   1.284      def __init__ (self,name):
   1.285          self.name=name
   1.286 +        self.type=domain_types[domains.index(name)]
   1.287      def start(self):
   1.288          return ""
   1.289      def stop(self):
   1.290          return ""
   1.291      def start_commandline(self):
   1.292          return ""
   1.293 -    def graphviz(self):
   1.294 -        return ""
   1.295      def get_domain_id(self):
   1.296          return get_domain_id(self.name)
   1.297 +    def graphviz_string(self):
   1.298 +        return self.name+" [color=white,shape=plaintext,label=\"  "+self.name+"\",shapefile=\"shapes/all/"+\
   1.299 +        domain_types[domains.index(self.name)]+".png\",fontcolor=black,fontsize=16,target=\"http://google.com\"]"
   1.300 +    def console_string(self):
   1.301 +        if self.type == 'quagga' or self.type == 'xenomips':
   1.302 +            return "sudo xm console "+self.name
   1.303 +        elif self.name in real_bridges or self.name in real_nodes:
   1.304 +            return "echo Press enter to connect; read line; "+connection_table[self.name]
   1.305 +
   1.306 +
   1.307 +class Link:
   1.308 +    def __init__ (self,name,node,interface,bridge,label=""):
   1.309 +        self.name=name
   1.310 +        self.node=node
   1.311 +        self.interface=interface
   1.312 +        self.bridge=bridge
   1.313 +        self.label=label
   1.314 +
   1.315 +    def is_temporary(self):
   1.316 +        return [self.node,self.interface,self.bridge] in temporary_links
   1.317 +
   1.318 +    def is_broken(self):
   1.319 +        return ([self.node,self.interface,self.bridge] in broken_links)
   1.320 +
   1.321 +    def graphviz_string(self):
   1.322 +        if self.is_temporary():
   1.323 +            return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",color=blue,len=10,w=5,weight=5]"
   1.324 +        if self.is_broken():
   1.325 +            return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",style=dashed]"
   1.326 +
   1.327 +        ip="\\n.%s.%s" % (bridges.index(self.bridge)+1, domains.index(self.node)+1) 
   1.328 +        if domain_types[domains.index(self.node)] == 'xenomips':
   1.329 +            int_name="fa"+str(self.interface)+"/0"
   1.330 +        else:
   1.331 +            int_name="eth"+str(self.interface)
   1.332 +        if self.label != "":
   1.333 +            int_name = self.label
   1.334 +        return self.node+" -- "+self.bridge+" [taillabel=\""+int_name+ip+"\",fontsize=14,fontname=fixed]"
   1.335 +
   1.336  
   1.337  #-----------------------------------------------------------------------
   1.338  # DOMAINS
   1.339 @@ -620,6 +679,9 @@
   1.340  
   1.341  nodes=domains
   1.342  
   1.343 +create_objects()
   1.344 +
   1.345 +
   1.346  if len(sys.argv) == 2:
   1.347      if sys.argv[1] == 'start-all':
   1.348          start_all()