xentaur
view xentaur.py @ 64:baf0c3300c19
update tags
author | convert-repo |
---|---|
date | Sun Jun 29 09:03:52 2008 +0000 (2008-06-29) |
parents | e838c1223b89 |
children | cf823d27b029 |
line source
1 #!/usr/bin/python
2 # vim: set fileencoding=utf-8 :
4 import sys,os,time
6 xentaur_path=os.environ['HOME']+"/xentaur"
8 sys.path.append('/etc/xen')
9 sys.path.append(xentaur_path)
10 sys.path.append('.')
12 #network='snrs_ipsec_rsa_1'
13 node_object={}
14 link_object={}
15 bridge_object={}
17 network='openvpnbridge'
18 domain='debian1'
20 #network='snrs'
21 #domain='dyn1'
22 from xendomain import *
24 bridges_turned_down=[]
26 from IPython.Shell import IPShellEmbed
29 screenrc=os.environ['HOME']+"/.screenrc_xentaur"
30 path_shapes='/xen/xentaur/shapes'
32 def run(program, *args):
33 pid = os.fork()
34 if not pid:
35 os.execvp(program, (program,) + args)
36 return os.wait()[0]
38 def run_command(line):
39 #cmds=line.split()
40 #run(cmds[0],*cmds[1:])
41 run("/bin/sh", "-c", line)
43 def run_command_return_stdout(line):
44 p = os.popen(line)
45 output = p.read()
46 p.close()
47 return output
49 ################################################################################
50 #Xentaur command-line commands
52 ## Start
54 def start_bridges():
55 unbound_bridges=set(bridges)-set(real_bridges)
56 script=""
57 script="\n".join(map(lambda x: "sudo brctl show | awk '{print $1}' | grep -qx "+x+" || sudo brctl addbr "+x, unbound_bridges))
58 script+="\n"+"\n".join(map(lambda x: "sudo brctl stp "+x+" off", unbound_bridges))
59 script+="\n"+"\n".join(map(lambda x: "sudo ip link set "+x+" up", unbound_bridges))
61 print """#!/bin/sh
62 # create unbound bridges
63 %s
64 """ % (script)
66 def start_domain(domain):
67 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"
69 def start_domains(doms=domains):
70 for domain in doms:
71 if not domain in real_nodes:
72 start_domain(domain)
74 def start_all():
75 graph()
76 screen()
77 start_bridges()
78 start_domains()
80 ## Stop
82 def stop_domain(domain,wait=0):
83 if wait:
84 print "sudo xm shutdown -w "+domain
85 else:
86 print "sudo xm shutdown "+domain
88 def stop_domains(doms=domains, wait=0):
89 for domain in doms:
90 if not domain in real_nodes:
91 stop_domain(domain,wait)
93 def stop_bridges():
94 ###FIXME###
95 return 0
97 def stop_all(wait=0):
98 stop_domains(domains, wait)
99 stop_bridges()
101 def restart_all():
102 stop_all(1)
103 start_all()
105 ####################################################
107 def create_objects():
108 create_node_objects()
109 create_bridge_objects()
110 create_link_objects()
112 def create_node_objects():
113 for dom in domains:
114 node_object[dom]=Node(dom)
116 def create_bridge_objects():
117 for bridge in bridges:
118 bridge_object[bridge]=Bridge(bridge)
120 def create_link_objects():
122 for node, bridges_raw in vbridges_table.iteritems():
123 interface=0
124 j=0
125 for this_bridge in bridges_raw:
126 int_label=""
127 if this_bridge.find(':') != -1:
128 res = this_bridge.split(':')
129 this_bridge= res[0]
130 bridges_raw[j] = this_bridge
131 int_label = res[1]
132 if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
133 name="%s %s %s" % (node,interface,this_bridge)
134 link_object[name]=Link(name,node,interface,this_bridge,int_label)
135 interface+=1
136 vbridges_table[node]=bridges_raw
138 for node, bridges_raw in bridge_bridge_table.iteritems():
139 interface=0
140 j=0
141 for this_bridge in bridges_raw:
142 int_label=""
143 if this_bridge.find(':') != -1:
144 res = this_bridge.split(':')
145 this_bridge= res[2]
146 bridges_raw[j] = this_bridge
147 int_label = res[1]
148 if not [ node, bridges_raw.index(this_bridge), this_bridge ] in temporary_links:
149 name="%s %s %s" % (node,interface,this_bridge)
150 link_object[name]=Link(name,node,interface,this_bridge,int_label)
151 interface+=1
152 bridge_bridge_table[node]=bridges_raw
154 for node,interface,bridge in temporary_links:
155 name="%s %s %s" % (node,interface,bridge)
156 link_object[name]=Link(name,node,interface,this_bridge)
158 for node,interface,bridge in broken_links:
159 name="%s %s %s" % (node,interface,bridge)
160 link_object[name]=Link(name,node,interface,this_bridge)
163 ####################################################
165 def screen():
166 wait_seconds=1
167 screens=[]
168 for domain in domains:
169 screens.append("screen -t %s %s sh -c 'while true; do %s ; echo Retrying in %s secods...; sleep %s ; clear; done'" %
170 (domain,domains.index(domain)+1,node_object[domain].console_string(),wait_seconds,wait_seconds))
171 screenlist="\n".join(screens)
173 hardstatus='hardstatus string "%{rk}Xentaur%{bk}@%H %{gk}%c %{yk}%d.%m %{wk}%?%-Lw%?%{bw}%n*%f%t%?(%u)%?%{wk}%?%+Lw%?"'
175 f=open(screenrc, "w");
176 f.write("""
177 hardstatus on
178 hardstatus alwayslastline
179 %s
181 screen -t console 0 sh -c 'while true; do cd %s; ./xentaur.py shell ; echo Retrying in %s secods...; sleep %s ; clear; done'
182 #screen -t xentaur - sh -c 'while true; do bash ; echo Retrying in %s secods...; sleep %s ; clear; done'
183 %s
184 """ % (hardstatus,xentaur_path,wait_seconds,wait_seconds,wait_seconds,wait_seconds,screenlist))
185 f.close()
186 print "# GNU Screen config file is written to: %s" % screenrc
188 def graph():
189 nodelist=""
190 bridgelist=""
191 linklist=""
192 physicallist=""
193 networklist=""
195 nodelist=";\n ".join(map(lambda node: node_object[node].graphviz_string(),nodes))
196 if nodelist: nodelist += ";"
197 bridgelist=";\n ".join(map(lambda bridge: bridge_object[bridge].graphviz_string(),bridges))
198 if bridgelist: bridgelist += ";"
199 linklist=";\n ".join(map(lambda link: link_object[link].graphviz_string(),link_object.keys()))
200 if linklist: linklist += ";"
202 f = open(network+".dot", "w");
203 f.write ("""
204 graph G {
205 edge [len=1.25];
206 splines=true;
207 // nodes
208 %s
210 // bridges
211 %s
213 // physical
214 node [shape=rectangle,color=blue];
215 %s
217 // networks (not bridges, not physical)
218 node [shape=rectangle,color=green];
219 %s
221 // links (between nodes and bridges)
222 %s
224 };
225 """ % (nodelist, bridgelist, physicallist, networklist, linklist))
226 f.close()
227 run_command("neato -Tpng -o %s.png %s.dot "%(network,network))
228 run_command("neato -Tjpg -o %s.jpg %s.dot "%(network,network))
229 run_command("neato -Tsvg -o %s.svg %s.dot "%(network,network))
230 run_command("neato -Tcmapx -o %s.cmapx -NURL=http://google.com %s.dot "%(network,network))
231 print "# Network map is written to files: %s.{png,svg,jpg,dot}" % network
233 def autoredraw():
234 graph()
236 def shell():
237 autoredraw()
238 ipshell = IPShellEmbed()
239 ipshell()
241 def version():
242 print """
243 Xentaur 0.1-PRE
245 ,--,
246 _ ___/ /\\|
247 ,;`( )__, ) ~
248 // .// '--;
249 ' / \ |
251 """
252 # print "Xentaur 0.1-PRE"
253 # print "(Godzilla-mutant) _"
254 # print " / * \\"
255 # print " / .-"
256 # print " / |"
257 # print " | \\ \\\\ \\"
258 # print " _ -------| \\ \\\\ \\"
259 # print " / / \\_\\ -"
260 # print "/ |\\ | |"
261 # print "| | \\ .-----. | \\ |"
262 # print " | / \\ \\ \\ \\"
263 # print " \\/|.\\ \\ \\ \\ \\"
264 # print " \\| - . \\_\\ \\_\\"
265 # print "-----------------------------------------------"
268 def info():
269 version()
271 print "Network name: ", network
272 print "-----------------------------------------------"
273 print
274 print "Nodes: ", len(domains)
275 print " * virtual nodes: ", len(domains)-len(real_nodes)
276 print " * real nodes:", len(real_nodes)
277 print
278 print "Bridges:", len(bridges)
279 print " * virtual bridges:", len(bridges)-len(real_bridges)-len(cross_bridges)
280 print " * real switches:", len(real_bridges)
281 print " * direct links:", len(cross_bridges)
283 def show_usage():
284 print """Usage:
285 xentaur <command> [<argument>]
287 Commands:
288 start-all -- start bridges and domains
289 start-domains -- start domains only
290 start-bridges -- start bridges only
291 stop-all -- stop bridges and domains
292 stop-domains -- stop domains only
293 stop-bridges -- stop bridges only (domains have to be stopped already)
294 restart-all -- restart bridges and domains
296 start <domain> -- start the <domain>
297 stop <domain> -- stop the <domain>
299 graph -- generate network scheme (result is in <network>.{png,jpg,svg})
300 screen -- generate GNU Screen config file (~/.screenrc_xentaur)
301 shell -- run Xentaur shell
303 """
305 def save():
306 print "network =", xen_config_name
307 print "domains =", domains
308 print "domain_types =", domain_types
309 print "bridges =", bridges
310 print "vbridges_table =", vbridges_table
311 print "hidden_bridges =", hidden_bridges
312 print "broken_links =", broken_links
313 print "temporary_links =", temporary_links
314 print "bridges_turned_down =", bridges_turned_down
316 #-----------------------------------------------------------------------
317 # CLASSES
319 class Bridge:
320 def __init__ (self,name):
321 self.name=name
322 def up(self):
323 bridge_up(self.name)
324 def down(self):
325 bridge_down(self.name)
326 def show(self):
327 show_bridge(self.name)
328 def dump_start(self,filter=""):
329 dump_start(self.name,filter)
331 def is_hidden(self):
332 return self.name in hidden_bridges
333 def is_real(self):
334 return self.name in real_bridges
335 def is_turned_down(self):
336 return self.name in bridges_turned_down
337 def is_cross(self):
338 return self.name in cross_bridges
340 def graphviz_string(self):
341 if self.is_hidden():
342 return "//"
343 elif self.is_cross():
344 return "%s [shape=circle,height=0.03,color=black,fillcolor=black,style=filled,label=\"\"]" % (self.name)
345 elif self.is_real():
346 return "%s [color=white,shape=none,shapefile=\"%s/all/real_switch.png\"]" % (self.name, path_shapes)
347 elif self.is_turned_down():
348 return "%s [color=white,shape=none,shapefile=\"%s/all/switch_turned_down.png\"]" % (self.name, path_shapes)
349 else:
350 return "%s [color=white,shape=none,shapefile=\"%s/all/switch.png\"]" % (self.name, path_shapes)
353 class Node:
354 def __init__ (self,name):
355 self.name=name
356 self.type=domain_types[domains.index(name)]
357 def start(self):
358 return ""
359 def stop(self):
360 return ""
361 def start_commandline(self):
362 return ""
363 def get_domain_id(self):
364 return get_domain_id(self.name)
365 def graphviz_string(self):
366 return self.name+" [color=white,shape=plaintext,label=\" "+self.name+"\",shapefile=\""+path_shapes+"/all/"+\
367 domain_types[domains.index(self.name)]+".png\",fontcolor=black,fontsize=16,target=\"http://google.com\"]"
368 def console_string(self):
369 if self.type in [ 'quagga', 'xenomips', 'freebsd', 'linux' ]:
370 return "sudo xm console "+self.name
371 elif self.name in real_bridges or self.name in real_nodes:
372 return "echo Press enter to connect; read line; "+connection_table[self.name]
375 class Link:
376 def __init__ (self,name,node,interface,bridge,label=""):
377 self.name=name
378 self.node=node
379 self.interface=interface
380 self.bridge=bridge
381 self.label=label
383 def is_temporary(self):
384 return [self.node,self.interface,self.bridge] in temporary_links
386 def is_broken(self):
387 return ([self.node,self.interface,self.bridge] in broken_links)
389 def is_hidden(self):
390 return self.bridge in hidden_bridges
392 def graphviz_string(self):
393 if self.is_hidden():
394 return "//"
395 if self.is_temporary():
396 return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",color=blue,len=10,w=5,weight=5]"
397 if self.is_broken():
398 return self.node+" -- "+self.bridge+" [taillabel=\"fa"+str(self.interface)+"/0\",style=dashed]"
400 ip="\\n.%s.%s" % (bridges.index(self.bridge)+1, domains.index(self.node)+1)
401 if domain_types[domains.index(self.node)] == 'xenomips':
402 int_name="fa"+str(self.interface)+"/0"
403 else:
404 int_name="eth"+str(self.interface)
405 if self.label != "":
406 int_name = self.label
407 return self.node+" -- "+self.bridge+" [taillabel=\""+int_name+ip+"\",fontsize=14,fontname=fixed]"
410 #-----------------------------------------------------------------------
411 # DOMAINS
413 def get_domain_id(domain):
414 return run_command_return_stdout("sudo xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain).rstrip("\n")
417 #-----------------------------------------------------------------------
418 # BRIDGES and IFACES
420 def bridge_down(bridge):
421 """
422 Turn the bridge <bridge> down
423 """
424 if bridge in real_bridges:
425 print "Bridge %s is a real bridge" % (bridge)
426 return -1
427 if bridge in bridges_turned_down:
428 print "Bridge %s is turned down already" % (bridge)
429 else:
430 bridges_turned_down.append(bridge)
431 run_command("sudo ip link set %s down" % bridge)
432 autoredraw()
434 def bridge_up(bridge):
435 """
436 Turn the bridge <bridge> up
437 """
438 if bridge in real_bridges:
439 print "Bridge %s is a real bridge" % (bridge)
440 return -1
441 if not (bridge in bridges_turned_down):
442 print "Bridge %s is turned up already" % (bridge)
443 else:
444 bridges_turned_down.remove(bridge)
445 run_command("sudo ip link set %s up" % bridge)
446 autoredraw()
448 def show_bridge(bridge):
449 """
450 Show the state of the bridge <bridge>
451 """
452 if bridge in real_bridges:
453 print "Bridge %s is a real bridge" % (bridge)
454 return -1
455 run_command("sudo ip link show %s" % bridge)
458 def int_disconnect(domain, int_number):
459 """
460 Disconnect the interface with the number <int_number>
461 of the domain <domain> from the bridge to which
462 it is connected
463 """
464 dom_id=get_domain_id(domain)
465 bridge=vbridges_table[domain][int_number]
466 if not bridge:
467 print "Interface %s of the %s domain is not connected" % (int_number, domain)
468 return 1
469 run_command("sudo brctl delif %s vif%s.%s" % (bridge, dom_id, int_number))
470 vbridges_table[domain][int_number]=''
471 if [ domain, int_number, bridge ] in temporary_links:
472 temporary_links.remove([ domain, int_number, bridge ])
473 else:
474 broken_links.append([ domain, int_number, bridge ])
475 autoredraw()
477 def int_connect(domain, int_number, bridge):
478 """
479 Connect the interface with the number <int_number>
480 of the domain <domain> to the bridge <bridge>
481 """
482 if bridge in real_bridges:
483 print "Bridge %s is a real bridge" % (bridge)
484 return -1
486 dom_id=get_domain_id(domain)
487 if vbridges_table[domain][int_number]:
488 print "Interface %s of the %s domain is connected already to the %s bridge" % (int_number, domain, vbridges_table[domain][int_number])
489 return 1
490 run_command("sudo brctl addif %s vif%s.%s" % (bridge, dom_id, int_number))
491 vbridges_table[domain][int_number]=bridge
492 if [ domain, int_number, bridge ] in broken_links:
493 broken_links.remove([ domain, int_number, bridge ])
494 else:
495 temporary_links.append([ domain, int_number, bridge ])
496 autoredraw()
498 def int_reconnect(domain, int_number, bridge):
499 """
500 Reconnect the interface with the number <int_number>
501 of the domain <domain> from the bridge to which
502 it is connected to the bridge <bridge>
503 """
504 if bridge in real_bridges:
505 print "Bridge %s is a real bridge" % (bridge)
506 return -1
508 int_disconnect(domain, int_number)
509 int_connect(domain, int_number, bridge)
511 def show_int(domain, int_number):
512 """
513 Show information about the interface <int_nuber>
514 of the domain <domain>
515 """
516 return vbridges_table[domain][int_number]
519 def dump_start(bridge, filter=""):
520 if bridge in real_bridges:
521 print "Bridge %s is a real bridge" % (bridge)
522 return -1
523 try:
524 print "Writing dump... (press Ctrl-C to stop)"
525 run_command("sudo tcpdump -w xentaur.dump -i %s %s > /dev/null 2>&1 " % (bridge,filter))
526 except:
527 print "Done.\n Dump is written to xentaur.dump"
528 return 0
530 def dump_stop():
531 return 0
534 #-----------------------------------------------------------------------
535 # CONFIGURATION TEMPLATES
538 def configure_ip_addresses(doms=domains):
540 cisco_set_ip_on_int="""
541 \n\n\n
542 int fa%s/0
543 no ip address
544 ip address %s 255.255.255.0
545 no shutdown
546 exit
547 """
549 quagga_set_ip_on_int="""
550 int eth%s
551 no ip address
552 ip address %s/24
553 no shutdown
554 exit
555 """
557 linux_set_ip_on_int="""
558 ifconfig eth%s %s netmask 255.255.255.0
559 """
561 for dom in doms:
562 i=domains.index(dom)+1
563 if domain_types[domains.index(dom)] == 'quagga':
564 command = quagga_set_ip_on_int
565 write_to(i,"\nconf t\n")
566 j=0
567 for br in vbridges_table[dom]:
568 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
569 j+=1
570 write_to(i,"\nend\n")
571 elif domain_types[domains.index(dom)] == 'linux':
572 command = linux_set_ip_on_int
573 j=0
574 for br in vbridges_table[dom]:
575 #write_to(i, command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)) )
576 print i, command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i))
577 j+=1
578 else:
579 command = cisco_set_ip_on_int
580 write_to(i,"\nena\nconf t\n")
581 j=0
582 for br in vbridges_table[dom]:
583 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
584 j+=1
585 write_to(i,"\nend\n")
586 return 0
588 def configure_no_ip_addresses(doms=domains):
590 cisco_set_ip_on_int="""
591 \n\n\n
592 int fa%s/0
593 no ip address %s 255.255.255.0
594 exit
595 """
597 quagga_set_ip_on_int="""
598 int eth%s
599 no ip address %s/24
600 exit
601 """
603 for dom in doms:
604 i=domains.index(dom)+1
605 if domain_types[domains.index(dom)] == 'quagga':
606 command = quagga_set_ip_on_int
607 write_to(i,"\nconf t\n")
608 j=0
609 for br in vbridges_table[dom]:
610 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
611 j+=1
612 write_to(i,"\nend\n")
613 else:
614 command = cisco_set_ip_on_int
615 write_to(i,"\nena\nconf t\n")
616 j=0
617 for br in vbridges_table[dom]:
618 write_to(i,command % (j, "192.168.%s.%s"%(bridges.index(br)+1,i)))
619 j+=1
620 write_to(i,"\nend\n")
621 return 0
623 def configure_ospf(doms=domains):
624 for dom in doms:
625 if domain_types[domains.index(dom)] == 'quagga':
626 write_to(dom,"\n\nconf t\nrouter ospf\nnetwork 192.168.0.0/16 area 0\nend\n")
627 else:
628 write_to(dom,"\n\nena\nconf t\nrouter ospf 1\nnetwork 192.168.0.0 0.0.255.255 area 0\nend\n")
629 return 0
631 def configure_hostname(doms=domains):
632 for dom in doms:
633 if domain_types[domains.index(dom)] == 'quagga':
634 write_to(dom,"\n\nconf t\nhostname %s\nend\n" % dom)
635 else:
636 write_to(dom,"\n\nena\nconf t\nhostname %s\nend\n" % dom)
637 return 0
639 def configure_logging_synchronous(doms=domains):
640 for dom in domains:
641 if domain_types[domains.index(dom)] == 'quagga':
642 0
643 else:
644 write_to(dom,"\n\nena\nconf t\nline console 0\nlogging synchronous\nend\n")
645 return 0
647 def configure_exec_timeout_0(doms=domains):
648 for dom in domains:
649 if domain_types[domains.index(dom)] == 'quagga':
650 0
651 else:
652 write_to(dom,"\n\nena\nconf t\nline console 0\nexec-timeout 0\nend\n")
653 return 0
655 def configure_no_cdp_log_mismatch_duplex(doms=domains):
656 for dom in filter_by_type(domains,'xenomips'):
657 write_to(dom,"\n\nena\nconf t\nno cdp log mismatch duplex\nend\n")
659 def configure_save(doms=domains):
660 write_to(doms,"\nwr\n")
662 def configure_root(doms=domains):
663 write_to(doms,"root\n")
665 #-----------------------------------------------------------------------
668 def add_domain(name,type):
669 domains.append(name)
670 domain_types.append(type)
672 def brake_link(domain,bridge):
673 broken_links.append([domain,bridge])
675 wt_timeout=0.5
676 def write_to(screen,string,return_to_screen=""):
677 """
678 write_to(screen,string):
680 Type *string* to the specified screen(s).
681 Screen may be specified with the number *screen*,
682 with array of numbers,
683 with array of names.
685 """
686 screen_numbers=[] # number of the screens to write to
687 if type(screen) == list:
688 screen_numbers=map(lambda x: domains.index(x)+1, screen)
689 elif type(screen) == int:
690 screen_numbers=[screen]
691 else:
692 screen_numbers=[domains.index(screen)+1]
694 for screen_number in screen_numbers:
695 run_command("screen -X select "+str(screen_number))
696 time.sleep(wt_timeout)
697 for line in string.splitlines():
698 f=open('/tmp/xentaurbuf', 'w')
699 f.write(line+"\n")
700 f.close()
701 run_command("screen -X readreg p /tmp/xentaurbuf")
702 time.sleep(wt_timeout)
703 run_command("nohup screen -X paste p >& /dev/null")
704 time.sleep(wt_timeout)
706 if return_to_screen != "":
707 run_command("screen -X select %s" % (return_to_screen))
708 time.sleep(wt_timeout)
710 def filter_by_type(doms,type):
711 """
712 filter_by_type(doms,type)
714 Return only domains of *doms* that have specified *type*
715 """
716 return filter(lambda x: domain_types[domains.index(x)]==type,domains)
718 #-----------------------------------------------------------------------
720 cisco_fa01_up="""
721 ena
722 conf t
723 int fa0/0
724 duplex half
725 no shutdown
726 exit
727 int fa1/0
728 duplex half
729 no shutdown
730 exit
731 exit
732 exit
733 """
735 cisco_set_ip_on_int="""
736 interface fa%s/0
737 no ip address
738 ip address %s 255.255.255.0
739 exit
740 """
742 nodes=domains
744 create_objects()
747 if len(sys.argv) == 2:
748 if sys.argv[1] == 'start-all':
749 start_all()
750 elif sys.argv[1] == 'start-domains':
751 start_domains()
752 elif sys.argv[1] == 'start-bridges':
753 start_bridges()
754 elif sys.argv[1] == 'stop-all':
755 stop_all()
756 elif sys.argv[1] == 'stop-domains':
757 stop_domains()
758 elif sys.argv[1] == 'stop-bridges':
759 stop_bridges()
760 elif sys.argv[1] == 'restart-all':
761 restart_all()
762 elif sys.argv[1] == 'screen':
763 screen()
764 elif sys.argv[1] == 'graph':
765 graph()
766 elif sys.argv[1] == 'shell':
767 shell()
768 elif sys.argv[1] == 'info':
769 info()
770 else:
771 show_usage()
772 sys.exit(1)
773 elif len(sys.argv) == 3:
774 if sys.argv[1] == 'start':
775 start_domain(sys.argv[2])
776 elif sys.argv[1] == 'stop':
777 stop_domain(sys.argv[2])
778 elif sys.argv[1] == 'restart':
779 stop_domain(sys.argv[2])
780 start_domain(sys.argv[2])
781 else:
782 show_usage()
783 sys.exit(1)
784 else:
785 show_usage()
786 sys.exit(1)
788 sys.exit(0)