xentaur

view xentaur.py @ 35:244f1602496a

config splitted to several modules
author igor
date Tue Sep 25 22:16:24 2007 +0300 (2007-09-25)
parents c68d804c3017
children 7bf7abe92123
line source
1 #!/usr/bin/python
4 import sys,os,time
5 import xenomips_vars
6 xenomips_vars.N='1'
8 xentaur_path=os.environ['HOME']+"/xentaur"
10 sys.path.append('/etc/xen')
11 sys.path.append(xentaur_path)
13 network='faberge'
14 domain='dyn1'
15 from xendomain import *
17 #try:
18 # exec 'from '+network+' import bridges,vbridges_table, hidden_bridges, domains, broken_links, temporary_links, domain_types'
19 #except:
20 # print "Can't find module: %s " % (xen_config_name)
21 # sys.exit(0)
23 bridges_turned_down=[]
25 from IPython.Shell import IPShellEmbed
28 screenrc=os.environ['HOME']+"/.screenrc_xentaur"
30 def run(program, *args):
31 pid = os.fork()
32 if not pid:
33 os.execvp(program, (program,) + args)
34 return os.wait()[0]
36 def run_command(line):
37 #cmds=line.split()
38 #run(cmds[0],*cmds[1:])
39 run("/bin/sh", "-c", line)
41 def run_command_return_stdout(line):
42 p = os.popen(line)
43 output = p.read()
44 p.close()
45 return output
47 def create_bridges_script():
48 unbound_bridges=bridges
49 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))
50 create_unbound_bridges+="\n"+"\n".join(map(lambda x: "sudo /bin/ip link set "+x+" up", unbound_bridges))
52 print """#!/bin/sh
53 # create unbound bridges
54 %(create_unbound_bridges)s
55 """ % {'create_unbound_bridges' : create_unbound_bridges}
58 def create_domains_script():
59 for domain in domains:
60 print "sudo /usr/sbin/xm create "+xentaur_path+"/xendomain "+" domain="+domain+" && sleep 1 && sudo /usr/sbin/xm sched-credit -d $(sudo /usr/sbin/xm list | grep "+domain+" | awk '{print $2}') -c 10 && sleep 1"
62 def destroy_domains_script():
63 for domain in domains:
64 print "sudo /usr/sbin/xm shutdown "+domain
66 def create_screens_script():
67 N=1
68 screens=[]
69 for domain in domains:
70 screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do sudo xm console "+domain+" ; echo Retrying in 5 seconds...; sleep 5; done'")
71 N+=1
72 screenlist="\n".join(screens)
74 #
75 # Previous terminal acccess commands:
76 # ip="192.168.80."+str(200+N)
77 # screens.append("screen -t "+domain+" "+str(N)+" sh -c 'while true; do ssh root@"+ip+" ; done'")
78 #
80 #hardstatus string "\%{gk}\%c \%{yk}\%M\%d \%{wk}\%?\%-Lw\%?\%{bw}\%n*\%f\%t\%?(\%u)\%?\%{wk}\%?\%+Lw\%?"
82 f=open(screenrc, "w");
83 f.write("""
84 hardstatus on
85 hardstatus alwayslastline
87 screen -t console 0 bash
88 %s
89 """ % (screenlist))
90 f.close()
92 def graph_node(node):
93 i=0
94 domain_type={}
95 for domain in domains:
96 domain_type[domain]=domain_types[i]
97 i+=1
98 return node+" [label=\" "+node+"\",shapefile=\"shapes/all/"+domain_type[node]+".png\",fontcolor=black,fontsize=16]"
100 def graph_bridge(bridge):
101 if bridge in hidden_bridges:
102 return ""
103 if bridge in bridges_turned_down:
104 return "%s [shape=none,shapefile=\"shapes/all/switch_turned_down.png\"]" % (bridge)
105 else:
106 return "%s [shape=none,shapefile=\"shapes/all/switch.png\"]" % (bridge)
109 def graph():
110 nodelist=""
111 bridgelist=""
112 linklist=""
113 physicallist=""
114 networklist=""
116 nodelist=";\n ".join(map(graph_node,nodes))
117 if nodelist: nodelist += ";"
119 bridgelist=";\n ".join(map(graph_bridge,bridges))
120 if bridgelist: bridgelist += ";"
122 links=[]
123 for host, bridges_raw in vbridges_table.iteritems():
124 i=0
125 for this_bridge in bridges_raw:
126 if this_bridge in hidden_bridges or not this_bridge:
127 continue
128 if not [ host, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
129 links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(bridges_raw.index(this_bridge))+"/0\"]")
130 i+=1
131 # if [ host, this_bridge ] in broken_links:
132 # links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(i)+"/0\",style=dashed]")
133 # else:
134 # links.append(host+" -- "+this_bridge+" [taillabel=\"fa"+str(i)+"/0\"]")
136 for link in temporary_links:
137 links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",color=blue,len=10,w=5,weight=5]")
139 for link in broken_links:
140 links.append(link[0]+" -- "+link[2]+" [taillabel=\"fa"+str(link[1])+"/0\",style=dashed]")
142 linklist=";\n ".join(links)
144 graph_dot = {
145 'nodelist' : nodelist,
146 'bridgelist' : bridgelist,
147 'linklist' : linklist,
148 'physicallist' : physicallist,
149 'networklist' : networklist,
150 }
152 f = open("xenomips.dot", "w");
153 f.write ("""
154 graph G {
155 edge [len=1.25];
156 splines=true;
157 // nodes
159 node [shape=plaintext,color=white,shapefile="shapes/cisco.bmp/router.png"];
160 %(nodelist)s
162 // bridges
164 node [shape=none,shapefile="shapes/all/switch.png"];
165 %(bridgelist)s
167 // physical
169 node [shape=rectangle,color=blue];
170 %(physicallist)s
172 // networks (not bridges, not physical)
173 node [shape=rectangle,color=green];
174 %(networklist)s
176 // links (between nodes and bridges)
177 %(linklist)s
179 };
180 """ % graph_dot)
181 f.close()
182 run_command("neato -Tpng -o xenomips.png xenomips.dot ")
184 def autoredraw():
185 graph()
187 def start_all():
188 create_bridges_script()
189 create_screens_script()
190 create_domains_script()
191 graph()
192 print """
193 cat <<NOTE_FOR_USER
194 # To view virtual network map, run:
195 gqview xenomips.png
196 # To attach to VM consoles, run:
197 screen -c screenrc
198 NOTE_FOR_USER
199 """
201 def shell():
202 autoredraw()
203 ipshell = IPShellEmbed()
204 ipshell()
206 def stop_all():
207 destroy_domains_script()
209 def show_usage():
210 print """Usage:
211 xentaur {start|stop|start-bridges|start-domains|stop-domains|screen|graph}
212 """
214 def save():
215 print "network =", xen_config_name
216 print "domains =", domains
217 print "domain_types =", domain_types
218 print "bridges =", bridges
219 print "vbridges_table =", vbridges_table
220 print "hidden_bridges =", hidden_bridges
221 print "broken_links =", broken_links
222 print "temporary_links =", temporary_links
223 print "bridges_turned_down =", bridges_turned_down
225 #-----------------------------------------------------------------------
226 # CLASSES
228 class Bridge:
229 def __init__ (self,name):
230 self.name=name
231 def up(self):
232 bridge_up(self.name)
233 def down(self):
234 bridge_down(self.name)
235 def show(self):
236 show_bridge(self.name)
237 def dump_start(self,filter=""):
238 dump_start(self.name,filter)
241 #-----------------------------------------------------------------------
242 # DOMAINS
244 def get_domain_id(domain):
245 return run_command_return_stdout("sudo xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain).rstrip("\n")
248 #-----------------------------------------------------------------------
249 # BRIDGES and IFACES
251 def bridge_down(bridge):
252 """
253 Turn the bridge <bridge> down
254 """
255 if bridge in bridges_turned_down:
256 print "Bridge %s is turned down already" % (bridge)
257 else:
258 bridges_turned_down.append(bridge)
259 run_command("sudo ip link set %s down" % bridge)
260 autoredraw()
262 def bridge_up(bridge):
263 """
264 Turn the bridge <bridge> up
265 """
266 if not (bridge in bridges_turned_down):
267 print "Bridge %s is turned up already" % (bridge)
268 else:
269 bridges_turned_down.remove(bridge)
270 run_command("sudo ip link set %s up" % bridge)
271 autoredraw()
273 def show_bridge(bridge):
274 """
275 Show the state of the bridge <bridge>
276 """
277 run_command("sudo ip link show %s" % bridge)
280 def int_disconnect(domain, int_number):
281 """
282 Disconnect the interface with the number <int_number>
283 of the domain <domain> from the bridge to which
284 it is connected
285 """
286 dom_id=get_domain_id(domain)
287 bridge=vbridges_table[domain][int_number]
288 if not bridge:
289 print "Interface %s of the %s domain is not connected" % (int_number, domain)
290 return 1
291 run_command("sudo brctl delif %s vif%s.%s" % (bridge, dom_id, int_number))
292 vbridges_table[domain][int_number]=''
293 if [ domain, int_number, bridge ] in temporary_links:
294 temporary_links.remove([ domain, int_number, bridge ])
295 else:
296 broken_links.append([ domain, int_number, bridge ])
297 autoredraw()
299 def int_connect(domain, int_number, bridge):
300 """
301 Connect the interface with the number <int_number>
302 of the domain <domain> to the bridge <bridge>
303 """
304 dom_id=get_domain_id(domain)
306 if vbridges_table[domain][int_number]:
307 print "Interface %s of the %s domain is connected already to the %s bridge" % (int_number, domain, vbridges_table[domain][int_number])
308 return 1
309 run_command("sudo brctl addif %s vif%s.%s" % (bridge, dom_id, int_number))
310 vbridges_table[domain][int_number]=bridge
311 if [ domain, int_number, bridge ] in broken_links:
312 broken_links.remove([ domain, int_number, bridge ])
313 else:
314 temporary_links.append([ domain, int_number, bridge ])
315 autoredraw()
317 def int_reconnect(domain, int_number, bridge):
318 """
319 Reconnect the interface with the number <int_number>
320 of the domain <domain> from the bridge to which
321 it is connected to the bridge <bridge>
322 """
323 int_disconnect(domain, int_number)
324 int_connect(domain, int_number, bridge)
326 def show_int(domain, int_number):
327 """
328 Show information about the interface <int_nuber>
329 of the domain <domain>
330 """
331 return vbridges_table[domain][int_number]
334 def dump_start(bridge, filter=""):
335 try:
336 print "Writing dump... (press Ctrl-C to stop)"
337 run_command("sudo tcpdump -w xentaur.dump -i %s %s > /dev/null 2>&1 " % (bridge,filter))
338 except:
339 print "Done.\n Dump is written to xentaur.dump"
340 return 0
342 def dump_stop():
343 return 0
346 #-----------------------------------------------------------------------
347 # CONFIGURATION TEMPLATES
350 def configure_ip_addresses(doms=domains):
351 return 0
353 def configure_ospf(doms=domains):
354 return 0
356 def configure_save(doms=domains):
357 write_to(doms,"\nwr\n")
359 #-----------------------------------------------------------------------
362 def add_domain(name,type):
363 domains.append(name)
364 domain_types.append(type)
366 def brake_link(domain,bridge):
367 broken_links.append([domain,bridge])
369 wt_timeout=0.5
370 def write_to(screen,string,return_to_screen=""):
371 """
372 write_to(screen,string):
374 Type *string* to the specified screen(s).
375 Screen may be specified with the number *screen*,
376 with array of numbers,
377 with array of names.
379 """
380 screen_numbers=[] # number of the screens to write to
381 if type(screen) == list:
382 screen_numbers=map(lambda x: domains.index(x)+1, screen)
383 elif type(screen) == int:
384 screen_numbers=[screen]
385 else:
386 screen_numbers=[domains.index(screen)+1]
388 for screen_number in screen_numbers:
389 run_command("screen -X select "+str(screen_number))
390 time.sleep(wt_timeout)
391 for line in string.splitlines():
392 f=open('/tmp/xentaurbuf', 'w')
393 f.write(line+"\n")
394 f.close()
395 run_command("screen -X readreg p /tmp/xentaurbuf")
396 time.sleep(wt_timeout)
397 run_command("nohup screen -X paste p >& /dev/null")
398 time.sleep(wt_timeout)
400 if return_to_screen != "":
401 run_command("screen -X select %s" % (return_to_screen))
402 time.sleep(wt_timeout)
404 #-----------------------------------------------------------------------
406 cisco_fa01_up="""
407 ena
408 conf t
409 int fa0/0
410 no shutdown
411 exit
412 int fa1/0
413 no shutdown
414 exit
415 exit
416 exit
417 """
419 cisco_set_ip_on_int="""
420 interface fa%s/0
421 no ip address
422 ip address %s 255.255.255.0
423 exit
424 """
428 nodes=domains
430 if len(sys.argv) > 1:
431 if sys.argv[1] == 'start':
432 start_all()
433 if sys.argv[1] == 'stop':
434 stop_all()
435 if sys.argv[1] == 'start-bridges':
436 create_bridges_script()
437 if sys.argv[1] == 'start-domains':
438 create_domains_script()
439 if sys.argv[1] == 'stop-domains':
440 destroy_domains_script()
441 elif sys.argv[1] == 'screen':
442 create_screens_script()
443 elif sys.argv[1] == 'graph':
444 graph()
445 elif sys.argv[1] == 'shell':
446 shell()
448 else:
449 show_usage()
450 sys.exit(1)
452 sys.exit(0)