xentaur
view xentaur.py @ 47:b67ffcdd0043
xenomips default parameters
| author | igor | 
|---|---|
| date | Wed Oct 24 16:08:42 2007 +0300 (2007-10-24) | 
| parents | 8c00f233a1d4 | 
| children | 65e80fabc89c | 
 line source
     1 #!/usr/bin/python
     4 import sys,os,time
     6 xentaur_path=os.environ['HOME']+"/xentaur"
     8 sys.path.append('/etc/xen')
     9 sys.path.append(xentaur_path)
    11 network='snrs_ipsec_rsa_1'
    12 domain='qua1'
    13 from xendomain import *
    15 bridges_turned_down=[]
    17 from IPython.Shell import IPShellEmbed
    20 screenrc=os.environ['HOME']+"/.screenrc_xentaur"
    22 def run(program, *args):
    23     pid = os.fork()
    24     if not pid:
    25         os.execvp(program, (program,) +  args)
    26     return os.wait()[0]
    28 def run_command(line):
    29     #cmds=line.split()
    30     #run(cmds[0],*cmds[1:])
    31     run("/bin/sh", "-c", line)
    33 def run_command_return_stdout(line):
    34     p = os.popen(line)
    35     output = p.read()
    36     p.close()
    37     return output
    39 def create_bridges_script():
    40     unbound_bridges=set(bridges)-set(real_bridges)
    41     create_unbound_bridges="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
    42     create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
    43     create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
    45     print """#!/bin/sh
    46 # create unbound bridges
    47 %(create_unbound_bridges)s
    48 """ % {'create_unbound_bridges' : create_unbound_bridges}
    51 def create_domains_script():
    52     for domain in domains:
    53         if not domain in real_nodes:
    54             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"
    56 def destroy_domains_script():
    57     for domain in domains:
    58         if not domain in real_nodes:
    59             print "sudo xm shutdown "+domain
    61 def create_screens_script():
    62     N=1
    63     screens=[]
    64     for domain in domains:
    65         screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do sudo xm console "+domain+" ; echo Retrying in 5 seconds...; sleep 5; done'")
    66         N+=1
    67     screenlist="\n".join(screens)
    69 #
    70 # Previous terminal acccess commands:
    71 #        ip="192.168.80."+str(200+N)
    72 #        screens.append("screen -t "+domain+"   "+str(N)+" sh -c 'while true; do ssh root@"+ip+" ; done'")
    73 #
    75 #hardstatus string "\%{gk}\%c \%{yk}\%M\%d \%{wk}\%?\%-Lw\%?\%{bw}\%n*\%f\%t\%?(\%u)\%?\%{wk}\%?\%+Lw\%?"
    77     f=open(screenrc, "w");
    78     f.write("""
    79 hardstatus on
    80 hardstatus alwayslastline
    82 screen -t console 0 bash
    83 %s
    84 """ % (screenlist))
    85     f.close()
    87 def graph_node(node):
    88     i=0
    89     domain_type={}
    90     for domain in domains:
    91         domain_type[domain]=domain_types[i]
    92         i+=1
    93     return node+" [label=\"  "+node+"\",shapefile=\"shapes/all/"+domain_type[node]+".png\",fontcolor=black,fontsize=16]"
    95 def graph_bridge(bridge):
    96     if bridge in hidden_bridges:
    97         return ""
    98     if bridge in real_bridges:
    99         return "%s [shape=none,shapefile=\"shapes/all/real_switch.png\"]" % (bridge)
   100     elif bridge in bridges_turned_down:
   101         return "%s [shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (bridge)
   102     else:
   103         return "%s [shape=none,shapefile=\"shapes/all/switch.png\"]" % (bridge)
   106 def graph():
   107     nodelist=""
   108     bridgelist=""
   109     linklist=""
   110     physicallist=""
   111     networklist=""
   113     nodelist=";\n    ".join(map(graph_node,nodes))
   114     if nodelist: nodelist += ";"
   116     bridgelist=";\n    ".join(map(graph_bridge,bridges))
   117     if bridgelist: bridgelist += ";"
   119     links=[]
   120     for host, bridges_raw in vbridges_table.iteritems():
   121         i=0
   122         for this_bridge in bridges_raw:
   123             if this_bridge in hidden_bridges or not this_bridge:
   124                 continue 
   125             if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   126                 links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(bridges_raw.index(this_bridge))+"/0\"]")
   127                 i+=1
   129     for link in temporary_links:
   130         links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",color=blue,len=10,w=5,weight=5]")
   132     for link in broken_links:
   133         links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",style=dashed]")
   136     # bridge-bridge links
   137     for host, bridges_raw in bridge_bridge_table.iteritems():
   138         i=0
   139         for this_bridge in bridges_raw:
   140             if this_bridge in hidden_bridges or not this_bridge:
   141                 continue 
   142             if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   143                 links.append(host+" -- "+this_bridge)
   144                 i+=1
   148     linklist=";\n    ".join(links)
   150     graph_dot = {
   151             'nodelist'      : nodelist,
   152             'bridgelist'    : bridgelist,
   153             'linklist'      : linklist,
   154             'physicallist'  : physicallist,
   155             'networklist'   : networklist,
   156           }
   158     f = open(network+".dot", "w");
   159     f.write ("""
   160 graph G {
   161     edge [len=1.25];
   162     splines=true;
   163 // nodes
   165     node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
   166     %(nodelist)s
   168 // bridges
   170     node [shape=none,shapefile="shapes/all/switch.png"];
   171     %(bridgelist)s
   173 // physical
   175     node [shape=rectangle,color=blue];
   176     %(physicallist)s
   178 // networks (not bridges, not physical)
   179     node [shape=rectangle,color=green];
   180     %(networklist)s
   182 // links (between nodes and bridges)
   183     %(linklist)s
   185 };
   186 """ % graph_dot)
   187     f.close()
   188     run_command("neato -Tpng -o %s.png %s.dot "%(network,network))
   189     run_command("neato -Tjpg -o %s.jpg %s.dot "%(network,network))
   190     run_command("neato -Tsvg -o %s.svg %s.dot "%(network,network))
   192 def autoredraw():
   193     graph()
   195 def start_all():
   196         create_bridges_script()
   197         create_screens_script()
   198         create_domains_script()
   199         graph()
   200         print """
   201         cat <<NOTE_FOR_USER
   202 # To view virtual network map, run:
   203     gqview xenomips.png
   204 # To attach to VM consoles, run:
   205     screen -c screenrc
   206 NOTE_FOR_USER
   207 """
   209 def shell():
   210     autoredraw()
   211     ipshell = IPShellEmbed()
   212     ipshell()
   214 def stop_all():
   215         destroy_domains_script()
   217 def show_usage():
   218     print """Usage:
   219     xentaur {start|stop|start-bridges|start-domains|stop-domains|screen|graph}
   220 """
   222 def save():
   223     print "network =",          xen_config_name
   224     print "domains =",          domains
   225     print "domain_types =",     domain_types
   226     print "bridges =",          bridges
   227     print "vbridges_table =",   vbridges_table
   228     print "hidden_bridges =",   hidden_bridges
   229     print "broken_links =",     broken_links
   230     print "temporary_links =",  temporary_links
   231     print "bridges_turned_down =", bridges_turned_down
   233 #-----------------------------------------------------------------------
   234 # CLASSES
   236 class Bridge:
   237     def __init__ (self,name):
   238         self.name=name
   239     def up(self):
   240         bridge_up(self.name)
   241     def down(self):
   242         bridge_down(self.name)
   243     def show(self):
   244         show_bridge(self.name)
   245     def dump_start(self,filter=""):
   246         dump_start(self.name,filter)
   249 class Domain:
   250     def __init__ (self,name):
   251         self.name=name
   252     def start(self):
   253         return ""
   254     def stop(self):
   255         return ""
   256     def start_commandline(self):
   257         return ""
   258     def graphviz(self):
   259         return ""
   260     def get_domain_id(self):
   261         return get_domain_id(self.name)
   263 #-----------------------------------------------------------------------
   264 # DOMAINS
   266 def get_domain_id(domain):
   267     return run_command_return_stdout("sudo xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain).rstrip("\n")
   270 #-----------------------------------------------------------------------
   271 # BRIDGES and IFACES
   273 def bridge_down(bridge):
   274     """
   275     Turn the bridge <bridge> down
   276     """
   277     if bridge in real_bridges:
   278         print "Bridge %s is a real bridge" % (bridge)
   279         return -1
   280     if bridge in bridges_turned_down:
   281         print "Bridge %s is turned down already" % (bridge)
   282     else:
   283         bridges_turned_down.append(bridge)
   284         run_command("sudo ip link set %s down" % bridge)
   285         autoredraw()
   287 def bridge_up(bridge):
   288     """
   289     Turn the bridge <bridge> up
   290     """
   291     if bridge in real_bridges:
   292         print "Bridge %s is a real bridge" % (bridge)
   293         return -1
   294     if not (bridge in bridges_turned_down):
   295         print "Bridge %s is turned up already" % (bridge)
   296     else:
   297         bridges_turned_down.remove(bridge)
   298         run_command("sudo ip link set %s up" % bridge)
   299         autoredraw()
   301 def show_bridge(bridge):
   302     """
   303     Show the state of the bridge <bridge>
   304     """
   305     if bridge in real_bridges:
   306         print "Bridge %s is a real bridge" % (bridge)
   307         return -1
   308     run_command("sudo ip link show %s" % bridge)
   311 def int_disconnect(domain, int_number):
   312     """
   313     Disconnect the interface with the number <int_number>
   314     of the domain <domain> from the bridge to which
   315     it is connected
   316     """
   317     dom_id=get_domain_id(domain)
   318     bridge=vbridges_table[domain][int_number]
   319     if not bridge:
   320         print "Interface %s of the %s domain is not connected" % (int_number, domain)
   321         return 1
   322     run_command("sudo brctl delif %s vif%s.%s" % (bridge, dom_id, int_number))
   323     vbridges_table[domain][int_number]=''
   324     if [ domain, int_number, bridge ] in temporary_links:
   325         temporary_links.remove([ domain, int_number, bridge ])
   326     else:
   327         broken_links.append([ domain, int_number, bridge ])
   328     autoredraw()
   330 def int_connect(domain, int_number, bridge):
   331     """
   332     Connect the interface with the number <int_number>
   333     of the domain <domain> to the bridge <bridge>
   334     """
   335     if bridge in real_bridges:
   336         print "Bridge %s is a real bridge" % (bridge)
   337         return -1
   339     dom_id=get_domain_id(domain)
   340     if vbridges_table[domain][int_number]:
   341         print "Interface %s of the %s domain is connected already to the %s bridge" % (int_number, domain, vbridges_table[domain][int_number])
   342         return 1
   343     run_command("sudo brctl addif %s vif%s.%s" % (bridge, dom_id, int_number))
   344     vbridges_table[domain][int_number]=bridge
   345     if [ domain, int_number, bridge ] in broken_links:
   346         broken_links.remove([ domain, int_number, bridge ])
   347     else:
   348         temporary_links.append([ domain, int_number, bridge ])
   349     autoredraw()
   351 def int_reconnect(domain, int_number, bridge):
   352     """
   353     Reconnect the interface with the number <int_number>
   354     of the domain <domain> from the bridge to which
   355     it is connected to the bridge <bridge>
   356     """
   357     if bridge in real_bridges:
   358         print "Bridge %s is a real bridge" % (bridge)
   359         return -1
   361     int_disconnect(domain, int_number)
   362     int_connect(domain, int_number, bridge)
   364 def show_int(domain, int_number):
   365     """
   366     Show information about the interface <int_nuber>
   367     of the domain <domain>
   368     """
   369     return vbridges_table[domain][int_number]
   372 def dump_start(bridge, filter=""):
   373     if bridge in real_bridges:
   374         print "Bridge %s is a real bridge" % (bridge)
   375         return -1
   376     try:
   377         print "Writing dump... (press Ctrl-C to stop)"
   378         run_command("sudo tcpdump -w xentaur.dump -i %s %s > /dev/null 2>&1 " % (bridge,filter))
   379     except:
   380         print "Done.\n Dump is written to xentaur.dump"
   381     return 0
   383 def dump_stop():
   384     return 0
   387 #-----------------------------------------------------------------------
   388 # CONFIGURATION TEMPLATES
   391 def configure_ip_addresses(doms=domains):
   393     cisco_set_ip_on_int="""
   394 \n\n\n
   395 int fa%s/0
   396 no ip address
   397 ip address %s 255.255.255.0
   398 no shutdown
   399 exit
   400 """
   402     quagga_set_ip_on_int="""
   403 int eth%s
   404 no ip address
   405 ip address %s/24
   406 no shutdown
   407 exit
   408 """
   410     for dom in doms:
   411         i=domains.index(dom)+1
   412         if domain_types[domains.index(dom)] == 'quagga':
   413             command = quagga_set_ip_on_int
   414             write_to(i,"\nconf t\n")
   415             j=0
   416             for br in  vbridges_table[dom]:
   417                 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
   418                 j+=1
   419             write_to(i,"\nend\n")
   420         else:
   421             command = cisco_set_ip_on_int
   422             write_to(i,"\nena\nconf t\n")
   423             j=0
   424             for br in  vbridges_table[dom]:
   425                 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
   426                 j+=1
   427             write_to(i,"\nend\n")
   428     return 0
   430 def configure_no_ip_addresses(doms=domains):
   432     cisco_set_ip_on_int="""
   433 \n\n\n
   434 int fa%s/0
   435 no ip address %s 255.255.255.0
   436 exit
   437 """
   439     quagga_set_ip_on_int="""
   440 int eth%s
   441 no ip address %s/24
   442 exit
   443 """
   445     for dom in doms:
   446         i=domains.index(dom)+1
   447         if domain_types[domains.index(dom)] == 'quagga':
   448             command = quagga_set_ip_on_int
   449             write_to(i,"\nconf t\n")
   450             j=0
   451             for br in  vbridges_table[dom]:
   452                 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
   453                 j+=1
   454             write_to(i,"\nend\n")
   455         else:
   456             command = cisco_set_ip_on_int
   457             write_to(i,"\nena\nconf t\n")
   458             j=0
   459             for br in  vbridges_table[dom]:
   460                 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
   461                 j+=1
   462             write_to(i,"\nend\n")
   463     return 0
   465 def configure_ospf(doms=domains):
   466     for dom in doms:
   467         if domain_types[domains.index(dom)] == 'quagga':
   468             write_to(dom,"\n\nconf t\nrouter ospf\nnetwork 192.168.0.0/16 area 0\nend\n")
   469         else:
   470             write_to(dom,"\n\nena\nconf t\nrouter ospf 1\nnetwork 192.168.0.0 0.0.255.255 area 0\nend\n")
   471     return 0
   473 def configure_save(doms=domains):
   474     write_to(doms,"\nwr\n")
   476 #-----------------------------------------------------------------------
   479 def add_domain(name,type):
   480     domains.append(name)
   481     domain_types.append(type)
   483 def brake_link(domain,bridge):
   484     broken_links.append([domain,bridge])
   486 wt_timeout=0.5
   487 def write_to(screen,string,return_to_screen=""):
   488     """
   489     write_to(screen,string):
   491         Type *string* to the specified screen(s).
   492         Screen may be specified with the number *screen*,
   493         with array of numbers, 
   494         with array of names.
   496     """
   497     screen_numbers=[]           # number of the screens to write to
   498     if type(screen) == list:
   499         screen_numbers=map(lambda x: domains.index(x)+1, screen)
   500     elif type(screen) == int:
   501         screen_numbers=[screen]
   502     else:
   503         screen_numbers=[domains.index(screen)+1]
   505     for screen_number in screen_numbers:
   506         run_command("screen -X select "+str(screen_number))
   507         time.sleep(wt_timeout)
   508         for line in string.splitlines():
   509             f=open('/tmp/xentaurbuf', 'w')
   510             f.write(line+"\n")
   511             f.close()
   512             run_command("screen -X readreg p /tmp/xentaurbuf")
   513             time.sleep(wt_timeout)
   514             run_command("nohup screen -X paste p >& /dev/null")
   515             time.sleep(wt_timeout)
   517         if return_to_screen != "":
   518             run_command("screen -X select %s" % (return_to_screen))
   519             time.sleep(wt_timeout)
   521 #-----------------------------------------------------------------------
   523 cisco_fa01_up="""
   524 ena
   525 conf t
   526 int fa0/0
   527 no shutdown
   528 exit
   529 int fa1/0
   530 no shutdown
   531 exit
   532 exit
   533 exit
   534 """
   536 cisco_set_ip_on_int="""
   537 interface fa%s/0
   538 no ip address
   539 ip address %s 255.255.255.0
   540 exit
   541 """
   545 nodes=domains
   547 if len(sys.argv) > 1:
   548     if sys.argv[1] == 'start':
   549         start_all()
   550     if sys.argv[1] == 'stop':
   551         stop_all()
   552     if sys.argv[1] == 'start-bridges':
   553         create_bridges_script()
   554     if sys.argv[1] == 'start-domains':
   555         create_domains_script()
   556     if sys.argv[1] == 'stop-domains':
   557         destroy_domains_script()
   558     elif sys.argv[1] == 'screen':
   559         create_screens_script()
   560     elif sys.argv[1] == 'graph':
   561         graph()
   562     elif sys.argv[1] == 'shell':
   563         shell()
   565 else:
   566     show_usage()
   567     sys.exit(1)
   569 sys.exit(0)
