xentaur

view xentaur.py @ 66:aaf034af3a35

Merge of Xgurulla into Xentaur code. Not completed yet!!!

Now Xentaur can work with Amazon EC2,
but only with. Local domains management
is switched off temporarily.
author Igor Chubin <igor@chub.in>
date Sat Jan 09 20:20:08 2010 +0200 (2010-01-09)
parents cf823d27b029
children 6c145935ece5
line source
1 #!/usr/bin/python
2 # vim: set fileencoding=utf-8 :
4 import sys,os,time
5 from IPython.Shell import IPShellEmbed
7 path_xentaur="%s/hg/xentaur" % os.environ['HOME']
8 path_shapes=path_xentaur+'/shapes'
9 path_scripts=path_xentaur+'/files'
11 network='net1'
13 path_network=os.environ['HOME']+"/.xentaur/"+network
14 if not os.path.exists(path_network):
15 os.makedirs(path_network)
16 screenrc=path_network+"/.screenrc_xentaur"
18 sys.path.append('/etc/xen')
19 sys.path.append(path_xentaur)
20 sys.path.append(path_network)
21 sys.path.append('.')
23 node_object={}
24 link_object={}
25 bridge_object={}
26 ec2_node={}
28 domain='dyn1'
29 from xendomain import *
31 bridges_turned_down=[]
33 def run(program, *args):
34 pid = os.fork()
35 if not pid:
36 os.execvp(program, (program,) + args)
37 return os.wait()[0]
39 def run_command(line):
40 #cmds=line.split()
41 #run(cmds[0],*cmds[1:])
42 run("/bin/sh", "-c", line)
44 def run_command_return_stdout(line):
45 p = os.popen(line)
46 output = p.read()
47 p.close()
48 return output
50 ################################################################################
51 #Xentaur command-line commands
53 ## Start
55 def start_bridges():
56 unbound_bridges=set(bridges)-set(real_bridges)
57 script=""
58 script="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
59 script+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
60 script+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
62 print """#!/bin/sh
63 # create unbound bridges
64 %s
65 """ % (script)
67 def start_domain(domain):
68 print "sudo xm create "+path_xentaur+"/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"
70 def start_domains(doms=domains):
71 for domain in doms:
72 if not domain in real_nodes:
73 start_domain(domain)
75 def start_all():
76 graph()
77 screen()
78 html()
79 start_bridges()
80 start_domains()
82 def ec2_assign_nodes_to_instances():
83 domain_number=0
84 for dom in domains:
85 node_name=network+"-node%s"%(domain_number/2)
86 ec2_node[dom]=node_name
87 domain_number+=1
89 def make_start_emulators():
90 s=""
91 #s+="cat screenrc_template > screenrc_$NETWORK\n"
92 #s+="echo \"screen -t console 0 sh -c 'cd ~/xentaur; ./xentaur.py shell'\" >> screenrc_$NETWORK\n"
93 ios="/mnt/ios/C7200-AD.BIN"
94 ec2_assign_nodes_to_instances()
95 for dom in domains:
96 node_name=ec2_node[dom]
97 i=0
98 line='dynamips '+ios
99 line2=''
100 for iface in vbridges_table[dom]:
101 bridge=vbridges_table[dom][i]
102 if i>0:
103 line += " -p %s:PA-FE-TX "%i
104 line += " -s %s:0:tap:%s_%s "% (i,dom,iface)
105 line2 += "sleep 2; brctl addif %s %s; "%(bridge, dom+"_"+iface)
106 line2 +='ifconfig %s up; ifconfig %s promisc ;' %(bridge, bridge)
107 line2 += "ifconfig %s_%s up; "%(dom, iface)
108 i+=1
109 s += "ssh %s \"mkdir -p /mnt/%s; cd /mnt/%s; screen -S %s- -d -m %s\"\n"%(node_name,dom,dom,dom,line)
110 s += "ssh %s \"%s\"\n" % (node_name, line2)
111 #s += "echo \"screen %s ssh -t %s 'screen -r %s-'\" >> screenrc_%s\n" % (domain_number, node_name, dom, network)
112 #s += "echo \"screen -t %s %s connect-ec2-session INSTANCE EC2_NODE %s %s %s\" >> screenrc_$NETWORK\n" % (dom, domain_number+1, node_name, network, dom)
113 return s
115 def make_start_instances_config(net=network):
116 f = open(path_network+"/start-instances-"+network, "w");
117 f.write("INSTANCES_NUMBER=%s\n"%((len(domains)+1)/2))
118 f.write("start_emulators()\n{\n%s\n}\n"%make_start_emulators())
119 f.close()
121 def start_network(net=network):
122 make_start_instances_config()
123 #run_command("cd %s; env NETWORK=%s sh %s instances start" % (path_network, network, path_scrips+"/ec2-instances"))
125 def stop_network(net=network):
126 run_command("cd %s; env NETWORK=%s sh instances stop" % (path_network, network))
128 ## Stop
130 def stop_domain(domain,wait=0):
131 if wait:
132 print "sudo xm shutdown -w "+domain
133 else:
134 print "sudo xm shutdown "+domain
136 def stop_domains(doms=domains, wait=0):
137 for domain in doms:
138 if not domain in real_nodes:
139 stop_domain(domain,wait)
141 def stop_bridges():
142 ###FIXME###
143 return 0
145 def stop_all(wait=0):
146 stop_domains(domains, wait)
147 stop_bridges()
149 def restart_all():
150 stop_all(1)
151 start_all()
153 ####################################################
155 def create_objects():
156 create_node_objects()
157 create_bridge_objects()
158 create_link_objects()
160 def create_node_objects():
161 for dom in domains:
162 node_object[dom]=Node(dom)
164 def create_bridge_objects():
165 for bridge in bridges:
166 bridge_object[bridge]=Bridge(bridge)
168 def create_link_objects():
170 for node, bridges_raw in vbridges_table.iteritems():
171 interface=0
172 j=0
173 for this_bridge in bridges_raw:
174 int_label=""
175 if this_bridge.find(':') != -1:
176 res = this_bridge.split(':')
177 this_bridge= res[0]
178 bridges_raw[j] = this_bridge
179 int_label = res[1]
180 if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
181 name="%s %s %s" % (node,interface,this_bridge)
182 link_object[name]=Link(name,node,interface,this_bridge,int_label)
183 interface+=1
184 vbridges_table[node]=bridges_raw
186 for node, bridges_raw in bridge_bridge_table.iteritems():
187 interface=0
188 j=0
189 for this_bridge in bridges_raw:
190 int_label=""
191 if this_bridge.find(':') != -1:
192 res = this_bridge.split(':')
193 this_bridge= res[2]
194 bridges_raw[j] = this_bridge
195 int_label = res[1]
196 if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
197 name="%s %s %s" % (node,interface,this_bridge)
198 link_object[name]=Link(name,node,interface,this_bridge,int_label)
199 interface+=1
200 bridge_bridge_table[node]=bridges_raw
202 for node,interface,bridge in temporary_links:
203 name="%s %s %s" % (node,interface,bridge)
204 link_object[name]=Link(name,node,interface,this_bridge)
206 for node,interface,bridge in broken_links:
207 name="%s %s %s" % (node,interface,bridge)
208 link_object[name]=Link(name,node,interface,this_bridge)
211 ####################################################
213 def screen():
214 wait_seconds=1
215 screens=[]
216 for domain in domains:
217 screens.append("screen -t %(domain)s %(domain_number)s %(console_string)s" % {
218 'domain' : domain,
219 'domain_number' : domains.index(domain)+1,
220 'console_string': node_object[domain].console_string(),
221 'wait_interval' : wait_seconds } )
223 screenlist="\n".join(screens)
225 hardstatus='hardstatus string "%{rk}Xentaur%{bk}@%H %{gk}%c %{yk}%d.%m %{wk}%?%-Lw%?%{bw}%n*%f%t%?(%u)%?%{wk}%?%+Lw%?"'
227 f=open(screenrc, "w");
228 f.write("""
229 hardstatus on
230 hardstatus alwayslastline
231 %s
233 screen -t console 0 sh -c 'while true; do %s/xentaur.py shell ; echo Retrying in %s secods...; sleep %s ; clear; done'
234 %s
235 """ % (hardstatus,path_xentaur,wait_seconds,wait_seconds,screenlist))
236 f.close()
237 print "# GNU Screen config file is written to: %s" % screenrc
239 def graph():
240 nodelist=""
241 bridgelist=""
242 linklist=""
243 physicallist=""
244 networklist=""
246 nodelist=";\n ".join(map(lambda node: node_object[node].graphviz_string(),nodes))
247 if nodelist: nodelist += ";"
248 bridgelist=";\n ".join(map(lambda bridge: bridge_object[bridge].graphviz_string(),bridges))
249 if bridgelist: bridgelist += ";"
250 linklist=";\n ".join(map(lambda link: link_object[link].graphviz_string(),link_object.keys()))
251 if linklist: linklist += ";"
253 f = open(path_network+"/"+network+".dot", "w");
254 f.write ("""
255 graph G {
256 edge [len=1.25];
257 splines=true;
258 // nodes
259 %s
261 // bridges
262 %s
264 // physical
265 node [shape=rectangle,color=blue];
266 %s
268 // networks (not bridges, not physical)
269 node [shape=rectangle,color=green];
270 %s
272 // links (between nodes and bridges)
273 %s
275 };
276 """ % (nodelist, bridgelist, physicallist, networklist, linklist))
277 f.close()
278 run_command("neato -Tpng -o %s.png %s.dot "%(path_network+"/"+network,path_network+"/"+network))
279 run_command("neato -Tjpg -o %s.jpg %s.dot "%(path_network+"/"+network,path_network+"/"+network))
280 run_command("neato -Tsvg -o %s.svg %s.dot "%(path_network+"/"+network,path_network+"/"+network))
281 #run_command("neato -Tcmapx -o %s.cmapx -NURL=http://google.com %s.dot "%(path_network+"/"+network,path_network+"/"+network))
282 print "# Network map is written to files: %s.{png,svg,jpg,dot}" % (path_network+"/"+network)
284 def html():
285 f = open(path_network+"/index.html", "w");
286 f.write ("""
287 <html>
288 <head>
289 <title>Network %s map</network>
290 <body>
291 <img src="%s.png" /><br/>
292 <pre>
293 nodes=%s
294 bridges=%s
295 vbridges_table=%s
296 </pre>
297 </body>
298 </head>
299 </html>
300 """ % (network, network, domains, bridges, vbridges_table))
301 f.close()
302 #run_command("cp %s.html /var/www/ec2/network/%s/index.html"%(network,network))
304 def autoredraw():
305 graph()
306 html()
307 screen()
309 def shell():
310 autoredraw()
311 ipshell = IPShellEmbed(['-noconfirm_exit'])
312 ipshell()
314 def version():
315 print """
316 Xentaur 0.1-PRE
318 ,--,
319 _ ___/ /\\|
320 ,;`( )__, ) ~
321 // .// '--;
322 ' / \ |
324 """
326 def info():
327 version()
329 print "Network name: ", network
330 print "-----------------------------------------------"
331 print
332 print "Nodes: ", len(domains)
333 print " * virtual nodes: ", len(domains)-len(real_nodes)
334 print " * real nodes:", len(real_nodes)
335 print
336 print "Bridges:", len(bridges)
337 print " * virtual bridges:", len(bridges)-len(real_bridges)-len(cross_bridges)
338 print " * real switches:", len(real_bridges)
339 print " * direct links:", len(cross_bridges)
341 def show_usage():
342 print """Usage:
343 xentaur <command> [<argument>]
345 Commands:
346 start-all -- start bridges and domains
347 start-domains -- start domains only
348 start-bridges -- start bridges only
349 stop-all -- stop bridges and domains
350 stop-domains -- stop domains only
351 stop-bridges -- stop bridges only (domains have to be stopped already)
352 restart-all -- restart bridges and domains
354 start <domain> -- start the <domain>
355 stop <domain> -- stop the <domain>
357 graph -- generate network scheme (result is in <network>.{png,jpg,svg})
358 screen -- generate GNU Screen config file (~/.screenrc_xentaur)
359 shell -- run Xentaur shell
361 """
363 def save():
364 print "network =", xen_config_name
365 print "domains =", domains
366 print "domain_types =", domain_types
367 print "bridges =", bridges
368 print "vbridges_table =", vbridges_table
369 print "hidden_bridges =", hidden_bridges
370 print "broken_links =", broken_links
371 print "temporary_links =", temporary_links
372 print "bridges_turned_down =", bridges_turned_down
374 #-----------------------------------------------------------------------
375 # CLASSES
377 class Bridge:
378 def __init__ (self,name):
379 self.name=name
380 def up(self):
381 bridge_up(self.name)
382 def down(self):
383 bridge_down(self.name)
384 def show(self):
385 show_bridge(self.name)
386 def dump_start(self,filter=""):
387 dump_start(self.name,filter)
389 def is_hidden(self):
390 return self.name in hidden_bridges
391 def is_real(self):
392 return self.name in real_bridges
393 def is_turned_down(self):
394 return self.name in bridges_turned_down
395 def is_cross(self):
396 return self.name in cross_bridges
398 def graphviz_string(self):
399 if self.is_hidden():
400 return "//"
401 elif self.is_cross():
402 return "%s [shape=circle,height=0.03,color=black,fillcolor=black,style=filled,label=\"\"]" % (self.name)
403 elif self.is_real():
404 return "%s [color=white,shape=none,shapefile=\"%s/all/real_switch.png\"]" % (self.name, path_shapes)
405 elif self.is_turned_down():
406 return "%s [color=white,shape=none,shapefile=\"%s/all/switch_turned_down.png\"]" % (self.name, path_shapes)
407 else:
408 return "%s [color=white,shape=none,shapefile=\"%s/all/switch.png\"]" % (self.name, path_shapes)
411 class Node:
412 def __init__ (self,name):
413 self.name=name
414 self.type=domain_types[domains.index(name)]
415 def start(self):
416 return ""
417 def stop(self):
418 return ""
419 def start_commandline(self):
420 return ""
421 def get_domain_id(self):
422 return get_domain_id(self.name)
423 def graphviz_string(self):
424 return self.name+" [color=white,shape=plaintext,label=\" "+self.name+"\",shapefile=\""+path_shapes+"/all/"+\
425 domain_types[domains.index(self.name)]+".png\",fontcolor=black,fontsize=16,target=\"http://google.com\"]"
426 def console_string(self):
427 ec2=True # FIXME
428 ec2_assign_nodes_to_instances()
429 if ec2:
430 return path_scripts+"/node-terminal-session INSTANCE EC2_NODE %s %s %s"%(ec2_node[self.name], network, self.name)
432 if self.type in [ 'quagga', 'dynamips', 'freebsd', 'linux' ]:
433 return "sudo xm console "+self.name
434 elif self.name in real_bridges or self.name in real_nodes:
435 return "echo Press enter to connect; read line; "+connection_table[self.name]
438 class Link:
439 def __init__ (self,name,node,interface,bridge,label=""):
440 self.name=name
441 self.node=node
442 self.interface=interface
443 self.bridge=bridge
444 self.label=label
446 def is_temporary(self):
447 return [self.node,self.interface,self.bridge] in temporary_links
449 def is_broken(self):
450 return ([self.node,self.interface,self.bridge] in broken_links)
452 def is_hidden(self):
453 return self.bridge in hidden_bridges
455 def graphviz_string(self):
456 if self.is_hidden():
457 return "//"
458 if self.is_temporary():
459 return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",color=blue,len=10,w=5,weight=5]"
460 if self.is_broken():
461 return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",style=dashed]"
463 ip="\\n.%s.%s" % (bridges.index(self.bridge)+1, domains.index(self.node)+1)
464 if domain_types[domains.index(self.node)] == 'dynamips':
465 int_name="fa"+str(self.interface)+"/0"
466 else:
467 int_name="eth"+str(self.interface)
468 if self.label != "":
469 int_name = self.label
470 return self.node+" -- "+self.bridge+" [taillabel=\""+int_name+ip+"\",fontsize=14,fontname=fixed]"
473 #-----------------------------------------------------------------------
474 # DOMAINS
476 def get_domain_id(domain):
477 return run_command_return_stdout("sudo xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain).rstrip("\n")
480 #-----------------------------------------------------------------------
481 # BRIDGES and IFACES
483 def bridge_down(bridge):
484 """
485 Turn the bridge <bridge> down
486 """
487 if bridge in real_bridges:
488 print "Bridge %s is a real bridge" % (bridge)
489 return -1
490 if bridge in bridges_turned_down:
491 print "Bridge %s is turned down already" % (bridge)
492 else:
493 bridges_turned_down.append(bridge)
494 run_command("sudo ip link set %s down" % bridge)
495 autoredraw()
497 def bridge_up(bridge):
498 """
499 Turn the bridge <bridge> up
500 """
501 if bridge in real_bridges:
502 print "Bridge %s is a real bridge" % (bridge)
503 return -1
504 if not (bridge in bridges_turned_down):
505 print "Bridge %s is turned up already" % (bridge)
506 else:
507 bridges_turned_down.remove(bridge)
508 run_command("sudo ip link set %s up" % bridge)
509 autoredraw()
511 def show_bridge(bridge):
512 """
513 Show the state of the bridge <bridge>
514 """
515 if bridge in real_bridges:
516 print "Bridge %s is a real bridge" % (bridge)
517 return -1
518 run_command("sudo ip link show %s" % bridge)
521 def int_disconnect(domain, int_number):
522 """
523 Disconnect the interface with the number <int_number>
524 of the domain <domain> from the bridge to which
525 it is connected
526 """
527 dom_id=get_domain_id(domain)
528 bridge=vbridges_table[domain][int_number]
529 if not bridge:
530 print "Interface %s of the %s domain is not connected" % (int_number, domain)
531 return 1
532 run_command("sudo brctl delif %s vif%s.%s" % (bridge, dom_id, int_number))
533 vbridges_table[domain][int_number]=''
534 if [ domain, int_number, bridge ] in temporary_links:
535 temporary_links.remove([ domain, int_number, bridge ])
536 else:
537 broken_links.append([ domain, int_number, bridge ])
538 autoredraw()
540 def int_connect(domain, int_number, bridge):
541 """
542 Connect the interface with the number <int_number>
543 of the domain <domain> to the bridge <bridge>
544 """
545 if bridge in real_bridges:
546 print "Bridge %s is a real bridge" % (bridge)
547 return -1
549 dom_id=get_domain_id(domain)
550 if vbridges_table[domain][int_number]:
551 print "Interface %s of the %s domain is connected already to the %s bridge" % (int_number, domain, vbridges_table[domain][int_number])
552 return 1
553 run_command("sudo brctl addif %s vif%s.%s" % (bridge, dom_id, int_number))
554 vbridges_table[domain][int_number]=bridge
555 if [ domain, int_number, bridge ] in broken_links:
556 broken_links.remove([ domain, int_number, bridge ])
557 else:
558 temporary_links.append([ domain, int_number, bridge ])
559 autoredraw()
561 def int_reconnect(domain, int_number, bridge):
562 """
563 Reconnect the interface with the number <int_number>
564 of the domain <domain> from the bridge to which
565 it is connected to the bridge <bridge>
566 """
567 if bridge in real_bridges:
568 print "Bridge %s is a real bridge" % (bridge)
569 return -1
571 int_disconnect(domain, int_number)
572 int_connect(domain, int_number, bridge)
574 def show_int(domain, int_number):
575 """
576 Show information about the interface <int_nuber>
577 of the domain <domain>
578 """
579 return vbridges_table[domain][int_number]
582 def dump_start(bridge, filter=""):
583 if bridge in real_bridges:
584 print "Bridge %s is a real bridge" % (bridge)
585 return -1
586 try:
587 print "Writing dump... (press Ctrl-C to stop)"
588 run_command("sudo tcpdump -w xentaur.dump -i %s %s > /dev/null 2>&1 " % (bridge,filter))
589 except:
590 print "Done.\n Dump is written to xentaur.dump"
591 return 0
593 def dump_stop():
594 return 0
597 #-----------------------------------------------------------------------
598 # CONFIGURATION TEMPLATES
601 def configure_ip_addresses(doms=domains):
603 cisco_set_ip_on_int="""
604 \n\n\n
605 int fa%s/0
606 duplex full
607 no ip address
608 ip address %s 255.255.255.0
609 no shutdown
610 exit
611 """
613 quagga_set_ip_on_int="""
614 int eth%s
615 no ip address
616 ip address %s/24
617 no shutdown
618 exit
619 """
621 linux_set_ip_on_int="""
622 ifconfig eth%s %s netmask 255.255.255.0
623 """
625 for dom in doms:
626 i=domains.index(dom)+1
627 if domain_types[domains.index(dom)] == 'quagga':
628 command = quagga_set_ip_on_int
629 write_to(i,"\nconf t\n")
630 j=0
631 for br in vbridges_table[dom]:
632 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
633 j+=1
634 write_to(i,"\nend\n")
635 elif domain_types[domains.index(dom)] == 'linux':
636 command = linux_set_ip_on_int
637 j=0
638 for br in vbridges_table[dom]:
639 #write_to(i, command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)) )
640 print i, command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i))
641 j+=1
642 else:
643 command = cisco_set_ip_on_int
644 write_to(i,"\nena\nconf t\n")
645 j=0
646 for br in vbridges_table[dom]:
647 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
648 j+=1
649 write_to(i,"\nend\n")
650 return 0
652 def configure_no_ip_addresses(doms=domains):
654 cisco_set_ip_on_int="""
655 \n\n\n
656 int fa%s/0
657 no ip address %s 255.255.255.0
658 exit
659 """
661 quagga_set_ip_on_int="""
662 int eth%s
663 no ip address %s/24
664 exit
665 """
667 for dom in doms:
668 i=domains.index(dom)+1
669 if domain_types[domains.index(dom)] == 'quagga':
670 command = quagga_set_ip_on_int
671 write_to(i,"\nconf t\n")
672 j=0
673 for br in vbridges_table[dom]:
674 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
675 j+=1
676 write_to(i,"\nend\n")
677 else:
678 command = cisco_set_ip_on_int
679 write_to(i,"\nena\nconf t\n")
680 j=0
681 for br in vbridges_table[dom]:
682 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
683 j+=1
684 write_to(i,"\nend\n")
685 return 0
687 def configure_ospf(doms=domains):
688 for dom in doms:
689 if domain_types[domains.index(dom)] == 'quagga':
690 write_to(dom,"\n\nconf t\nrouter ospf\nnetwork 192.168.0.0/16 area 0\nend\n")
691 else:
692 write_to(dom,"\n\nena\nconf t\nrouter ospf 1\nnetwork 192.168.0.0 0.0.255.255 area 0\nend\n")
693 return 0
695 def configure_hostname(doms=domains):
696 for dom in doms:
697 if domain_types[domains.index(dom)] == 'quagga':
698 write_to(dom,"\n\nconf t\nhostname %s\nend\n" % dom)
699 else:
700 write_to(dom,"\n\nena\nconf t\nhostname %s\nend\n" % dom)
701 return 0
703 def configure_logging_synchronous(doms=domains):
704 for dom in domains:
705 if domain_types[domains.index(dom)] == 'quagga':
706 0
707 else:
708 write_to(dom,"\n\nena\nconf t\nline console 0\nlogging synchronous\nend\n")
709 return 0
711 def configure_exec_timeout_0(doms=domains):
712 for dom in domains:
713 if domain_types[domains.index(dom)] == 'quagga':
714 0
715 else:
716 write_to(dom,"\n\nena\nconf t\nline console 0\nexec-timeout 0\nend\n")
717 return 0
719 def configure_no_cdp_log_mismatch_duplex(doms=domains):
720 for dom in filter_by_type(domains,'dynamips'):
721 write_to(dom,"\n\nena\nconf t\nno cdp log mismatch duplex\nend\n")
723 def configure_save(doms=domains):
724 write_to(doms,"\nwr\n")
726 def configure_root(doms=domains):
727 write_to(doms,"root\n")
729 #-----------------------------------------------------------------------
732 def add_domain(name,type):
733 domains.append(name)
734 domain_types.append(type)
736 def brake_link(domain,bridge):
737 broken_links.append([domain,bridge])
739 wt_timeout=0.5
740 def write_to(screen,string,return_to_screen=""):
741 """
742 write_to(screen,string):
744 Type *string* to the specified screen(s).
745 Screen may be specified with the number *screen*,
746 with array of numbers,
747 with array of names.
749 """
750 screen_numbers=[] # number of the screens to write to
751 if type(screen) == list:
752 screen_numbers=map(lambda x: domains.index(x)+1, screen)
753 elif type(screen) == int:
754 screen_numbers=[screen]
755 else:
756 screen_numbers=[domains.index(screen)+1]
758 for screen_number in screen_numbers:
759 run_command("screen -X select "+str(screen_number))
760 time.sleep(wt_timeout)
761 for line in string.splitlines():
762 f=open('/tmp/xentaurbuf', 'w')
763 f.write(line+"\n")
764 f.close()
765 run_command("screen -X readreg p /tmp/xentaurbuf")
766 time.sleep(wt_timeout)
767 run_command("nohup screen -X paste p >& /dev/null")
768 time.sleep(wt_timeout)
770 if return_to_screen != "":
771 run_command("screen -X select %s" % (return_to_screen))
772 time.sleep(wt_timeout)
774 def filter_by_type(doms,type):
775 """
776 filter_by_type(doms,type)
778 Return only domains of *doms* that have specified *type*
779 """
780 return filter(lambda x: domain_types[domains.index(x)]==type,domains)
782 #-----------------------------------------------------------------------
784 cisco_fa01_up="""
785 ena
786 conf t
787 int fa0/0
788 duplex half
789 no shutdown
790 exit
791 int fa1/0
792 duplex half
793 no shutdown
794 exit
795 exit
796 exit
797 """
799 cisco_set_ip_on_int="""
800 interface fa%s/0
801 no ip address
802 ip address %s 255.255.255.0
803 exit
804 """
806 nodes=domains
808 create_objects()
811 if len(sys.argv) == 2:
812 if sys.argv[1] == 'start-all':
813 start_all()
814 elif sys.argv[1] == 'start-domains':
815 start_domains()
816 elif sys.argv[1] == 'start-bridges':
817 start_bridges()
818 elif sys.argv[1] == 'stop-all':
819 stop_all()
820 elif sys.argv[1] == 'stop-domains':
821 stop_domains()
822 elif sys.argv[1] == 'stop-bridges':
823 stop_bridges()
824 elif sys.argv[1] == 'restart-all':
825 restart_all()
826 elif sys.argv[1] == 'screen':
827 screen()
828 elif sys.argv[1] == 'graph':
829 graph()
830 elif sys.argv[1] == 'shell':
831 shell()
832 elif sys.argv[1] == 'info':
833 info()
834 else:
835 show_usage()
836 sys.exit(1)
837 elif len(sys.argv) == 3:
838 if sys.argv[1] == 'start':
839 start_domain(sys.argv[2])
840 elif sys.argv[1] == 'stop':
841 stop_domain(sys.argv[2])
842 elif sys.argv[1] == 'restart':
843 stop_domain(sys.argv[2])
844 start_domain(sys.argv[2])
845 else:
846 show_usage()
847 sys.exit(1)
848 else:
849 show_usage()
850 sys.exit(1)
852 sys.exit(0)