ia64/xen-unstable

view tools/python/xen/xm/main.py @ 1882:495ae087d703

bitkeeper revision 1.1108.1.13 (4100e3a6AM3nkMAOO2NrkuSXmz7H3w)

Set parameter for fbvt call.
author mjw@wray-m-3.hpl.hp.com
date Fri Jul 23 10:08:38 2004 +0000 (2004-07-23)
parents f26582ec895e
children dad2f070529a e59c333c2ba0
line source
1 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
2 """Grand unified management application for Xen.
3 """
4 import os
5 import os.path
6 import sys
7 from getopt import getopt
8 import socket
10 from xen.xend import PrettyPrint
11 from xen.xend import sxp
12 from xen.xend.XendClient import XendError, server
13 from xen.xend.XendClient import main as xend_client_main
14 from xen.xm import create, destroy, shutdown
16 class Prog:
17 """Base class for sub-programs.
18 """
20 """Program group it belongs to"""
21 group = 'all'
22 """Program name."""
23 name = '??'
24 """Short program info."""
25 info = ''
27 def __init__(self, xm):
28 self.xm = xm
30 def err(self, msg):
31 self.xm.err(msg)
33 def help(self, args):
34 self.shortHelp(args)
36 def shortHelp(self, args):
37 print "%-14s %s" % (self.name, self.info)
39 def main(self, args):
40 """Program main entry point.
41 """
42 pass
45 class ProgUnknown(Prog):
47 name = 'unknown'
48 info = ''
50 def help(self, args):
51 self.xm.err("Unknown command: %s\nTry '%s help' for more information."
52 % (args[0], self.xm.name))
54 main = help
56 class Xm:
57 """Main application.
58 """
60 def __init__(self):
61 self.name = 'xm'
62 self.unknown = ProgUnknown(self)
63 self.progs = {}
65 def err(self, msg):
66 print >>sys.stderr, "Error:", msg
67 sys.exit(1)
69 def main(self, args):
70 try:
71 self.main_call(args)
72 except socket.error, ex:
73 print >>sys.stderr, ex
74 self.err("Error connecting to xend, is xend running?")
75 except XendError, ex:
76 self.err(str(ex))
78 def main_call(self, args):
79 """Main entry point. Dispatches to the progs.
80 """
81 self.name = args[0]
82 if len(args) < 2:
83 args.append('help')
84 help = self.helparg(args)
85 p = self.getprog(args[1], self.unknown)
86 if help or len(args) < 2:
87 p.help(args[1:])
88 else:
89 p.main(args[1:])
91 def helparg(self, args):
92 for a in args:
93 if a in ['-h', '--help']:
94 return 1
95 return 0
97 def prog(self, pklass):
98 """Add a sub-program.
100 pklass program class (Prog subclass)
101 """
102 p = pklass(self)
103 self.progs[p.name] = p
104 return p
106 def getprog(self, name, val=None):
107 """Get a sub-program.
108 name Name of the sub-program (or optionally, an unambiguous
109 prefix of its name)
110 val Default return value if no (unique) match is found
111 """
113 match = None
114 for progname in self.progs.keys():
115 if progname == name:
116 match = progname
117 break
118 if progname.startswith(name):
119 if not match:
120 match = progname
121 else:
122 return val # name is ambiguous - bail out
124 return self.progs.get(match, val)
126 def proglist(self):
127 """Get a list of sub-programs, ordered by group.
128 """
129 groups = {}
130 for p in self.progs.values():
131 l = groups.get(p.group, [])
132 l.append(p)
133 groups[p.group] = l
134 kl = groups.keys()
135 kl.sort()
136 pl = []
137 for k in kl:
138 l = groups[k]
139 l.sort()
140 pl += l
141 return pl
143 # Create the application object, then add the sub-program classes.
144 xm = Xm()
146 class ProgHelp(Prog):
148 name = "help"
149 info = "Print help."
151 def help(self, args):
152 if len(args) == 2:
153 name = args[1]
154 p = self.xm.getprog(name)
155 if p:
156 p.help(args[1:])
157 else:
158 print '%s: Unknown command: %s' % (self.name, name)
159 else:
160 for p in self.xm.proglist():
161 p.shortHelp(args)
162 print "\nTry '%s help CMD' for help on CMD" % self.xm.name
164 main = help
166 xm.prog(ProgHelp)
168 class ProgCreate(Prog):
170 group = 'domain'
171 name = "create"
172 info = """Create a domain."""
174 def help(self, args):
175 create.main([args[0], '-h'])
177 def main(self, args):
178 create.main(args)
180 xm.prog(ProgCreate)
182 class ProgSave(Prog):
183 group = 'domain'
184 name = "save"
185 info = """Save domain state (and config) to file."""
187 def help(self, args):
188 print args[0], "DOM FILE"
189 print """\nSave domain with id DOM to FILE."""
191 def main(self, args):
192 if len(args) < 3: self.err("%s: Missing arguments" % args[0])
193 dom = args[1]
194 savefile = os.path.abspath(args[2])
195 server.xend_domain_save(dom, savefile)
197 xm.prog(ProgSave)
199 class ProgRestore(Prog):
200 group = 'domain'
201 name = "restore"
202 info = """Create a domain from a saved state."""
204 def help(self, args):
205 print args[0], "FILE [CONFIG]"
206 print "\nRestore a domain from FILE using configuration CONFIG."
208 def main(self, help, args):
209 if len(args) < 2: self.err("%s: Missing arguments" % args[0])
210 savefile = os.path.abspath(args[1])
211 if len(args) >= 3:
212 configfile = os.path.abspath(args[2])
213 else:
214 configfile = None
215 info = server.xend_domain_restore(savefile, configfile)
216 PrettyPrint.prettyprint(info)
218 xm.prog(ProgRestore)
220 class ProgList(Prog):
221 group = 'domain'
222 name = "list"
223 info = """List info about domains."""
225 short_options = 'l'
226 long_options = ['long']
228 def help(self, args):
229 if help:
230 print args[0], '[options] [DOM...]'
231 print """\nGet information about domains.
232 Either all domains or the domains given.
234 -l, --long Get more detailed information.
235 """
236 return
238 def main(self, args):
239 use_long = 0
240 (options, params) = getopt(args[1:],
241 self.short_options,
242 self.long_options)
243 n = len(params)
244 for (k, v) in options:
245 if k in ['-l', '--long']:
246 use_long = 1
248 if n == 0:
249 doms = map(int, server.xend_domains())
250 doms.sort()
251 else:
252 doms = map(int, params)
254 if use_long:
255 self.long_list(doms)
256 else:
257 self.brief_list(doms)
259 def brief_list(self, doms):
260 print 'Dom Name Mem(MB) CPU State Time(s)'
261 for dom in doms:
262 info = server.xend_domain(dom)
263 d = {}
264 d['dom'] = int(dom)
265 d['name'] = sxp.child_value(info, 'name', '??')
266 d['mem'] = int(sxp.child_value(info, 'memory', '0'))
267 d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
268 d['state'] = sxp.child_value(info, 'state', '??')
269 d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
270 print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f" % d)
272 def long_list(self, doms):
273 for dom in doms:
274 info = server.xend_domain(dom)
275 print '\nDomain %d' % dom
276 PrettyPrint.prettyprint(info)
278 xm.prog(ProgList)
280 class ProgDestroy(Prog):
281 group = 'domain'
282 name = "destroy"
283 info = """Terminate a domain immediately."""
285 def help(self, args):
286 destroy.main([args[0], '-h'])
288 def main(self, args):
289 destroy.main(args)
291 xm.prog(ProgDestroy)
293 class ProgShutdown(Prog):
294 group = 'domain'
295 name = "shutdown"
296 info = """Shutdown a domain."""
298 def help(self, args):
299 shutdown.main([args[0], '-h'])
301 def main(self, args):
302 shutdown.main(args)
304 xm.prog(ProgShutdown)
306 class ProgPause(Prog):
307 group = 'domain'
308 name = "pause"
309 info = """Pause execution of a domain."""
311 def help(self, args):
312 print args[0], 'DOM'
313 print '\nPause execution of domain DOM.'
315 def main(self, args):
316 if len(args) < 2: self.err("%s: Missing domain" % args[0])
317 dom = args[1]
318 server.xend_domain_pause(dom)
320 xm.prog(ProgPause)
322 class ProgUnpause(Prog):
323 group = 'domain'
324 name = "unpause"
325 info = """Unpause a paused domain."""
327 def help(self, args):
328 print args[0], 'DOM'
329 print '\nUnpause execution of domain DOM.'
331 def main(self, args):
332 if len(args) < 2: self.err("%s: Missing domain" % args[0])
333 dom = args[1]
334 server.xend_domain_unpause(dom)
336 xm.prog(ProgUnpause)
338 class ProgPincpu(Prog):
339 group = 'domain'
340 name = "pincpu"
341 info = """Pin a domain to a cpu. """
343 def help(self, args):
344 print args[0],'DOM CPU'
345 print '\nPin domain DOM to cpu CPU.'
347 def main(self, args):
348 if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
349 v = map(int, args[1:3])
350 server.xend_domain_pincpu(*v)
352 xm.prog(ProgPincpu)
354 class ProgBvt(Prog):
355 group = 'scheduler'
356 name = "bvt"
357 info = """Set BVT scheduler parameters."""
359 def help(self, args):
360 print args[0], "DOM MCUADV WARP WARPL WARPU"
361 print '\nSet Borrowed Virtual Time scheduler parameters.'
363 def main(self, args):
364 if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0])
365 v = map(int, args[1:6])
366 server.xend_domain_cpu_bvt_set(*v)
368 xm.prog(ProgBvt)
370 class ProgBvtslice(Prog):
371 group = 'scheduler'
372 name = "bvt_ctxallow"
373 info = """Set the BVT scheduler context switch allowance."""
375 def help(self, args):
376 print args[0], 'CTX_ALLOW'
377 print '\nSet Borrowed Virtual Time scheduler context switch allowance.'
379 def main(self, args):
380 if len(args) < 2: self.err('%s: Missing context switch allowance'
381 % args[0])
382 slice = int(args[1])
383 server.xend_node_cpu_bvt_slice_set(slice)
385 xm.prog(ProgBvtslice)
387 class ProgFbvt(Prog):
388 group = 'scheduler'
389 name = "fbvt"
390 info = """Set FBVT scheduler parameters."""
392 def help(self, args):
393 print args[0], "DOM MCUADV WARP WARPL WARPU"
394 print '\nSet Fair Borrowed Virtual Time scheduler parameters.'
396 def main(self, args):
397 if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0])
398 v = map(int, args[1:6])
399 server.xend_domain_cpu_fbvt_set(*v)
401 xm.prog(ProgFbvt)
403 class ProgFbvtslice(Prog):
404 group = 'scheduler'
405 name = "fbvt_ctxallow"
406 info = """Set the FBVT scheduler context switch allowance."""
408 def help(self, args):
409 print args[0], 'CTX_ALLOW'
410 print '\nSet Fair Borrowed Virtual Time scheduler context switch allowance.'
412 def main(self, args):
413 if len(args) < 2: self.err('%s: Missing context switch allowance.'
414 % args[0])
415 ctx_allow = int(args[1])
416 server.xend_node_cpu_fbvt_slice_set(ctx_allow)
418 xm.prog(ProgFbvtslice)
421 class ProgAtropos(Prog):
422 group = 'scheduler'
423 name= "atropos"
424 info = """Set atropos parameters."""
426 def help(self, args):
427 print args[0], "DOM PERIOD SLICE LATENCY XTRATIME"
428 print "\nSet atropos parameters."
430 def main(self, args):
431 if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
432 v = map(int, args[1:5])
433 server.xend_domain_cpu_atropos_set(*v)
435 xm.prog(ProgAtropos)
437 class ProgRrobin(Prog):
438 group = 'scheduler'
439 name = "rrobin"
440 info = """Set round robin slice."""
442 def help(self, args):
443 print args[0], "SLICE"
444 print "\nSet round robin scheduler slice."
446 def main(self, args):
447 if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
448 rrslice = int(args[1])
449 server.xend_node_rrobin_set(rrslice)
451 xm.prog(ProgRrobin)
453 class ProgInfo(Prog):
454 group = 'host'
455 name = "info"
456 info = """Get information about the xen host."""
458 def main(self, args):
459 info = server.xend_node()
460 for x in info[1:]:
461 print "%-23s:" % x[0], x[1]
463 xm.prog(ProgInfo)
465 class ProgConsoles(Prog):
466 group = 'console'
467 name = "consoles"
468 info = """Get information about domain consoles."""
470 def main(self, args):
471 l = server.xend_consoles()
472 print "Dom Port Id"
473 for x in l:
474 info = server.xend_console(x)
475 d = {}
476 d['dom'] = sxp.child(info, 'dst', ['dst', '?', '?'])[1]
477 d['port'] = sxp.child_value(info, 'port', '?')
478 d['id'] = sxp.child_value(info, 'id', '?')
479 print "%(dom)3s %(port)4s %(id)3s" % d
481 xm.prog(ProgConsoles)
483 class ProgConsole(Prog):
484 group = 'console'
485 name = "console"
486 info = """Open a console to a domain."""
488 def help(self, args):
489 print "console DOM"
490 print "\nOpen a console to domain DOM."
492 def main(self, args):
493 if len(args) < 2: self.err("%s: Missing domain" % args[0])
494 dom = args[1]
495 info = server.xend_domain(dom)
496 console = sxp.child(info, "console")
497 if not console:
498 self.err("No console information")
499 port = sxp.child_value(console, "port")
500 from xen.util import console_client
501 console_client.connect("localhost", int(port))
503 xm.prog(ProgConsole)
505 class ProgCall(Prog):
506 name = "call"
507 info = "Call xend api functions."
509 def help (self, args):
510 print "call fn argss..."
511 print """
512 Call a xend HTTP API function. The leading 'xend_' on the function
513 can be omitted. See xen.xend.XendClient for the API functions.
514 """
516 def main(self, args):
517 xend_client_main(args)
519 xm.prog(ProgCall)
521 class ProgDmesg(Prog):
522 group = 'host'
523 name = "dmesg"
524 info = """Print Xen boot output."""
526 def main(self, args):
527 print server.xend_dmesg()[1]
529 xm.prog(ProgDmesg)
531 def main(args):
532 xm.main(args)