xentaur
view xentaur.py @ 30:55b03e2a35c0
another shape added
| author | igor | 
|---|---|
| date | Fri Sep 21 22:40:26 2007 +0300 (2007-09-21) | 
| parents | d22ff6f55dc5 | 
| children | 532f2ed25f70 | 
 line source
     1 #!/usr/bin/python
     4 import sys,os,time
     5 import xenomips_vars
     6 xenomips_vars.N='1'
     7 sys.path.append('/etc/xen')
     9 xen_config_name='fabergeN'
    10 exec 'from '+xen_config_name+' import bridges,vbridges_table, hidden_bridges, domains, broken_links, temporary_links, domain_types'
    12 bridges_turned_down=[]
    14 from IPython.Shell import IPShellEmbed
    17 screenrc=os.environ['HOME']+"/.screenrc_xentaur"
    19 def run(program, *args):
    20     pid = os.fork()
    21     if not pid:
    22         os.execvp(program, (program,) +  args)
    23     return os.wait()[0]
    25 def run_command(line):
    26     #cmds=line.split()
    27     #run(cmds[0],*cmds[1:])
    28     run("/bin/sh", "-c", line)
    30 def run_command_return_stdout(line):
    31     p = os.popen(line)
    32     output = p.read()
    33     p.close()
    34     return output
    36 def create_bridges_script():
    37     unbound_bridges=bridges
    38     create_unbound_bridges="\n".join(map(lambda x: "sudo /usr/sbin/brctl show | awk '{print $1}' | grep -q "+x+" || sudo /usr/sbin/brctl addbr "+x, unbound_bridges))
    39     create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo /bin/ip link set "+x+" up", unbound_bridges))
    41     print """#!/bin/sh
    42 # create unbound bridges
    43 %(create_unbound_bridges)s
    44 """ % {'create_unbound_bridges' : create_unbound_bridges}
    47 def create_domains_script():
    48     for N in range(len(domains)):
    49         print "sudo /usr/sbin/xm create "+xen_config_name+" N="+str(N)+" && sleep 1 && sudo /usr/sbin/xm sched-credit -d $(sudo /usr/sbin/xm list | grep "+domains[N]+" | awk '{print $2}') -c 10 && sleep 1"
    51 def destroy_domains_script():
    52     for N in range(len(domains)):
    53         print "sudo /usr/sbin/xm shutdown "+domains[N]
    55 def create_screens_script():
    57     N=1
    58     screens=[]
    59     for domain in domains:
    60         screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do sudo xm console "+domain+" ; echo Retrying in 5 seconds...; sleep 5; done'")
    61         N+=1
    62     screenlist="\n".join(screens)
    64 #
    65 # Previous terminal acccess commands:
    66 #        ip="192.168.80."+str(200+N)
    67 #        screens.append("screen -t "+domain+"   "+str(N)+" sh -c 'while true; do ssh root@"+ip+" ; done'")
    68 #
    70 #hardstatus string "\%{gk}\%c \%{yk}\%M\%d \%{wk}\%?\%-Lw\%?\%{bw}\%n*\%f\%t\%?(\%u)\%?\%{wk}\%?\%+Lw\%?"
    72     f=open(screenrc, "w");
    73     f.write("""
    74 hardstatus on
    75 hardstatus alwayslastline
    77 screen -t console 0 bash
    78 %s
    79 """ % (screenlist))
    80     f.close()
    82 def graph_node(node):
    83     i=0
    84     domain_type={}
    85     for domain in domains:
    86         domain_type[domain]=domain_types[i]
    87         i+=1
    88     return node+" [label=\"  "+node+"\",shapefile=\"shapes/all/"+domain_type[node]+".png\",fontcolor=navy,fontsize=14]"
    90 def graph_bridge(bridge):
    91     if bridge in hidden_bridges:
    92         return ""
    93     if bridge in bridges_turned_down:
    94         return "%s [shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (bridge)
    95     else:
    96         return "%s [shape=none,shapefile=\"shapes/all/switch.png\"]" % (bridge)
    99 def graph():
   100     nodelist=""
   101     bridgelist=""
   102     linklist=""
   103     physicallist=""
   104     networklist=""
   106     nodelist=";\n    ".join(map(graph_node,nodes))
   107     if nodelist: nodelist += ";"
   109     bridgelist=";\n    ".join(map(graph_bridge,bridges))
   110     if bridgelist: bridgelist += ";"
   112     links=[]
   113     for host, bridges_raw in vbridges_table.iteritems():
   114         i=0
   115         for this_bridge in bridges_raw:
   116             if this_bridge in hidden_bridges or not this_bridge:
   117                 continue 
   118             if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
   119                 links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(bridges_raw.index(this_bridge))+"/0\"]")
   120                 i+=1
   121        #         if [ host, this_bridge ] in broken_links:
   122        #             links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(i)+"/0\",style=dashed]")
   123        #         else:
   124        #             links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(i)+"/0\"]")
   126     for link in temporary_links:
   127         links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",color=blue,len=10,w=5,weight=5]")
   129     for link in broken_links:
   130         links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",style=dashed]")
   132     linklist=";\n    ".join(links)
   134     graph_dot = {
   135             'nodelist'      : nodelist,
   136             'bridgelist'    : bridgelist,
   137             'linklist'      : linklist,
   138             'physicallist'  : physicallist,
   139             'networklist'   : networklist,
   140           }
   142     f = open("xenomips.dot", "w");
   143     f.write ("""
   144 graph G {
   145     edge [len=1.25];
   146     splines=true;
   147 // nodes
   149     node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
   150     %(nodelist)s
   152 // bridges
   154     node [shape=none,shapefile="shapes/all/switch.png"];
   155     %(bridgelist)s
   157 // physical
   159     node [shape=rectangle,color=blue];
   160     %(physicallist)s
   162 // networks (not bridges, not physical)
   163     node [shape=rectangle,color=green];
   164     %(networklist)s
   166 // links (between nodes and bridges)
   167     %(linklist)s
   169 };
   170 """ % graph_dot)
   171     f.close()
   172     run_command("neato -Tpng -o xenomips.png xenomips.dot ")
   174 def autoredraw():
   175     graph()
   177 def start_all():
   178         create_bridges_script()
   179         create_screens_script()
   180         create_domains_script()
   181         graph()
   182         print """
   183         cat <<NOTE_FOR_USER
   184 # To view virtual network map, run:
   185     gqview xenomips.png
   186 # To attach to VM consoles, run:
   187     screen -c screenrc
   188 NOTE_FOR_USER
   189 """
   191 def shell():
   192     ipshell = IPShellEmbed()
   193     ipshell()
   195 def stop_all():
   196         destroy_domains_script()
   198 def show_usage():
   199     print """Usage:
   200     xentaur {start|stop|start-bridges|start-domains|stop-domains|screen|graph}
   201 """
   203 #-----------------------------------------------------------------------
   204 # DOMAINS
   206 def get_domain_id(domain):
   207     return run_command_return_stdout("sudo xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain).rstrip("\n")
   210 #-----------------------------------------------------------------------
   211 # BRIDGES and IFACES
   213 def bridge_down(bridge):
   214     """
   215     Turn the bridge <bridge> down
   216     """
   217     if bridge in bridges_turned_down:
   218         print "Bridge %s is turned down already" % (bridge)
   219     else:
   220         bridges_turned_down.append(bridge)
   221         run_command("sudo ip link set %s down" % bridge)
   222         autoredraw()
   224 def bridge_up(bridge):
   225     """
   226     Turn the bridge <bridge> up
   227     """
   228     if not (bridge in bridges_turned_down):
   229         print "Bridge %s is turned up already" % (bridge)
   230     else:
   231         bridges_turned_down.remove(bridge)
   232         run_command("sudo ip link set %s up" % bridge)
   233         autoredraw()
   235 def show_bridge(bridge):
   236     """
   237     Show the state of the bridge <bridge>
   238     """
   239     run_command("sudo ip link show %s" % bridge)
   242 def int_disconnect(domain, int_number):
   243     """
   244     Disconnect the interface with the number <int_number>
   245     of the domain <domain> from the bridge to which
   246     it is connected
   247     """
   248     dom_id=get_domain_id(domain)
   249     bridge=vbridges_table[domain][int_number]
   250     if not bridge:
   251         print "Interface %s of the %s domain is not connected" % (int_number, domain)
   252         return 1
   253     run_command("sudo brctl delif %s vif%s.%s" % (bridge, dom_id, int_number))
   254     vbridges_table[domain][int_number]=''
   255     if [ domain, int_number, bridge ] in temporary_links:
   256         temporary_links.remove([ domain, int_number, bridge ])
   257     else:
   258         broken_links.append([ domain, int_number, bridge ])
   259     autoredraw()
   261 def int_connect(domain, int_number, bridge):
   262     """
   263     Connect the interface with the number <int_number>
   264     of the domain <domain> to the bridge <bridge>
   265     """
   266     dom_id=get_domain_id(domain)
   268     if vbridges_table[domain][int_number]:
   269         print "Interface %s of the %s domain is connected already to the %s bridge" % (int_number, domain, vbridges_table[domain][int_number])
   270         return 1
   271     run_command("sudo brctl addif %s vif%s.%s" % (bridge, dom_id, int_number))
   272     vbridges_table[domain][int_number]=bridge
   273     if [ domain, int_number, bridge ] in broken_links:
   274         broken_links.remove([ domain, int_number, bridge ])
   275     else:
   276         temporary_links.append([ domain, int_number, bridge ])
   277     autoredraw()
   279 def int_reconnect(domain, int_number, bridge):
   280     """
   281     Reconnect the interface with the number <int_number>
   282     of the domain <domain> from the bridge to which
   283     it is connected to the bridge <bridge>
   284     """
   285     int_disconnect(domain, int_number)
   286     int_connect(domain, int_number, bridge)
   288 def show_int(domain, int_number):
   289     """
   290     Show information about the interface <int_nuber>
   291     of the domain <domain>
   292     """
   293     return vbridges_table[domain][int_number]
   296 def dump_start(bridge, filter=""):
   297     run_command("sudo tcpdump -w xentaur.dump -i %s %s" % (bridge,filter))
   298     return 0
   300 def dump_stop():
   301     return 0
   303 #-----------------------------------------------------------------------
   306 def add_domain(name,type):
   307     domains.append(name)
   308     domain_types.append(type)
   310 def brake_link(domain,bridge):
   311     broken_links.append([domain,bridge])
   313 wt_timeout=0.5
   314 def write_to(screen,string,return_to_screen=""):
   315     """
   316     write_to(screen,string):
   318         Type *string* to the specified screen(s).
   319         Screen may be specified with the number *screen*,
   320         with array of numbers, 
   321         with array of names.
   323     """
   324     screen_numbers=[]           # number of the screens to write to
   325     if type(screen) == list:
   326         screen_numbers=map(lambda x: domains.index(x)+1, screen)
   327     elif type(screen) == int:
   328         screen_numbers=[screen]
   329     else:
   330         screen_numbers=[domains.index(screen)+1]
   332     for screen_number in screen_numbers:
   333         run_command("screen -X select "+str(screen_number))
   334         time.sleep(wt_timeout)
   335         for line in string.splitlines():
   336             f=open('/tmp/xentaurbuf', 'w')
   337             f.write(line+"\n")
   338             f.close()
   339             run_command("screen -X readreg p /tmp/xentaurbuf")
   340             time.sleep(wt_timeout)
   341             run_command("nohup screen -X paste p >& /dev/null")
   342             time.sleep(wt_timeout)
   344         if return_to_screen != "":
   345             run_command("screen -X select %s" % (return_to_screen))
   346             time.sleep(wt_timeout)
   348 #-----------------------------------------------------------------------
   350 cisco_fa01_up="""
   351 ena
   352 conf t
   353 int fa0/0
   354 no shutdown
   355 exit
   356 int fa1/0
   357 no shutdown
   358 exit
   359 exit
   360 exit
   361 """
   363 cisco_set_ip_on_int="""
   364 interface fa%s/0
   365 no ip address
   366 ip address %s 255.255.255.0
   367 exit
   368 """
   370 #-----------------------------------------------------------------------
   372 nodes=domains
   374 if len(sys.argv) > 1:
   375     if sys.argv[1] == 'start':
   376         start_all()
   377     if sys.argv[1] == 'stop':
   378         stop_all()
   379     if sys.argv[1] == 'start-bridges':
   380         create_bridges_script()
   381     if sys.argv[1] == 'start-domains':
   382         create_domains_script()
   383     if sys.argv[1] == 'stop-domains':
   384         destroy_domains_script()
   385     elif sys.argv[1] == 'screen':
   386         create_screens_script()
   387     elif sys.argv[1] == 'graph':
   388         graph()
   389     elif sys.argv[1] == 'shell':
   390         shell()
   392 else:
   393     show_usage()
   394     sys.exit(1)
   396 sys.exit(0)
