ia64/xen-unstable

view tools/python/xen/xm/main.py @ 18549:ddf62f696111

xm: Fix xm start -c / --vncviewer

In xm start the --vncviewer option has no effect, instead -c tries to
both connect to the console and start vncviewer. Additionally, to
start vncviewer it uses the domid variable which is only defined a few
lines later. Thus xm start -c doesn't work at all.

This patch fixes both problems.

Signed-off-by: Kevin Wolf <kwolf@suse.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Sep 25 13:07:43 2008 +0100 (2008-09-25)
parents 79459028af39
children 9404bcb6d32e
line source
1 # (C) Copyright IBM Corp. 2005
2 # Copyright (C) 2004 Mike Wray
3 # Copyright (c) 2005-2006 XenSource Ltd.
4 #
5 # Authors:
6 # Sean Dague <sean at dague dot net>
7 # Mike Wray <mike dot wray at hp dot com>
8 #
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of version 2.1 of the GNU Lesser General Public
11 # License as published by the Free Software Foundation.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 """Grand unified management application for Xen.
23 """
24 import atexit
25 import cmd
26 import os
27 import pprint
28 import shlex
29 import sys
30 import re
31 import getopt
32 import socket
33 import traceback
34 import xmlrpclib
35 import time
36 import datetime
37 from select import select
38 import xml.dom.minidom
39 from xen.util.blkif import blkdev_name_to_number
40 from xen.util import vscsi_util
41 from xen.util.pci import *
43 import warnings
44 warnings.filterwarnings('ignore', category=FutureWarning)
46 from xen.xend import PrettyPrint
47 from xen.xend import sxp
48 from xen.xend import XendClient
49 from xen.xend.XendConstants import *
51 from xen.xm.opts import OptionError, Opts, wrap, set_true
52 from xen.xm import console
53 from xen.util.xmlrpcclient import ServerProxy
54 import xen.util.xsm.xsm as security
55 from xen.util.xsm.xsm import XSMError
56 from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
58 import XenAPI
60 import xen.lowlevel.xc
61 xc = xen.lowlevel.xc.xc()
63 import inspect
64 from xen.xend import XendOptions
65 xoptions = XendOptions.instance()
67 import signal
68 signal.signal(signal.SIGINT, signal.SIG_DFL)
70 # getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
71 # getopt.getopt if gnu_getopt is not available. This will mean that options
72 # may only be specified before positional arguments.
73 if not hasattr(getopt, 'gnu_getopt'):
74 getopt.gnu_getopt = getopt.getopt
76 XM_CONFIG_FILE_ENVVAR = 'XM_CONFIG_FILE'
77 XM_CONFIG_FILE_DEFAULT = '/etc/xen/xm-config.xml'
79 # Supported types of server
80 SERVER_LEGACY_XMLRPC = 'LegacyXMLRPC'
81 SERVER_XEN_API = 'Xen-API'
83 # General help message
85 USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \
86 "Control, list, and manipulate Xen guest instances.\n"
88 USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \
89 'For more help on \'xm\' see the xm(1) man page.\n' \
90 'For more help on \'xm create\' see the xmdomain.cfg(5) '\
91 ' man page.\n'
93 # Help strings are indexed by subcommand name in this way:
94 # 'subcommand': (argstring, description)
96 SUBCOMMAND_HELP = {
97 # common commands
99 'shell' : ('', 'Launch an interactive shell.'),
101 'console' : ('[-q|--quiet] <Domain>',
102 'Attach to <Domain>\'s console.'),
103 'vncviewer' : ('[--[vncviewer-]autopass] <Domain>',
104 'Attach to <Domain>\'s VNC server.'),
105 'create' : ('<ConfigFile> [options] [vars]',
106 'Create a domain based on <ConfigFile>.'),
107 'destroy' : ('<Domain>',
108 'Terminate a domain immediately.'),
109 'help' : ('', 'Display this message.'),
110 'list' : ('[options] [Domain, ...]',
111 'List information about all/some domains.'),
112 'mem-max' : ('<Domain> <Mem>',
113 'Set the maximum amount reservation for a domain.'),
114 'mem-set' : ('<Domain> <Mem>',
115 'Set the current memory usage for a domain.'),
116 'migrate' : ('<Domain> <Host>',
117 'Migrate a domain to another machine.'),
118 'pause' : ('<Domain>', 'Pause execution of a domain.'),
119 'reboot' : ('<Domain> [-wa]', 'Reboot a domain.'),
120 'reset' : ('<Domain>', 'Reset a domain.'),
121 'restore' : ('<CheckpointFile> [-p]',
122 'Restore a domain from a saved state.'),
123 'save' : ('[-c] <Domain> <CheckpointFile>',
124 'Save a domain state to restore later.'),
125 'shutdown' : ('<Domain> [-waRH]', 'Shutdown a domain.'),
126 'top' : ('', 'Monitor a host and the domains in real time.'),
127 'unpause' : ('<Domain>', 'Unpause a paused domain.'),
128 'uptime' : ('[-s] [Domain, ...]',
129 'Print uptime for all/some domains.'),
131 # Life cycle xm commands
132 'new' : ('<ConfigFile> [options] [vars]',
133 'Adds a domain to Xend domain management'),
134 'delete' : ('<DomainName>',
135 'Remove a domain from Xend domain management.'),
136 'start' : ('<DomainName>', 'Start a Xend managed domain'),
137 'resume' : ('<DomainName>', 'Resume a Xend managed domain'),
138 'suspend' : ('<DomainName>', 'Suspend a Xend managed domain'),
140 # less used commands
142 'dmesg' : ('[-c|--clear]',
143 'Read and/or clear Xend\'s message buffer.'),
144 'domid' : ('<DomainName>', 'Convert a domain name to domain id.'),
145 'domname' : ('<DomId>', 'Convert a domain id to domain name.'),
146 'dump-core' : ('[-L|--live] [-C|--crash] [-R|--reset] <Domain> [Filename]',
147 'Dump core for a specific domain.'),
148 'info' : ('[-c|--config]', 'Get information about Xen host.'),
149 'log' : ('', 'Print Xend log'),
150 'rename' : ('<Domain> <NewDomainName>', 'Rename a domain.'),
151 'sched-sedf' : ('<Domain> [options]', 'Get/set EDF parameters.'),
152 'sched-credit': ('[-d <Domain> [-w[=WEIGHT]|-c[=CAP]]]',
153 'Get/set credit scheduler parameters.'),
154 'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
155 'debug-keys' : ('<Keys>', 'Send debug keys to Xen.'),
156 'trigger' : ('<Domain> <nmi|reset|init|s3resume> [<VCPU>]',
157 'Send a trigger to a domain.'),
158 'vcpu-list' : ('[Domain, ...]',
159 'List the VCPUs for all/some domains.'),
160 'vcpu-pin' : ('<Domain> <VCPU|all> <CPUs|all>',
161 'Set which CPUs a VCPU can use.'),
162 'vcpu-set' : ('<Domain> <vCPUs>',
163 'Set the number of active VCPUs for allowed for the'
164 ' domain.'),
166 # device commands
168 'block-attach' : ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
169 'Create a new virtual block device.'),
170 'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
171 'Change block device configuration'),
172 'block-detach' : ('<Domain> <DevId> [-f|--force]',
173 'Destroy a domain\'s virtual block device.'),
174 'block-list' : ('<Domain> [--long]',
175 'List virtual block devices for a domain.'),
176 'network-attach': ('<Domain> [type=<type>] [mac=<mac>] [bridge=<bridge>] '
177 '[ip=<ip>] [script=<script>] [backend=<BackDomain>] '
178 '[vifname=<name>] [rate=<rate>] [model=<model>]'
179 '[accel=<accel>]',
180 'Create a new virtual network device.'),
181 'network-detach': ('<Domain> <DevId> [-f|--force]',
182 'Destroy a domain\'s virtual network device.'),
183 'network-list' : ('<Domain> [--long]',
184 'List virtual network interfaces for a domain.'),
185 'vnet-create' : ('<ConfigFile>','Create a vnet from ConfigFile.'),
186 'vnet-delete' : ('<VnetId>', 'Delete a Vnet.'),
187 'vnet-list' : ('[-l|--long]', 'List Vnets.'),
188 'vtpm-list' : ('<Domain> [--long]', 'List virtual TPM devices.'),
189 'pci-attach' : ('<Domain> <domain:bus:slot.func> [virtual slot]',
190 'Insert a new pass-through pci device.'),
191 'pci-detach' : ('<Domain> <domain:bus:slot.func>',
192 'Remove a domain\'s pass-through pci device.'),
193 'pci-list' : ('<Domain>',
194 'List pass-through pci devices for a domain.'),
195 'pci-list-assignable-devices' : ('', 'List all the assignable pci devices'),
196 'scsi-attach' : ('<Domain> <PhysDevice> <VirtDevice> [BackDomain]',
197 'Attach a new SCSI device.'),
198 'scsi-detach' : ('<Domain> <VirtDevice>',
199 'Detach a specified SCSI device.'),
200 'scsi-list' : ('<Domain> [--long]',
201 'List all SCSI devices currently attached.'),
203 # security
205 'addlabel' : ('<label> {dom <ConfigFile>|res <resource>|mgt <managed domain>}\n'
206 ' [<policy>]',
207 'Add security label to domain.'),
208 'rmlabel' : ('{dom <ConfigFile>|res <Resource>|mgt<managed domain>}',
209 'Remove a security label from domain.'),
210 'getlabel' : ('{dom <ConfigFile>|res <Resource>|mgt <managed domain>}',
211 'Show security label for domain or resource.'),
212 'dry-run' : ('<ConfigFile>',
213 'Test if a domain can access its resources.'),
214 'resources' : ('', 'Show info for each labeled resource.'),
215 'dumppolicy' : ('', 'Print hypervisor ACM state information.'),
216 'setpolicy' : ('<policytype> <policyfile> [options]',
217 'Set the policy of the system.'),
218 'resetpolicy' : ('',
219 'Set the policy of the system to the default policy.'),
220 'getpolicy' : ('[options]', 'Get the policy of the system.'),
221 'labels' : ('[policy] [type=dom|res|any]',
222 'List <type> labels for (active) policy.'),
223 'serve' : ('', 'Proxy Xend XMLRPC over stdio.'),
224 }
226 SUBCOMMAND_OPTIONS = {
227 'sched-sedf': (
228 ('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'),
229 ('-s [MS]', '--slice[=MS]' ,
230 'Worst-case execution time(ms). (slice < period)'),
231 ('-l [MS]', '--latency[=MS]',
232 'Scaled period (ms) when domain performs heavy I/O'),
233 ('-e [FLAG]', '--extra[=FLAG]',
234 'Flag (0 or 1) controls if domain can run in extra time.'),
235 ('-w [FLOAT]', '--weight[=FLOAT]',
236 'CPU Period/slice (do not set with --period/--slice)'),
237 ),
238 'sched-credit': (
239 ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'),
240 ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'),
241 ('-c CAP', '--cap=CAP', 'Cap (int)'),
242 ),
243 'list': (
244 ('-l', '--long', 'Output all VM details in SXP'),
245 ('', '--label', 'Include security labels'),
246 ('', '--state=<state>', 'Select only VMs with the specified state'),
247 ),
248 'console': (
249 ('-q', '--quiet', 'Do not print an error message if the domain does not exist'),
250 ),
251 'vncviewer': (
252 ('', '--autopass', 'Pass VNC password to viewer via stdin and -autopass'),
253 ('', '--vncviewer-autopass', '(consistency alias for --autopass)'),
254 ),
255 'dmesg': (
256 ('-c', '--clear', 'Clear dmesg buffer as well as printing it'),
257 ),
258 'vnet-list': (
259 ('-l', '--long', 'List Vnets as SXP'),
260 ),
261 'network-list': (
262 ('-l', '--long', 'List resources as SXP'),
263 ),
264 'dump-core': (
265 ('-L', '--live', 'Dump core without pausing the domain'),
266 ('-C', '--crash', 'Crash domain after dumping core'),
267 ('-R', '--reset', 'Reset domain after dumping core'),
268 ),
269 'start': (
270 ('-p', '--paused', 'Do not unpause domain after starting it'),
271 ('-c', '--console_autoconnect', 'Connect to the console after the domain is created'),
272 ('', '--vncviewer', 'Connect to display via VNC after the domain is created'),
273 ('', '--vncviewer-autopass', 'Pass VNC password to viewer via stdin and -autopass'),
274 ),
275 'resume': (
276 ('-p', '--paused', 'Do not unpause domain after resuming it'),
277 ),
278 'save': (
279 ('-c', '--checkpoint', 'Leave domain running after creating snapshot'),
280 ),
281 'restore': (
282 ('-p', '--paused', 'Do not unpause domain after restoring it'),
283 ),
284 'info': (
285 ('-c', '--config', 'List Xend configuration parameters'),
286 ),
287 }
289 common_commands = [
290 "console",
291 "vncviewer",
292 "create",
293 "new",
294 "delete",
295 "destroy",
296 "dump-core",
297 "help",
298 "list",
299 "mem-set",
300 "migrate",
301 "pause",
302 "reboot",
303 "reset",
304 "restore",
305 "resume",
306 "save",
307 "shell",
308 "shutdown",
309 "start",
310 "suspend",
311 "top",
312 "unpause",
313 "uptime",
314 "vcpu-set",
315 ]
317 domain_commands = [
318 "console",
319 "vncviewer",
320 "create",
321 "new",
322 "delete",
323 "destroy",
324 "domid",
325 "domname",
326 "dump-core",
327 "list",
328 "mem-max",
329 "mem-set",
330 "migrate",
331 "pause",
332 "reboot",
333 "rename",
334 "reset",
335 "restore",
336 "resume",
337 "save",
338 "shutdown",
339 "start",
340 "suspend",
341 "sysrq",
342 "trigger",
343 "top",
344 "unpause",
345 "uptime",
346 "vcpu-list",
347 "vcpu-pin",
348 "vcpu-set",
349 ]
351 host_commands = [
352 "debug-keys",
353 "dmesg",
354 "info",
355 "log",
356 "serve",
357 ]
359 scheduler_commands = [
360 "sched-credit",
361 "sched-sedf",
362 ]
364 device_commands = [
365 "block-attach",
366 "block-detach",
367 "block-list",
368 "block-configure",
369 "network-attach",
370 "network-detach",
371 "network-list",
372 "vtpm-list",
373 "pci-attach",
374 "pci-detach",
375 "pci-list",
376 "pci-list-assignable-devices",
377 "scsi-attach",
378 "scsi-detach",
379 "scsi-list",
380 ]
382 vnet_commands = [
383 "vnet-list",
384 "vnet-create",
385 "vnet-delete",
386 ]
388 acm_commands = [
389 "labels",
390 "addlabel",
391 "rmlabel",
392 "getlabel",
393 "dry-run",
394 "resources",
395 "dumppolicy",
396 "setpolicy",
397 "resetpolicy",
398 "getpolicy",
399 ]
401 all_commands = (domain_commands + host_commands + scheduler_commands +
402 device_commands + vnet_commands + acm_commands +
403 ['shell', 'event-monitor'])
406 ##
407 # Configuration File Parsing
408 ##
410 xmConfigFile = os.getenv(XM_CONFIG_FILE_ENVVAR, XM_CONFIG_FILE_DEFAULT)
411 config = None
412 if os.path.isfile(xmConfigFile):
413 try:
414 config = xml.dom.minidom.parse(xmConfigFile)
415 except:
416 print >>sys.stderr, ('Ignoring invalid configuration file %s.' %
417 xmConfigFile)
419 def parseServer():
420 if config:
421 server = config.getElementsByTagName('server')
422 if server:
423 st = server[0].getAttribute('type')
424 if st != SERVER_XEN_API and st != SERVER_LEGACY_XMLRPC:
425 print >>sys.stderr, ('Invalid server type %s; using %s.' %
426 (st, SERVER_LEGACY_XMLRPC))
427 st = SERVER_LEGACY_XMLRPC
428 return (st, server[0].getAttribute('uri'))
430 return SERVER_LEGACY_XMLRPC, XendClient.uri
432 def parseAuthentication():
433 server = config.getElementsByTagName('server')[0]
434 return (server.getAttribute('username'),
435 server.getAttribute('password'))
437 serverType, serverURI = parseServer()
438 server = None
441 ####################################################################
442 #
443 # Help/usage printing functions
444 #
445 ####################################################################
447 def cmdHelp(cmd):
448 """Print help for a specific subcommand."""
450 if not SUBCOMMAND_HELP.has_key(cmd):
451 for fc in SUBCOMMAND_HELP.keys():
452 if fc[:len(cmd)] == cmd:
453 cmd = fc
454 break
456 try:
457 args, desc = SUBCOMMAND_HELP[cmd]
458 except KeyError:
459 shortHelp()
460 return
462 print 'Usage: xm %s %s' % (cmd, args)
463 print
464 print desc
466 try:
467 # If options help message is defined, print this.
468 for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]:
469 if shortopt and longopt:
470 optdesc = '%s, %s' % (shortopt, longopt)
471 elif shortopt:
472 optdesc = shortopt
473 elif longopt:
474 optdesc = longopt
476 wrapped_desc = wrap(desc, 43)
477 print ' %-30s %-43s' % (optdesc, wrapped_desc[0])
478 for line in wrapped_desc[1:]:
479 print ' ' * 33 + line
480 print
481 except KeyError:
482 # if the command is an external module, we grab usage help
483 # from the module itself.
484 if cmd in IMPORTED_COMMANDS:
485 try:
486 cmd_module = __import__(cmd, globals(), locals(), 'xen.xm')
487 cmd_usage = getattr(cmd_module, "help", None)
488 if cmd_usage:
489 print cmd_usage()
490 except ImportError:
491 pass
493 def shortHelp():
494 """Print out generic help when xm is called without subcommand."""
496 print USAGE_HELP
497 print 'Common \'xm\' commands:\n'
499 for command in common_commands:
500 try:
501 args, desc = SUBCOMMAND_HELP[command]
502 except KeyError:
503 continue
504 wrapped_desc = wrap(desc, 50)
505 print ' %-20s %-50s' % (command, wrapped_desc[0])
506 for line in wrapped_desc[1:]:
507 print ' ' * 22 + line
509 print
510 print USAGE_FOOTER
511 print 'For a complete list of subcommands run \'xm help\'.'
513 def longHelp():
514 """Print out full help when xm is called with xm --help or xm help"""
516 print USAGE_HELP
517 print 'xm full list of subcommands:\n'
519 for command in all_commands:
520 try:
521 args, desc = SUBCOMMAND_HELP[command]
522 except KeyError:
523 continue
525 wrapped_desc = wrap(desc, 50)
526 print ' %-20s %-50s' % (command, wrapped_desc[0])
527 for line in wrapped_desc[1:]:
528 print ' ' * 22 + line
530 print
531 print USAGE_FOOTER
533 def _usage(cmd):
534 """ Print help usage information """
535 if cmd:
536 cmdHelp(cmd)
537 else:
538 shortHelp()
540 def usage(cmd = None):
541 """ Print help usage information and exits """
542 _usage(cmd)
543 sys.exit(1)
546 ####################################################################
547 #
548 # Utility functions
549 #
550 ####################################################################
552 def get_default_SR():
553 return [sr_ref
554 for sr_ref in server.xenapi.SR.get_all()
555 if server.xenapi.SR.get_type(sr_ref) == "local"][0]
557 def get_default_Network():
558 return [network_ref
559 for network_ref in server.xenapi.network.get_all()][0]
561 class XenAPIUnsupportedException(Exception):
562 pass
564 def xenapi_unsupported():
565 if serverType == SERVER_XEN_API:
566 raise XenAPIUnsupportedException, "This function is not supported by Xen-API"
568 def xenapi_only():
569 if serverType != SERVER_XEN_API:
570 raise XenAPIUnsupportedException, "This function is only supported by Xen-API"
572 def map2sxp(m):
573 return [[k, m[k]] for k in m.keys()]
575 def arg_check(args, name, lo, hi = -1):
576 n = len([i for i in args if i != '--'])
578 if hi == -1:
579 if n != lo:
580 err("'xm %s' requires %d argument%s.\n" % (name, lo,
581 lo == 1 and '' or 's'))
582 usage(name)
583 else:
584 if n < lo or n > hi:
585 err("'xm %s' requires between %d and %d arguments.\n" %
586 (name, lo, hi))
587 usage(name)
590 def unit(c):
591 if not c.isalpha():
592 return 0
593 base = 1
594 if c == 'G' or c == 'g': base = 1024 * 1024 * 1024
595 elif c == 'M' or c == 'm': base = 1024 * 1024
596 elif c == 'K' or c == 'k': base = 1024
597 else:
598 print 'ignoring unknown unit'
599 return base
601 def int_unit(str, dest):
602 base = unit(str[-1])
603 if not base:
604 return int(str)
606 value = int(str[:-1])
607 dst_base = unit(dest)
608 if dst_base == 0:
609 dst_base = 1
610 if dst_base > base:
611 return value / (dst_base / base)
612 else:
613 return value * (base / dst_base)
615 def err(msg):
616 print >>sys.stderr, "Error:", msg
619 def get_single_vm(dom):
620 if serverType == SERVER_XEN_API:
621 uuids = server.xenapi.VM.get_by_name_label(dom)
622 if len(uuids) > 0:
623 return uuids[0]
625 refs = []
627 try:
628 domid = int(dom)
629 refs = [vm_ref
630 for vm_ref in server.xenapi.VM.get_all()
631 if int(server.xenapi.VM.get_domid(vm_ref)) == domid]
632 except:
633 pass
635 if len(refs) > 0:
636 return refs[0]
638 raise OptionError("Domain '%s' not found." % dom)
639 else:
640 dominfo = server.xend.domain(dom, False)
641 return dominfo['uuid']
643 ##
644 #
645 # Xen-API Shell
646 #
647 ##
649 class Shell(cmd.Cmd):
650 def __init__(self):
651 cmd.Cmd.__init__(self)
652 self.prompt = "xm> "
653 if serverType == SERVER_XEN_API:
654 try:
655 res = server.xenapi.host.list_methods()
656 for f in res:
657 setattr(Shell, 'do_' + f + ' ', self.default)
658 except:
659 pass
661 def preloop(self):
662 cmd.Cmd.preloop(self)
663 try:
664 import readline
665 readline.set_completer_delims(' ')
666 except ImportError:
667 pass
669 def default(self, line):
670 words = shlex.split(line)
671 if len(words) > 0 and words[0] == 'xm':
672 words = words[1:]
673 if len(words) > 0:
674 cmd = xm_lookup_cmd(words[0])
675 if cmd:
676 _run_cmd(cmd, words[0], words[1:])
677 elif serverType == SERVER_XEN_API:
678 ok, res = _run_cmd(lambda x: server.xenapi_request(words[0],
679 tuple(x)),
680 words[0], words[1:])
681 if ok and res is not None and res != '':
682 pprint.pprint(res)
683 else:
684 print '*** Unknown command: %s' % words[0]
685 return False
687 def completedefault(self, text, line, begidx, endidx):
688 words = shlex.split(line[:begidx])
689 clas, func = words[0].split('.')
690 if len(words) > 1 or \
691 func.startswith('get_by_') or \
692 func == 'get_all':
693 return []
694 uuids = server.xenapi_request('%s.get_all' % clas, ())
695 return [u + " " for u in uuids if u.startswith(text)]
697 def emptyline(self):
698 pass
700 def do_EOF(self, line):
701 print
702 sys.exit(0)
704 def do_help(self, line):
705 _usage(line)
708 def xm_shell(args):
709 Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
712 def xm_event_monitor(args):
713 if serverType == SERVER_XEN_API:
714 while True:
715 server.xenapi.event.register(args)
716 events = server.xenapi.event.next()
717 for e in events:
718 print e
719 else:
720 err("Event monitoring not supported unless using Xen-API.")
723 #########################################################################
724 #
725 # Main xm functions
726 #
727 #########################################################################
729 def xm_save(args):
731 arg_check(args, "save", 2, 3)
733 try:
734 (options, params) = getopt.gnu_getopt(args, 'c', ['checkpoint'])
735 except getopt.GetoptError, opterr:
736 err(opterr)
737 sys.exit(1)
739 checkpoint = False
740 for (k, v) in options:
741 if k in ['-c', '--checkpoint']:
742 checkpoint = True
744 if len(params) != 2:
745 err("Wrong number of parameters")
746 usage('save')
748 dom = params[0]
749 savefile = os.path.abspath(params[1])
751 if not os.access(os.path.dirname(savefile), os.W_OK):
752 err("xm save: Unable to create file %s" % savefile)
753 sys.exit(1)
755 if serverType == SERVER_XEN_API:
756 server.xenapi.VM.save(get_single_vm(dom), savefile, checkpoint)
757 else:
758 server.xend.domain.save(dom, savefile, checkpoint)
760 def xm_restore(args):
761 arg_check(args, "restore", 1, 2)
763 try:
764 (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
765 except getopt.GetoptError, opterr:
766 err(opterr)
767 usage('restore')
769 paused = False
770 for (k, v) in options:
771 if k in ['-p', '--paused']:
772 paused = True
774 if len(params) != 1:
775 err("Wrong number of parameters")
776 usage('restore')
778 savefile = os.path.abspath(params[0])
780 if not os.access(savefile, os.R_OK):
781 err("xm restore: Unable to read file %s" % savefile)
782 sys.exit(1)
784 if serverType == SERVER_XEN_API:
785 server.xenapi.VM.restore(savefile, paused)
786 else:
787 server.xend.domain.restore(savefile, paused)
790 def datetime_to_secs(v):
791 unwanted = ":-."
792 for c in unwanted:
793 v = str(v).replace(c, "")
794 return time.mktime(time.strptime(v[0:14], '%Y%m%dT%H%M%S'))
796 def getDomains(domain_names, state, full = 0):
797 if serverType == SERVER_XEN_API:
798 doms_sxp = []
799 doms_dict = []
801 dom_recs = server.xenapi.VM.get_all_records()
802 dom_metrics_recs = server.xenapi.VM_metrics.get_all_records()
804 for dom_ref, dom_rec in dom_recs.items():
805 dom_metrics_rec = dom_metrics_recs[dom_rec['metrics']]
807 states = ('running', 'blocked', 'paused', 'shutdown',
808 'crashed', 'dying')
809 def state_on_off(state):
810 if state in dom_metrics_rec['state']:
811 return state[0]
812 else:
813 return "-"
814 state_str = "".join([state_on_off(state)
815 for state in states])
817 dom_rec.update({'name': dom_rec['name_label'],
818 'memory_actual': int(dom_metrics_rec['memory_actual'])/1024,
819 'vcpus': dom_metrics_rec['VCPUs_number'],
820 'state': state_str,
821 'cpu_time': dom_metrics_rec['VCPUs_utilisation'],
822 'start_time': datetime_to_secs(
823 dom_metrics_rec['start_time'])})
825 doms_sxp.append(['domain'] + map2sxp(dom_rec))
826 doms_dict.append(dom_rec)
828 if domain_names:
829 doms = [['domain'] + map2sxp(dom) for dom in doms_dict
830 if dom["name"] in domain_names]
832 if len(doms) > 0:
833 return doms
834 else:
835 print "Error: no domain%s named %s" % \
836 (len(domain_names) > 1 and 's' or '',
837 ', '.join(domain_names))
838 sys.exit(-1)
839 else:
840 return doms_sxp
841 else:
842 if domain_names:
843 return [server.xend.domain(dom, full) for dom in domain_names]
844 else:
845 return server.xend.domains_with_state(True, state, full)
848 def xm_list(args):
849 use_long = 0
850 show_vcpus = 0
851 show_labels = 0
852 state = 'all'
853 try:
854 (options, params) = getopt.gnu_getopt(args, 'lv',
855 ['long','vcpus','label',
856 'state='])
857 except getopt.GetoptError, opterr:
858 err(opterr)
859 usage('list')
861 for (k, v) in options:
862 if k in ['-l', '--long']:
863 use_long = 1
864 if k in ['-v', '--vcpus']:
865 show_vcpus = 1
866 if k in ['--label']:
867 show_labels = 1
868 if k in ['--state']:
869 state = v
871 if state != 'all' and len(params) > 0:
872 raise OptionError(
873 "You may specify either a state or a particular VM, but not both")
875 if show_vcpus:
876 print >>sys.stderr, (
877 "xm list -v is deprecated. Please use xm vcpu-list.")
878 xm_vcpu_list(params)
879 return
881 doms = getDomains(params, state, use_long)
883 if use_long:
884 map(PrettyPrint.prettyprint, doms)
885 elif show_labels:
886 xm_label_list(doms)
887 else:
888 xm_brief_list(doms)
891 def parse_doms_info(info):
892 def get_info(n, t, d):
893 return t(sxp.child_value(info, n, d))
895 def get_status(n, t, d):
896 return DOM_STATES[t(sxp.child_value(info, n, d))]
898 start_time = get_info('start_time', float, -1)
899 if start_time == -1:
900 up_time = float(-1)
901 else:
902 up_time = time.time() - start_time
904 parsed_info = {
905 'domid' : get_info('domid', str, ''),
906 'name' : get_info('name', str, '??'),
907 'state' : get_info('state', str, ''),
909 # VCPUs is the number online when the VM is up, or the number
910 # configured otherwise.
911 'vcpus' : get_info('online_vcpus', int,
912 get_info('vcpus', int, 0)),
913 'up_time' : up_time
914 }
916 security_label = get_info('security_label', str, '')
917 parsed_info['seclabel'] = security.parse_security_label(security_label)
919 if serverType == SERVER_XEN_API:
920 parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
921 cpu_times = get_info('cpu_time', lambda x : (x), 0.0)
922 if sum(cpu_times.values()) > 0:
923 parsed_info['cpu_time'] = sum(cpu_times.values()) / float(len(cpu_times.values()))
924 else:
925 parsed_info['cpu_time'] = 0
926 else:
927 parsed_info['mem'] = get_info('memory', int,0)
928 parsed_info['cpu_time'] = get_info('cpu_time', float, 0.0)
930 return parsed_info
932 def check_sched_type(sched):
933 if serverType == SERVER_XEN_API:
934 current = server.xenapi.host.get_sched_policy(
935 server.xenapi.session.get_this_host(server.getSession()))
936 else:
937 current = 'unknown'
938 for x in server.xend.node.info()[1:]:
939 if len(x) > 1 and x[0] == 'xen_scheduler':
940 current = x[1]
941 break
942 if sched != current:
943 err("Xen is running with the %s scheduler" % current)
944 sys.exit(1)
946 def parse_sedf_info(info):
947 def get_info(n, t, d):
948 return t(sxp.child_value(info, n, d))
950 return {
951 'domid' : get_info('domid', int, -1),
952 'period' : get_info('period', int, -1),
953 'slice' : get_info('slice', int, -1),
954 'latency' : get_info('latency', int, -1),
955 'extratime': get_info('extratime', int, -1),
956 'weight' : get_info('weight', int, -1),
957 }
959 def domid_match(domid, info):
960 return domid is None or domid == info['name'] or \
961 domid == str(info['domid'])
963 def xm_brief_list(doms):
964 print '%-40s %5s %5s %5s %10s %9s' % \
965 ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)')
967 format = "%(name)-40s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s " \
968 "%(cpu_time)8.1f"
970 for dom in doms:
971 d = parse_doms_info(dom)
972 print format % d
974 def xm_label_list(doms):
975 print '%-40s %5s %5s %5s %10s %9s %-10s' % \
976 ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
978 output = []
979 format = '%(name)-40s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
980 '%(cpu_time)8.1f %(seclabel)10s'
982 for dom in doms:
983 d = parse_doms_info(dom)
984 if d['seclabel'] == "" and serverType != SERVER_XEN_API:
985 seclab = server.xend.security.get_domain_label(d['name'])
986 if len(seclab) > 0 and seclab[0] == '\'':
987 seclab = seclab[1:]
988 d['seclabel'] = seclab
989 output.append((format % d, d['seclabel']))
991 #sort by labels
992 output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
993 for line, label in output:
994 print line
997 def xm_vcpu_list(args):
998 if serverType == SERVER_XEN_API:
999 if args:
1000 vm_refs = map(get_single_vm, args)
1001 else:
1002 vm_refs = server.xenapi.VM.get_all()
1004 vm_records = dict(map(lambda vm_ref:
1005 (vm_ref, server.xenapi.VM.get_record(
1006 vm_ref)),
1007 vm_refs))
1009 vm_metrics = dict(map(lambda (ref, record):
1010 (ref,
1011 server.xenapi.VM_metrics.get_record(
1012 record['metrics'])),
1013 vm_records.items()))
1015 dominfo = []
1017 # vcpu_list doesn't list 'managed' domains
1018 # when they are not running, so filter them out
1020 vm_refs = [vm_ref
1021 for vm_ref in vm_refs
1022 if vm_records[vm_ref]["power_state"] != "Halted"]
1024 for vm_ref in vm_refs:
1025 info = ['domain',
1026 ['domid', vm_records[vm_ref]['domid']],
1027 ['name', vm_records[vm_ref]['name_label']],
1028 ['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
1030 for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
1031 def chk_flag(flag):
1032 return flag in vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
1033 and 1 or 0
1035 vcpu_info = ['vcpu',
1036 ['number',
1037 i],
1038 ['online',
1039 chk_flag("online")],
1040 ['blocked',
1041 chk_flag("blocked")],
1042 ['running',
1043 chk_flag("running")],
1044 ['cpu_time',
1045 vm_metrics[vm_ref]['VCPUs_utilisation'][str(i)]],
1046 ['cpu',
1047 vm_metrics[vm_ref]['VCPUs_CPU'][str(i)]],
1048 ['cpumap',
1049 vm_metrics[vm_ref]['VCPUs_params']\
1050 ['cpumap%i' % i].split(",")]]
1052 info.append(vcpu_info)
1054 dominfo.append(info)
1055 else:
1056 if args:
1057 dominfo = map(server.xend.domain.getVCPUInfo, args)
1058 else:
1059 doms = server.xend.domains_with_state(False, 'all', False)
1060 dominfo = map(server.xend.domain.getVCPUInfo, doms)
1062 print '%-32s %5s %5s %5s %5s %9s %s' % \
1063 ('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
1065 format = '%(name)-32s %(domid)5s %(number)5d %(c)5s %(s)5s ' \
1066 ' %(cpu_time)8.1f %(cpumap)s'
1068 for dom in dominfo:
1069 def get_info(n):
1070 return sxp.child_value(dom, n)
1073 # convert a list of integers into a list of pairs indicating
1074 # continuous sequences in the list:
1076 # [0,1,2,3] -> [(0,3)]
1077 # [1,2,4,5] -> [(1,2),(4,5)]
1078 # [0] -> [(0,0)]
1079 # [0,1,4,6,7] -> [(0,1),(4,4),(6,7)]
1081 def list_to_rangepairs(cmap):
1082 cmap.sort()
1083 pairs = []
1084 x = y = 0
1085 for i in range(0,len(cmap)):
1086 try:
1087 if ((cmap[y+1] - cmap[i]) > 1):
1088 pairs.append((cmap[x],cmap[y]))
1089 x = y = i+1
1090 else:
1091 y = y + 1
1092 # if we go off the end, then just add x to y
1093 except IndexError:
1094 pairs.append((cmap[x],cmap[y]))
1096 return pairs
1099 # Convert pairs to range string, e.g: [(1,2),(3,3),(5,7)] -> 1-2,3,5-7
1101 def format_pairs(pairs):
1102 if not pairs:
1103 return "no cpus"
1104 out = ""
1105 for f,s in pairs:
1106 if (f==s):
1107 out += '%d'%f
1108 else:
1109 out += '%d-%d'%(f,s)
1110 out += ','
1111 # trim trailing ','
1112 return out[:-1]
1114 def format_cpumap(cpumap):
1115 cpumap = map(lambda x: int(x), cpumap)
1116 cpumap.sort()
1118 if serverType == SERVER_XEN_API:
1119 nr_cpus = len(server.xenapi.host.get_host_CPUs(
1120 server.xenapi.session.get_this_host(server.getSession())))
1121 else:
1122 for x in server.xend.node.info()[1:]:
1123 if len(x) > 1 and x[0] == 'nr_cpus':
1124 nr_cpus = int(x[1])
1126 # normalize cpumap by modulus nr_cpus, and drop duplicates
1127 cpumap = dict.fromkeys(
1128 filter(lambda x: x < nr_cpus, cpumap)).keys()
1129 if len(cpumap) == nr_cpus:
1130 return "any cpu"
1132 return format_pairs(list_to_rangepairs(cpumap))
1134 name = get_info('name')
1135 domid = get_info('domid')
1136 if domid is not None:
1137 domid = str(domid)
1138 else:
1139 domid = ''
1141 for vcpu in sxp.children(dom, 'vcpu'):
1142 def vinfo(n, t):
1143 return t(sxp.child_value(vcpu, n))
1145 number = vinfo('number', int)
1146 cpu = vinfo('cpu', int)
1147 cpumap = format_cpumap(vinfo('cpumap', list))
1148 online = vinfo('online', int)
1149 cpu_time = vinfo('cpu_time', float)
1150 running = vinfo('running', int)
1151 blocked = vinfo('blocked', int)
1153 if cpu < 0:
1154 c = ''
1155 s = ''
1156 elif online:
1157 c = str(cpu)
1158 if running:
1159 s = 'r'
1160 else:
1161 s = '-'
1162 if blocked:
1163 s += 'b'
1164 else:
1165 s += '-'
1166 s += '-'
1167 else:
1168 c = '-'
1169 s = '--p'
1171 print format % locals()
1173 def start_do_console(domain_name):
1174 cpid = os.fork()
1175 if cpid != 0:
1176 for i in range(10):
1177 # Catch failure of the create process
1178 time.sleep(1)
1179 (p, rv) = os.waitpid(cpid, os.WNOHANG)
1180 if os.WIFEXITED(rv):
1181 if os.WEXITSTATUS(rv) != 0:
1182 sys.exit(os.WEXITSTATUS(rv))
1183 try:
1184 # Acquire the console of the created dom
1185 if serverType == SERVER_XEN_API:
1186 domid = server.xenapi.VM.get_domid(
1187 get_single_vm(domain_name))
1188 else:
1189 dom = server.xend.domain(domain_name)
1190 domid = int(sxp.child_value(dom, 'domid', '-1'))
1191 console.execConsole(domid)
1192 except:
1193 pass
1194 print("Could not start console\n");
1195 sys.exit(0)
1197 def xm_start(args):
1199 paused = False
1200 console_autoconnect = False
1201 vncviewer = False
1202 vncviewer_autopass = False
1204 try:
1205 (options, params) = getopt.gnu_getopt(args, 'cp', ['console_autoconnect','paused','vncviewer','vncviewer-autopass'])
1206 for (k, v) in options:
1207 if k in ('-p', '--paused'):
1208 paused = True
1209 if k in ('-c', '--console_autoconnect'):
1210 console_autoconnect = True
1211 if k in ('--vncviewer'):
1212 vncviewer = True
1213 if k in ('--vncviewer-autopass'):
1214 vncviewer_autopass = True
1216 if len(params) != 1:
1217 raise OptionError("Expects 1 argument")
1218 except getopt.GetoptError, opterr:
1219 err(opterr)
1220 usage('start')
1222 dom = params[0]
1224 if console_autoconnect:
1225 start_do_console(dom)
1227 try:
1228 if serverType == SERVER_XEN_API:
1229 server.xenapi.VM.start(get_single_vm(dom), paused)
1230 domid = int(server.xenapi.VM.get_domid(get_single_vm(dom)))
1231 else:
1232 server.xend.domain.start(dom, paused)
1233 info = server.xend.domain(dom)
1234 domid = int(sxp.child_value(info, 'domid', '-1'))
1235 except:
1236 raise
1238 if domid == -1:
1239 raise xmlrpclib.Fault(0, "Domain '%s' is not started" % dom)
1241 if vncviewer:
1242 console.runVncViewer(domid, vncviewer_autopass, True)
1245 def xm_delete(args):
1246 arg_check(args, "delete", 1)
1247 dom = args[0]
1248 if serverType == SERVER_XEN_API:
1249 server.xenapi.VM.destroy(get_single_vm(dom))
1250 else:
1251 server.xend.domain.delete(dom)
1253 def xm_suspend(args):
1254 arg_check(args, "suspend", 1)
1255 dom = args[0]
1256 if serverType == SERVER_XEN_API:
1257 server.xenapi.VM.suspend(get_single_vm(dom))
1258 else:
1259 server.xend.domain.suspend(dom)
1261 def xm_resume(args):
1262 arg_check(args, "resume", 1, 2)
1264 try:
1265 (options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
1266 except getopt.GetoptError, opterr:
1267 err(opterr)
1268 usage('resume')
1270 paused = False
1271 for (k, v) in options:
1272 if k in ['-p', '--paused']:
1273 paused = True
1275 if len(params) != 1:
1276 err("Wrong number of parameters")
1277 usage('resume')
1279 dom = params[0]
1280 if serverType == SERVER_XEN_API:
1281 server.xenapi.VM.resume(get_single_vm(dom), paused)
1282 else:
1283 server.xend.domain.resume(dom, paused)
1285 def xm_reboot(args):
1286 arg_check(args, "reboot", 1, 3)
1287 from xen.xm import shutdown
1288 shutdown.main(["shutdown", "-R"] + args)
1290 def xm_shutdown(args):
1291 arg_check(args, "shutdown", 1, 4)
1292 from xen.xm import shutdown
1293 shutdown.main(["shutdown"] + args)
1295 def xm_reset(args):
1296 arg_check(args, "reset", 1)
1297 dom = args[0]
1299 if serverType == SERVER_XEN_API:
1300 server.xenapi.VM.hard_reboot(get_single_vm(dom))
1301 else:
1302 server.xend.domain.reset(dom)
1304 def xm_pause(args):
1305 arg_check(args, "pause", 1)
1306 dom = args[0]
1308 if serverType == SERVER_XEN_API:
1309 server.xenapi.VM.pause(get_single_vm(dom))
1310 else:
1311 server.xend.domain.pause(dom)
1313 def xm_unpause(args):
1314 arg_check(args, "unpause", 1)
1315 dom = args[0]
1317 if serverType == SERVER_XEN_API:
1318 server.xenapi.VM.unpause(get_single_vm(dom))
1319 else:
1320 server.xend.domain.unpause(dom)
1322 def xm_dump_core(args):
1323 live = False
1324 crash = False
1325 reset = False
1326 try:
1327 (options, params) = getopt.gnu_getopt(args, 'LCR', ['live', 'crash', 'reset'])
1328 for (k, v) in options:
1329 if k in ('-L', '--live'):
1330 live = True
1331 elif k in ('-C', '--crash'):
1332 crash = True
1333 elif k in ('-R', '--reset'):
1334 reset = True
1336 if crash and reset:
1337 raise OptionError("You may not specify more than one '-CR' option")
1338 if len(params) not in (1, 2):
1339 raise OptionError("Expects 1 or 2 argument(s)")
1340 except getopt.GetoptError, e:
1341 raise OptionError(str(e))
1343 dom = params[0]
1344 if len(params) == 2:
1345 filename = os.path.abspath(params[1])
1346 else:
1347 filename = None
1349 if not live:
1350 ds = server.xend.domain.pause(dom, True)
1352 try:
1353 print "Dumping core of domain: %s ..." % str(dom)
1354 server.xend.domain.dump(dom, filename, live, crash)
1356 if crash:
1357 print "Destroying domain: %s ..." % str(dom)
1358 server.xend.domain.destroy(dom)
1359 elif reset:
1360 print "Resetting domain: %s ..." % str(dom)
1361 server.xend.domain.reset(dom)
1362 finally:
1363 if not live and not crash and not reset and ds == DOM_STATE_RUNNING:
1364 server.xend.domain.unpause(dom)
1366 def xm_rename(args):
1367 arg_check(args, "rename", 2)
1369 if serverType == SERVER_XEN_API:
1370 server.xenapi.VM.set_name_label(get_single_vm(args[0]), args[1])
1371 else:
1372 server.xend.domain.setName(args[0], args[1])
1374 def xm_importcommand(command, args):
1375 cmd = __import__(command, globals(), locals(), 'xen.xm')
1376 cmd.main([command] + args)
1379 #############################################################
1381 def xm_vcpu_pin(args):
1382 arg_check(args, "vcpu-pin", 3)
1384 def cpu_make_map(cpulist):
1385 cpus = []
1386 for c in cpulist.split(','):
1387 if c.find('-') != -1:
1388 (x,y) = c.split('-')
1389 for i in range(int(x),int(y)+1):
1390 cpus.append(int(i))
1391 else:
1392 # remove this element from the list
1393 if c[0] == '^':
1394 cpus = [x for x in cpus if x != int(c[1:])]
1395 else:
1396 cpus.append(int(c))
1397 cpus.sort()
1398 return cpus
1400 dom = args[0]
1401 vcpu = args[1]
1402 if args[2] == 'all':
1403 cpumap = cpu_make_map('0-63')
1404 else:
1405 cpumap = cpu_make_map(args[2])
1407 if serverType == SERVER_XEN_API:
1408 cpumap = map(str, cpumap)
1409 server.xenapi.VM.add_to_VCPUs_params_live(
1410 get_single_vm(dom), "cpumap%i" % int(vcpu), ",".join(cpumap))
1411 else:
1412 server.xend.domain.pincpu(dom, vcpu, cpumap)
1414 def xm_mem_max(args):
1415 arg_check(args, "mem-max", 2)
1417 dom = args[0]
1419 if serverType == SERVER_XEN_API:
1420 mem = int_unit(args[1], 'k') * 1024
1421 server.xenapi.VM.set_memory_static_max(get_single_vm(dom), mem)
1422 else:
1423 mem = int_unit(args[1], 'm')
1424 server.xend.domain.maxmem_set(dom, mem)
1426 def xm_mem_set(args):
1427 arg_check(args, "mem-set", 2)
1429 dom = args[0]
1431 if serverType == SERVER_XEN_API:
1432 mem_target = int_unit(args[1], 'm') * 1024 * 1024
1433 server.xenapi.VM.set_memory_dynamic_max_live(get_single_vm(dom),
1434 mem_target)
1435 server.xenapi.VM.set_memory_dynamic_min_live(get_single_vm(dom),
1436 mem_target)
1437 else:
1438 mem_target = int_unit(args[1], 'm')
1439 server.xend.domain.setMemoryTarget(dom, mem_target)
1441 def xm_vcpu_set(args):
1442 arg_check(args, "vcpu-set", 2)
1444 dom = args[0]
1445 vcpus = int(args[1])
1447 if serverType == SERVER_XEN_API:
1448 server.xenapi.VM.set_VCPUs_number_live(get_single_vm(dom), vcpus)
1449 else:
1450 server.xend.domain.setVCpuCount(dom, vcpus)
1452 def xm_destroy(args):
1453 arg_check(args, "destroy", 1)
1455 dom = args[0]
1457 if serverType == SERVER_XEN_API:
1458 server.xenapi.VM.hard_shutdown(get_single_vm(dom))
1459 else:
1460 server.xend.domain.destroy(dom)
1462 def xm_domid(args):
1463 arg_check(args, "domid", 1)
1465 name = args[0]
1467 if serverType == SERVER_XEN_API:
1468 print server.xenapi.VM.get_domid(get_single_vm(name))
1469 else:
1470 dom = server.xend.domain(name)
1471 print sxp.child_value(dom, 'domid')
1473 def xm_domname(args):
1474 arg_check(args, "domname", 1)
1476 name = args[0]
1478 if serverType == SERVER_XEN_API:
1479 print server.xenapi.VM.get_name_label(get_single_vm(name))
1480 else:
1481 dom = server.xend.domain(name)
1482 print sxp.child_value(dom, 'name')
1484 def xm_sched_sedf(args):
1485 xenapi_unsupported()
1487 def ns_to_ms(val):
1488 return float(val) * 0.000001
1490 def ms_to_ns(val):
1491 return (float(val) / 0.000001)
1493 def print_sedf(info):
1494 info['period'] = ns_to_ms(info['period'])
1495 info['slice'] = ns_to_ms(info['slice'])
1496 info['latency'] = ns_to_ms(info['latency'])
1497 print( ("%(name)-32s %(domid)5d %(period)9.1f %(slice)9.1f" +
1498 " %(latency)7.1f %(extratime)6d %(weight)6d") % info)
1500 check_sched_type('sedf')
1502 # we want to just display current info if no parameters are passed
1503 if len(args) == 0:
1504 domid = None
1505 else:
1506 # we expect at least a domain id (name or number)
1507 # and at most a domid up to 5 options with values
1508 arg_check(args, "sched-sedf", 1, 11)
1509 domid = args[0]
1510 # drop domid from args since get_opt doesn't recognize it
1511 args = args[1:]
1513 opts = {}
1514 try:
1515 (options, params) = getopt.gnu_getopt(args, 'p:s:l:e:w:',
1516 ['period=', 'slice=', 'latency=', 'extratime=', 'weight='])
1517 except getopt.GetoptError, opterr:
1518 err(opterr)
1519 usage('sched-sedf')
1521 # convert to nanoseconds if needed
1522 for (k, v) in options:
1523 if k in ['-p', '--period']:
1524 opts['period'] = ms_to_ns(v)
1525 elif k in ['-s', '--slice']:
1526 opts['slice'] = ms_to_ns(v)
1527 elif k in ['-l', '--latency']:
1528 opts['latency'] = ms_to_ns(v)
1529 elif k in ['-e', '--extratime']:
1530 opts['extratime'] = v
1531 elif k in ['-w', '--weight']:
1532 opts['weight'] = v
1534 doms = filter(lambda x : domid_match(domid, x),
1535 [parse_doms_info(dom)
1536 for dom in getDomains(None, 'running')])
1537 if domid is not None and doms == []:
1538 err("Domain '%s' does not exist." % domid)
1539 usage('sched-sedf')
1541 # print header if we aren't setting any parameters
1542 if len(opts.keys()) == 0:
1543 print '%-33s %4s %-4s %-4s %-7s %-5s %-6s' % \
1544 ('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)',
1545 'Extra','Weight')
1547 for d in doms:
1548 # fetch current values so as not to clobber them
1549 try:
1550 sedf_raw = server.xend.domain.cpu_sedf_get(d['domid'])
1551 except xmlrpclib.Fault:
1552 # domain does not support sched-sedf?
1553 sedf_raw = {}
1555 sedf_info = parse_sedf_info(sedf_raw)
1556 sedf_info['name'] = d['name']
1557 # update values in case of call to set
1558 if len(opts.keys()) > 0:
1559 for k in opts.keys():
1560 sedf_info[k]=opts[k]
1562 # send the update, converting user input
1563 v = map(int, [sedf_info['period'], sedf_info['slice'],
1564 sedf_info['latency'],sedf_info['extratime'],
1565 sedf_info['weight']])
1566 rv = server.xend.domain.cpu_sedf_set(d['domid'], *v)
1567 if int(rv) != 0:
1568 err("Failed to set sedf parameters (rv=%d)."%(rv))
1570 # not setting values, display info
1571 else:
1572 print_sedf(sedf_info)
1574 def xm_sched_credit(args):
1575 """Get/Set options for Credit Scheduler."""
1577 check_sched_type('credit')
1579 try:
1580 opts, params = getopt.getopt(args, "d:w:c:",
1581 ["domain=", "weight=", "cap="])
1582 except getopt.GetoptError, opterr:
1583 err(opterr)
1584 usage('sched-credit')
1586 domid = None
1587 weight = None
1588 cap = None
1590 for o, a in opts:
1591 if o in ["-d", "--domain"]:
1592 domid = a
1593 elif o in ["-w", "--weight"]:
1594 weight = int(a)
1595 elif o in ["-c", "--cap"]:
1596 cap = int(a);
1598 doms = filter(lambda x : domid_match(domid, x),
1599 [parse_doms_info(dom)
1600 for dom in getDomains(None, 'all')])
1602 if weight is None and cap is None:
1603 if domid is not None and doms == []:
1604 err("Domain '%s' does not exist." % domid)
1605 usage('sched-credit')
1606 # print header if we aren't setting any parameters
1607 print '%-33s %4s %6s %4s' % ('Name','ID','Weight','Cap')
1609 for d in doms:
1610 try:
1611 if serverType == SERVER_XEN_API:
1612 info = server.xenapi.VM_metrics.get_VCPUs_params(
1613 server.xenapi.VM.get_metrics(
1614 get_single_vm(d['name'])))
1615 else:
1616 info = server.xend.domain.sched_credit_get(d['name'])
1617 except xmlrpclib.Fault:
1618 pass
1620 if 'weight' not in info or 'cap' not in info:
1621 # domain does not support sched-credit?
1622 info = {'weight': -1, 'cap': -1}
1624 info['weight'] = int(info['weight'])
1625 info['cap'] = int(info['cap'])
1627 info['name'] = d['name']
1628 info['domid'] = str(d['domid'])
1629 print( ("%(name)-32s %(domid)5s %(weight)6d %(cap)4d") % info)
1630 else:
1631 if domid is None:
1632 # place holder for system-wide scheduler parameters
1633 err("No domain given.")
1634 usage('sched-credit')
1636 if serverType == SERVER_XEN_API:
1637 if doms[0]['domid']:
1638 server.xenapi.VM.add_to_VCPUs_params_live(
1639 get_single_vm(domid),
1640 "weight",
1641 weight)
1642 server.xenapi.VM.add_to_VCPUs_params_live(
1643 get_single_vm(domid),
1644 "cap",
1645 cap)
1646 else:
1647 server.xenapi.VM.add_to_VCPUs_params(
1648 get_single_vm(domid),
1649 "weight",
1650 weight)
1651 server.xenapi.VM.add_to_VCPUs_params(
1652 get_single_vm(domid),
1653 "cap",
1654 cap)
1655 else:
1656 result = server.xend.domain.sched_credit_set(domid, weight, cap)
1657 if result != 0:
1658 err(str(result))
1660 def xm_info(args):
1661 arg_check(args, "info", 0, 1)
1663 try:
1664 (options, params) = getopt.gnu_getopt(args, 'c', ['config'])
1665 except getopt.GetoptError, opterr:
1666 err(opterr)
1667 usage('info')
1669 show_xend_config = 0
1670 for (k, v) in options:
1671 if k in ['-c', '--config']:
1672 show_xend_config = 1
1674 if show_xend_config:
1675 for name, obj in inspect.getmembers(xoptions):
1676 if not inspect.ismethod(obj):
1677 if name == "config":
1678 for x in obj[1:]:
1679 if len(x) < 2:
1680 print "%-38s: (none)" % x[0]
1681 else:
1682 print "%-38s:" % x[0], x[1]
1683 else:
1684 print "%-38s:" % name, obj
1685 return
1687 if serverType == SERVER_XEN_API:
1689 # Need to fake out old style xm info as people rely on parsing it
1691 host_record = server.xenapi.host.get_record(
1692 server.xenapi.session.get_this_host(server.getSession()))
1694 host_cpu_records = map(server.xenapi.host_cpu.get_record, host_record["host_CPUs"])
1696 host_metrics_record = server.xenapi.host_metrics.get_record(host_record["metrics"])
1698 def getVal(keys, default=""):
1699 data = host_record
1700 for key in keys:
1701 if key in data:
1702 data = data[key]
1703 else:
1704 return default
1705 return data
1707 def getCpuMhz():
1708 cpu_speeds = [int(host_cpu_record["speed"])
1709 for host_cpu_record in host_cpu_records
1710 if "speed" in host_cpu_record]
1711 if len(cpu_speeds) > 0:
1712 return sum(cpu_speeds) / len(cpu_speeds)
1713 else:
1714 return 0
1716 getCpuMhz()
1718 def getCpuFeatures():
1719 if len(host_cpu_records) > 0:
1720 return host_cpu_records[0].get("features", "")
1721 else:
1722 return ""
1724 info = {
1725 "host": getVal(["name_label"]),
1726 "release": getVal(["software_version", "release"]),
1727 "version": getVal(["software_version", "version"]),
1728 "machine": getVal(["software_version", "machine"]),
1729 "nr_cpus": getVal(["cpu_configuration", "nr_cpus"]),
1730 "nr_nodes": getVal(["cpu_configuration", "nr_nodes"]),
1731 "cores_per_socket": getVal(["cpu_configuration", "cores_per_socket"]),
1732 "threads_per_core": getVal(["cpu_configuration", "threads_per_core"]),
1733 "cpu_mhz": getCpuMhz(),
1734 "hw_caps": getCpuFeatures(),
1735 "total_memory": int(host_metrics_record["memory_total"])/1024/1024,
1736 "free_memory": int(host_metrics_record["memory_free"])/1024/1024,
1737 "xen_major": getVal(["software_version", "xen_major"]),
1738 "xen_minor": getVal(["software_version", "xen_minor"]),
1739 "xen_extra": getVal(["software_version", "xen_extra"]),
1740 "xen_caps": " ".join(getVal(["capabilities"], [])),
1741 "xen_scheduler": getVal(["sched_policy"]),
1742 "xen_pagesize": getVal(["other_config", "xen_pagesize"]),
1743 "platform_params": getVal(["other_config", "platform_params"]),
1744 "xen_changeset": getVal(["software_version", "xen_changeset"]),
1745 "cc_compiler": getVal(["software_version", "cc_compiler"]),
1746 "cc_compile_by": getVal(["software_version", "cc_compile_by"]),
1747 "cc_compile_domain": getVal(["software_version", "cc_compile_domain"]),
1748 "cc_compile_date": getVal(["software_version", "cc_compile_date"]),
1749 "xend_config_format":getVal(["software_version", "xend_config_format"])
1752 sorted = info.items()
1753 sorted.sort(lambda (x1,y1), (x2,y2): -cmp(x1,x2))
1755 for (k, v) in sorted:
1756 print "%-23s:" % k, v
1757 else:
1758 info = server.xend.node.info()
1759 for x in info[1:]:
1760 if len(x) < 2:
1761 print "%-23s: (none)" % x[0]
1762 else:
1763 print "%-23s:" % x[0], x[1]
1765 def xm_console(args):
1766 arg_check(args, "console", 1, 2)
1768 quiet = False;
1770 try:
1771 (options, params) = getopt.gnu_getopt(args, 'q', ['quiet'])
1772 except getopt.GetoptError, opterr:
1773 err(opterr)
1774 usage('console')
1776 for (k, v) in options:
1777 if k in ['-q', '--quiet']:
1778 quiet = True
1779 else:
1780 assert False
1782 if len(params) != 1:
1783 err('No domain given')
1784 usage('console')
1786 dom = params[0]
1788 try:
1789 if serverType == SERVER_XEN_API:
1790 domid = int(server.xenapi.VM.get_domid(get_single_vm(dom)))
1791 else:
1792 info = server.xend.domain(dom)
1793 domid = int(sxp.child_value(info, 'domid', '-1'))
1794 except:
1795 if quiet:
1796 sys.exit(1)
1797 else:
1798 raise
1800 if domid == -1:
1801 if quiet:
1802 sys.exit(1)
1803 else:
1804 raise xmlrpclib.Fault(0, "Domain '%s' is not started" % dom)
1806 console.execConsole(domid)
1809 def domain_name_to_domid(domain_name):
1810 if serverType == SERVER_XEN_API:
1811 domid = server.xenapi.VM.get_domid(
1812 get_single_vm(domain_name))
1813 else:
1814 dom = server.xend.domain(domain_name)
1815 domid = int(sxp.child_value(dom, 'domid', '-1'))
1816 return int(domid)
1818 def xm_vncviewer(args):
1819 autopass = False;
1821 try:
1822 (options, params) = getopt.gnu_getopt(args, '', ['autopass','vncviewer-autopass'])
1823 except getopt.GetoptError, opterr:
1824 err(opterr)
1825 usage('vncviewer')
1827 for (k, v) in options:
1828 if k in ['--autopass','--vncviewer-autopass']:
1829 autopass = True
1830 else:
1831 assert False
1833 if len(params) != 1:
1834 err('No domain given (or several parameters specified)')
1835 usage('vncviewer')
1837 dom = params[0]
1838 domid = domain_name_to_domid(dom)
1840 console.runVncViewer(domid, autopass)
1843 def xm_uptime(args):
1844 short_mode = 0
1846 try:
1847 (options, params) = getopt.gnu_getopt(args, 's', ['short'])
1848 except getopt.GetoptError, opterr:
1849 err(opterr)
1850 usage('uptime')
1852 for (k, v) in options:
1853 if k in ['-s', '--short']:
1854 short_mode = 1
1856 doms = getDomains(params, 'all')
1858 if short_mode == 0:
1859 print '%-33s %4s %s ' % ('Name','ID','Uptime')
1861 for dom in doms:
1862 d = parse_doms_info(dom)
1863 if d['domid'] == '':
1864 uptime = 0
1865 elif int(d['domid']) > 0:
1866 uptime = int(round(d['up_time']))
1867 else:
1868 f=open('/proc/uptime', 'r')
1869 upfile = f.read()
1870 uptime = int(round(float(upfile.split(' ')[0])))
1871 f.close()
1873 days = int(uptime / 86400)
1874 uptime -= (days * 86400)
1875 hours = int(uptime / 3600)
1876 uptime -= (hours * 3600)
1877 minutes = int(uptime / 60)
1878 uptime -= (minutes * 60)
1879 seconds = uptime
1881 upstring = ""
1882 if days > 0:
1883 upstring += str(days) + " day"
1884 if days > 1:
1885 upstring += "s"
1886 upstring += ", "
1887 upstring += '%(hours)2d:%(minutes)02d' % vars()
1889 if short_mode:
1890 now = datetime.datetime.now()
1891 upstring = now.strftime(" %H:%M:%S") + " up " + upstring
1892 upstring += ", " + d['name'] + " (" + d['domid'] + ")"
1893 else:
1894 upstring += ':%(seconds)02d' % vars()
1895 upstring = ("%(name)-32s %(domid)5s " % d) + upstring
1897 print upstring
1899 def xm_sysrq(args):
1900 arg_check(args, "sysrq", 2)
1901 dom = args[0]
1902 req = args[1]
1903 if serverType == SERVER_XEN_API:
1904 server.xenapi.VM.send_sysrq(get_single_vm(dom), req)
1905 else:
1906 server.xend.domain.send_sysrq(dom, req)
1908 def xm_trigger(args):
1909 vcpu = 0
1911 arg_check(args, "trigger", 2, 3)
1912 dom = args[0]
1913 trigger = args[1]
1914 if len(args) == 3:
1915 vcpu = int(args[2])
1917 if serverType == SERVER_XEN_API:
1918 server.xenapi.VM.send_trigger(get_single_vm(dom), trigger, vcpu)
1919 else:
1920 server.xend.domain.send_trigger(dom, trigger, vcpu)
1922 def xm_debug_keys(args):
1923 arg_check(args, "debug-keys", 1)
1925 keys = str(args[0])
1927 if serverType == SERVER_XEN_API:
1928 server.xenapi.host.send_debug_keys(
1929 server.xenapi.session.get_this_host(server.getSession()),
1930 keys)
1931 else:
1932 server.xend.node.send_debug_keys(keys)
1934 def xm_top(args):
1935 arg_check(args, "top", 0)
1937 os.system('xentop')
1939 def xm_dmesg(args):
1940 arg_check(args, "dmesg", 0, 1)
1942 try:
1943 (options, params) = getopt.gnu_getopt(args, 'c', ['clear'])
1944 except getopt.GetoptError, opterr:
1945 err(opterr)
1946 usage('dmesg')
1948 use_clear = 0
1949 for (k, v) in options:
1950 if k in ['-c', '--clear']:
1951 use_clear = 1
1953 if len(params) :
1954 err("No parameter required")
1955 usage('dmesg')
1957 if serverType == SERVER_XEN_API:
1958 host = server.xenapi.session.get_this_host(server.getSession())
1959 if use_clear:
1960 print server.xenapi.host.dmesg_clear(host),
1961 else:
1962 print server.xenapi.host.dmesg(host),
1963 else:
1964 if not use_clear:
1965 print server.xend.node.dmesg.info(),
1966 else:
1967 print server.xend.node.dmesg.clear(),
1969 def xm_log(args):
1970 arg_check(args, "log", 0)
1972 if serverType == SERVER_XEN_API:
1973 print server.xenapi.host.get_log(
1974 server.xenapi.session.get_this_host(server.getSession()))
1975 else:
1976 print server.xend.node.log()
1978 def xm_serve(args):
1979 if serverType == SERVER_XEN_API:
1980 print "Not supported with XenAPI"
1981 sys.exit(-1)
1983 arg_check(args, "serve", 0)
1985 from fcntl import fcntl, F_SETFL
1987 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
1988 s.connect(XendClient.XML_RPC_SOCKET)
1989 fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK)
1991 while True:
1992 iwtd, owtd, ewtd = select([sys.stdin, s], [], [])
1993 if s in iwtd:
1994 data = s.recv(4096)
1995 if len(data) > 0:
1996 sys.stdout.write(data)
1997 sys.stdout.flush()
1998 else:
1999 break
2000 if sys.stdin in iwtd:
2001 data = sys.stdin.read(4096)
2002 if len(data) > 0:
2003 s.sendall(data)
2004 else:
2005 break
2006 s.close()
2008 def parse_dev_info(info):
2009 def get_info(n, t, d):
2010 i = 0
2011 while i < len(info):
2012 if (info[i][0] == n):
2013 return t(info[i][1])
2014 i = i + 1
2015 return t(d)
2016 return {
2017 #common
2018 'backend-id' : get_info('backend-id', int, -1),
2019 'handle' : get_info('handle', int, 0),
2020 'state' : get_info('state', int, -1),
2021 'be-path' : get_info('backend', str, '??'),
2022 'event-ch' : get_info('event-channel',int, -1),
2023 #network specific
2024 'virtual-device' : get_info('virtual-device', str, '??'),
2025 'tx-ring-ref': get_info('tx-ring-ref', int, -1),
2026 'rx-ring-ref': get_info('rx-ring-ref', int, -1),
2027 'mac' : get_info('mac', str, '??'),
2028 #block-device specific
2029 'ring-ref' : get_info('ring-ref', int, -1),
2032 def arg_check_for_resource_list(args, name):
2033 use_long = 0
2034 try:
2035 (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
2036 except getopt.GetoptError, opterr:
2037 err(opterr)
2038 sys.exit(1)
2040 for (k, v) in options:
2041 if k in ['-l', '--long']:
2042 use_long = 1
2044 if len(params) == 0:
2045 print 'No domain parameter given'
2046 usage(name)
2047 if len(params) > 1:
2048 print 'No multiple domain parameters allowed'
2049 usage(name)
2051 return (use_long, params)
2053 def xm_network_list(args):
2054 (use_long, params) = arg_check_for_resource_list(args, "network-list")
2056 dom = params[0]
2058 if serverType == SERVER_XEN_API:
2059 vif_refs = server.xenapi.VM.get_VIFs(get_single_vm(dom))
2060 vif_properties = \
2061 map(server.xenapi.VIF.get_runtime_properties, vif_refs)
2062 devs = map(lambda (handle, properties): [handle, map2sxp(properties)],
2063 zip(range(len(vif_properties)), vif_properties))
2064 else:
2065 devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
2067 if use_long:
2068 map(PrettyPrint.prettyprint, devs)
2069 else:
2070 hdr = 0
2071 for x in devs:
2072 if hdr == 0:
2073 print 'Idx BE MAC Addr. handle state evt-ch tx-/rx-ring-ref BE-path'
2074 hdr = 1
2075 ni = parse_dev_info(x[1])
2076 ni['idx'] = int(x[0])
2077 print ("%(idx)-3d "
2078 "%(backend-id)-3d"
2079 "%(mac)-17s "
2080 "%(handle)-3d "
2081 "%(state)-3d "
2082 "%(event-ch)-3d "
2083 "%(tx-ring-ref)-5d/%(rx-ring-ref)-5d "
2084 "%(be-path)-30s "
2085 % ni)
2087 def xm_block_list(args):
2088 (use_long, params) = arg_check_for_resource_list(args, "block-list")
2090 dom = params[0]
2092 if serverType == SERVER_XEN_API:
2093 vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
2094 vbd_properties = \
2095 map(server.xenapi.VBD.get_runtime_properties, vbd_refs)
2096 vbd_devs = \
2097 map(server.xenapi.VBD.get_device, vbd_refs)
2098 vbd_devids = [blkdev_name_to_number(x)[1] for x in vbd_devs]
2099 devs = map(lambda (devid, prop): [devid, map2sxp(prop)],
2100 zip(vbd_devids, vbd_properties))
2101 else:
2102 devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
2104 if use_long:
2105 map(PrettyPrint.prettyprint, devs)
2106 else:
2107 hdr = 0
2108 for x in devs:
2109 if hdr == 0:
2110 print 'Vdev BE handle state evt-ch ring-ref BE-path'
2111 hdr = 1
2112 ni = parse_dev_info(x[1])
2113 ni['idx'] = int(x[0])
2114 print ("%(idx)-5d "
2115 "%(backend-id)-3d "
2116 "%(handle)-3d "
2117 "%(state)-3d "
2118 "%(event-ch)-3d "
2119 "%(ring-ref)-5d "
2120 "%(be-path)-30s "
2121 % ni)
2123 def xm_vtpm_list(args):
2124 (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
2126 dom = params[0]
2128 if serverType == SERVER_XEN_API:
2129 vtpm_refs = server.xenapi.VM.get_VTPMs(get_single_vm(dom))
2130 vtpm_properties = \
2131 map(server.xenapi.VTPM.get_runtime_properties, vtpm_refs)
2132 devs = map(lambda (handle, properties): [handle, map2sxp(properties)],
2133 zip(range(len(vtpm_properties)), vtpm_properties))
2134 else:
2135 devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
2137 if use_long:
2138 map(PrettyPrint.prettyprint, devs)
2139 else:
2140 hdr = 0
2141 for x in devs:
2142 if hdr == 0:
2143 print 'Idx BE handle state evt-ch ring-ref BE-path'
2144 hdr = 1
2145 ni = parse_dev_info(x[1])
2146 ni['idx'] = int(x[0])
2147 print ("%(idx)-3d "
2148 "%(backend-id)-3d "
2149 "%(handle)-3d "
2150 "%(state)-3d "
2151 "%(event-ch)-3d "
2152 "%(ring-ref)-5d "
2153 "%(be-path)-30s "
2154 % ni)
2157 def xm_pci_list(args):
2158 (use_long, params) = arg_check_for_resource_list(args, "pci-list")
2160 dom = params[0]
2162 devs = []
2163 if serverType == SERVER_XEN_API:
2164 for dpci_ref in server.xenapi.VM.get_DPCIs(get_single_vm(dom)):
2165 ppci_ref = server.xenapi.DPCI.get_PPCI(dpci_ref)
2166 ppci_record = server.xenapi.PPCI.get_record(ppci_ref)
2167 dev = {
2168 "domain": "0x%04x" % int(ppci_record["domain"]),
2169 "bus": "0x%02x" % int(ppci_record["bus"]),
2170 "slot": "0x%02x" % int(ppci_record["slot"]),
2171 "func": "0x%01x" % int(ppci_record["func"]),
2172 "vslt": "0x%02x" % \
2173 int(server.xenapi.DPCI.get_hotplug_slot(dpci_ref))
2175 devs.append(dev)
2177 else:
2178 devs = server.xend.domain.getDeviceSxprs(dom, 'pci')
2180 if len(devs) == 0:
2181 return
2183 has_vslt = devs[0].has_key('vslt')
2184 if has_vslt:
2185 hdr_str = 'VSlt domain bus slot func'
2186 fmt_str = "%(vslt)-3s %(domain)-3s %(bus)-3s %(slot)-3s %(func)-3s "
2187 else:
2188 hdr_str = 'domain bus slot func'
2189 fmt_str = "%(domain)-3s %(bus)-3s %(slot)-3s %(func)-3s "
2190 hdr = 0
2192 for x in devs:
2193 if hdr == 0:
2194 print (hdr_str)
2195 hdr = 1
2196 print ( fmt_str % x )
2198 def xm_pci_list_assignable_devices(args):
2199 # Each element of dev_list is a PciDevice
2200 dev_list = find_all_devices_owned_by_pciback()
2202 # Each element of devs_list is a list of PciDevice
2203 devs_list = check_FLR_capability(dev_list)
2205 devs_list = check_mmio_bar(devs_list)
2207 # Check if the devices have been assigned to guests.
2208 final_devs_list = []
2209 for dev_list in devs_list:
2210 available = True
2211 for d in dev_list:
2212 pci_str = '0x%x,0x%x,0x%x,0x%x' %(d.domain, d.bus, d.slot, d.func)
2213 # Xen doesn't care what the domid is, so we pass 0 here...
2214 domid = 0
2215 bdf = xc.test_assign_device(domid, pci_str)
2216 if bdf != 0:
2217 available = False
2218 break
2219 if available:
2220 final_devs_list = final_devs_list + [dev_list]
2222 for dev_list in final_devs_list:
2223 for d in dev_list:
2224 print d.name,
2225 print
2227 def vscsi_convert_sxp_to_dict(dev_sxp):
2228 dev_dict = {}
2229 for opt_val in dev_sxp[1:]:
2230 try:
2231 opt, val = opt_val
2232 dev_dict[opt] = val
2233 except TypeError:
2234 pass
2235 return dev_dict
2237 def xm_scsi_list(args):
2238 xenapi_unsupported()
2239 (use_long, params) = arg_check_for_resource_list(args, "scsi-list")
2241 dom = params[0]
2243 devs = server.xend.domain.getDeviceSxprs(dom, 'vscsi')
2245 if use_long:
2246 map(PrettyPrint.prettyprint, devs)
2247 else:
2248 hdr = 0
2249 for x in devs:
2250 if hdr == 0:
2251 print "%-3s %-3s %-5s %-10s %-5s %-10s %-4s" \
2252 % ('Idx', 'BE', 'state', 'phy-hctl', 'phy', 'vir-hctl', 'devstate')
2253 hdr = 1
2254 ni = parse_dev_info(x[1])
2255 ni['idx'] = int(x[0])
2256 for dev in x[1][0][1]:
2257 mi = vscsi_convert_sxp_to_dict(dev)
2258 print "%(idx)-3d %(backend-id)-3d %(state)-5d " % ni,
2259 print "%(p-dev)-10s %(p-devname)-5s %(v-dev)-10s %(frontstate)-4s" % mi
2261 def parse_block_configuration(args):
2262 dom = args[0]
2264 if args[1].startswith('tap:'):
2265 cls = 'tap'
2266 else:
2267 cls = 'vbd'
2269 vbd = [cls,
2270 ['uname', args[1]],
2271 ['dev', args[2]],
2272 ['mode', args[3]]]
2273 if len(args) == 5:
2274 vbd.append(['backend', args[4]])
2276 return (dom, vbd)
2279 def xm_block_attach(args):
2280 arg_check(args, 'block-attach', 4, 5)
2282 if serverType == SERVER_XEN_API:
2283 dom = args[0]
2284 uname = args[1]
2285 dev = args[2]
2286 mode = args[3]
2288 # First create new VDI
2289 vdi_record = {
2290 "name_label": "vdi" + str(uname.__hash__()),
2291 "name_description": "",
2292 "SR": get_default_SR(),
2293 "virtual_size": 0,
2294 "sector_size": 512,
2295 "type": "system",
2296 "sharable": False,
2297 "read_only": mode!="w",
2298 "other_config": {"location": uname}
2301 vdi_ref = server.xenapi.VDI.create(vdi_record)
2303 # Now create new VBD
2305 vbd_record = {
2306 "VM": get_single_vm(dom),
2307 "VDI": vdi_ref,
2308 "device": dev,
2309 "bootable": True,
2310 "mode": mode=="w" and "RW" or "RO",
2311 "type": "Disk",
2312 "qos_algorithm_type": "",
2313 "qos_algorithm_params": {}
2316 server.xenapi.VBD.create(vbd_record)
2318 else:
2319 (dom, vbd) = parse_block_configuration(args)
2320 server.xend.domain.device_create(dom, vbd)
2323 def xm_block_configure(args):
2324 arg_check(args, 'block-configure', 4, 5)
2326 (dom, vbd) = parse_block_configuration(args)
2327 server.xend.domain.device_configure(dom, vbd)
2330 def xm_network_attach(args):
2331 arg_check(args, 'network-attach', 1, 11)
2333 dom = args[0]
2334 vif = ['vif']
2335 vif_params = ['type', 'mac', 'bridge', 'ip', 'script', \
2336 'backend', 'vifname', 'rate', 'model', 'accel']
2338 if serverType == SERVER_XEN_API:
2339 vif_record = {
2340 "device": "eth0",
2341 "network": get_default_Network(),
2342 "VM": get_single_vm(dom),
2343 "MAC": "",
2344 "MTU": "",
2345 "qos_algorithm_type": "",
2346 "qos_algorithm_params": {},
2347 "other_config": {}
2350 def set(keys, val):
2351 record = vif_record
2352 for key in keys[:-1]:
2353 record = record[key]
2354 record[keys[-1]] = val
2356 def get_net_from_bridge(bridge):
2357 # In OSS, we just assert network.name_label == bridge name
2358 networks = dict([(record['name_label'], ref)
2359 for ref, record in server.xenapi.network
2360 .get_all_records().items()])
2361 if bridge not in networks.keys():
2362 raise "Unknown bridge name!"
2363 return networks[bridge]
2365 vif_conv = {
2366 'type':
2367 lambda x: None,
2368 'mac':
2369 lambda x: set(['MAC'], x),
2370 'bridge':
2371 lambda x: set(['network'], get_net_from_bridge(x)),
2372 'ip':
2373 lambda x: set(['other_config', 'ip'], x),
2374 'script':
2375 lambda x: set(['other_config', 'script'], x),
2376 'backend':
2377 lambda x: set(['other_config', 'backend'], x),
2378 'vifname':
2379 lambda x: set(['device'], x),
2380 'rate':
2381 lambda x: set(['qos_algorithm_params', 'rate'], x),
2382 'model':
2383 lambda x: None,
2384 'accel':
2385 lambda x: set(['other_config', 'accel'], x)
2388 for a in args[1:]:
2389 vif_param = a.split("=")
2390 if len(vif_param) != 2 or vif_param[1] == '' or \
2391 vif_param[0] not in vif_params:
2392 err("Invalid argument: %s" % a)
2393 usage('network-attach')
2394 else:
2395 vif_conv[vif_param[0]](vif_param[1])
2397 server.xenapi.VIF.create(vif_record)
2398 else:
2399 for a in args[1:]:
2400 vif_param = a.split("=")
2401 if len(vif_param) != 2 or vif_param[1] == '' or \
2402 vif_param[0] not in vif_params:
2403 err("Invalid argument: %s" % a)
2404 usage('network-attach')
2405 vif.append(vif_param)
2406 server.xend.domain.device_create(dom, vif)
2408 def parse_pci_configuration(args, state):
2409 dom = args[0]
2410 pci_dev_str = args[1]
2411 if len(args) == 3:
2412 vslt = args[2]
2413 else:
2414 vslt = '0x0' #chose a free virtual PCI slot
2415 pci=['pci']
2416 pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
2417 r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
2418 r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
2419 r"(?P<func>[0-7])$", pci_dev_str)
2420 if pci_match == None:
2421 raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
2422 pci_dev_info = pci_match.groupdict('0')
2423 try:
2424 pci.append(['dev', ['domain', '0x'+ pci_dev_info['domain']], \
2425 ['bus', '0x'+ pci_dev_info['bus']],
2426 ['slot', '0x'+ pci_dev_info['slot']],
2427 ['func', '0x'+ pci_dev_info['func']],
2428 ['vslt', '0x%x' % int(vslt, 16)]])
2429 except:
2430 raise OptionError("Invalid argument: %s %s" % (pci_dev_str,vslt))
2431 pci.append(['state', state])
2433 return (dom, pci)
2435 def xm_pci_attach(args):
2436 arg_check(args, 'pci-attach', 2, 3)
2437 (dom, pci) = parse_pci_configuration(args, 'Initialising')
2439 if serverType == SERVER_XEN_API:
2441 pci_dev = sxp.children(pci, 'dev')[0]
2442 domain = int(sxp.child_value(pci_dev, 'domain'), 16)
2443 bus = int(sxp.child_value(pci_dev, 'bus'), 16)
2444 slot = int(sxp.child_value(pci_dev, 'slot'), 16)
2445 func = int(sxp.child_value(pci_dev, 'func'), 16)
2446 vslt = int(sxp.child_value(pci_dev, 'vslt'), 16)
2447 name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
2449 target_ref = None
2450 for ppci_ref in server.xenapi.PPCI.get_all():
2451 if name == server.xenapi.PPCI.get_name(ppci_ref):
2452 target_ref = ppci_ref
2453 break
2454 if target_ref is None:
2455 raise OptionError("Device %s not found" % name)
2457 dpci_record = {
2458 "VM": get_single_vm(dom),
2459 "PPCI": target_ref,
2460 "hotplug_slot": vslt
2462 server.xenapi.DPCI.create(dpci_record)
2464 else:
2465 server.xend.domain.device_configure(dom, pci)
2467 def xm_scsi_attach(args):
2468 xenapi_unsupported()
2470 arg_check(args, 'scsi-attach', 3, 4)
2471 p_devname = args[1]
2472 v_dev = args[2]
2474 v_hctl = v_dev.split(':')
2475 if len(v_hctl) != 4:
2476 raise OptionError("Invalid argument: %s" % v_dev)
2478 (p_hctl, block) = vscsi_util.vscsi_search_hctl_and_block(p_devname)
2480 if p_hctl == None:
2481 raise OptionError("Cannot find device \"%s\"" % p_devname)
2483 dom = args[0]
2484 vscsi = ['vscsi']
2485 vscsi.append(['dev', \
2486 ['state', 'Initialising'], \
2487 ['devid', v_hctl[0]], \
2488 ['p-dev', p_hctl], \
2489 ['p-devname', block], \
2490 ['v-dev', v_dev] ])
2492 if len(args) == 4:
2493 vscsi.append(['backend', args[3]])
2495 vscsi.append(['state', 'Initialising'])
2496 vscsi.append(['devid', v_hctl[0]])
2497 server.xend.domain.device_configure(dom, vscsi)
2499 def detach(args, deviceClass):
2500 rm_cfg = True
2501 dom = args[0]
2502 dev = args[1]
2503 try:
2504 force = args[2]
2505 if (force != "--force") and (force != "-f"):
2506 print "Ignoring option %s"%(force)
2507 force = None
2508 except IndexError:
2509 force = None
2511 server.xend.domain.destroyDevice(dom, deviceClass, dev, force, rm_cfg)
2514 def xm_block_detach(args):
2515 if serverType == SERVER_XEN_API:
2516 arg_check(args, "block-detach", 2, 3)
2517 dom = args[0]
2518 dev = args[1]
2519 vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
2520 vbd_refs = [vbd_ref for vbd_ref in vbd_refs
2521 if server.xenapi.VBD.get_device(vbd_ref) == dev]
2522 if len(vbd_refs) > 0:
2523 vbd_ref = vbd_refs[0]
2524 vdi_ref = server.xenapi.VBD.get_VDI(vbd_ref)
2526 server.xenapi.VBD.destroy(vbd_ref)
2528 if len(server.xenapi.VDI.get_VBDs(vdi_ref)) <= 0:
2529 server.xenapi.VDI.destroy(vdi_ref)
2530 else:
2531 raise OptionError("Cannot find device '%s' in domain '%s'"
2532 % (dev,dom))
2533 else:
2534 arg_check(args, 'block-detach', 2, 3)
2535 dom = args[0]
2536 dev = args[1]
2537 dc = server.xend.domain.getBlockDeviceClass(dom, dev)
2538 if dc == "tap":
2539 detach(args, 'tap')
2540 else:
2541 detach(args, 'vbd')
2543 def xm_network_detach(args):
2544 if serverType == SERVER_XEN_API:
2545 arg_check(args, "network-detach", 2, 3)
2546 dom = args[0]
2547 devid = args[1]
2548 vif_refs = server.xenapi.VM.get_VIFs(get_single_vm(dom))
2549 vif_refs = [vif_ref for vif_ref in vif_refs
2550 if server.xenapi.VIF.\
2551 get_runtime_properties(vif_ref)["handle"] == devid]
2552 if len(vif_refs) > 0:
2553 vif_ref = vif_refs[0]
2555 server.xenapi.VIF.destroy(vif_ref)
2556 else:
2557 print "Cannot find device '%s' in domain '%s'" % (devid,dom)
2558 else:
2559 arg_check(args, 'network-detach', 2, 3)
2560 detach(args, 'vif')
2562 def xm_pci_detach(args):
2563 arg_check(args, 'pci-detach', 2)
2564 (dom, pci) = parse_pci_configuration(args, 'Closing')
2566 if serverType == SERVER_XEN_API:
2568 pci_dev = sxp.children(pci, 'dev')[0]
2569 domain = int(sxp.child_value(pci_dev, 'domain'), 16)
2570 bus = int(sxp.child_value(pci_dev, 'bus'), 16)
2571 slot = int(sxp.child_value(pci_dev, 'slot'), 16)
2572 func = int(sxp.child_value(pci_dev, 'func'), 16)
2573 vslt = int(sxp.child_value(pci_dev, 'vslt'), 16)
2574 name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
2576 target_ref = None
2577 for dpci_ref in server.xenapi.VM.get_DPCIs(get_single_vm(dom)):
2578 ppci_ref = server.xenapi.DPCI.get_PPCI(dpci_ref)
2579 if name == server.xenapi.PPCI.get_name(ppci_ref):
2580 target_ref = ppci_ref
2581 server.xenapi.DPCI.destroy(dpci_ref)
2582 break
2583 if target_ref is None:
2584 raise OptionError("Device %s not assigned" % name)
2586 else:
2587 server.xend.domain.device_configure(dom, pci)
2589 def xm_scsi_detach(args):
2590 xenapi_unsupported()
2591 arg_check(args, 'scsi-detach', 2)
2593 v_dev = args[1]
2594 v_hctl = v_dev.split(':')
2595 if len(v_hctl) != 4:
2596 raise OptionError("Invalid argument: %s" % v_dev)
2598 dom = args[0]
2599 vscsi = ['vscsi']
2600 vscsi.append(['dev', \
2601 ['state', 'Closing'], \
2602 ['devid', v_hctl[0]], \
2603 ['p-dev', ''], \
2604 ['p-devname', ''], \
2605 ['v-dev', v_dev] ])
2607 vscsi.append(['state', 'Closing'])
2608 vscsi.append(['devid', v_hctl[0]])
2609 server.xend.domain.device_configure(dom, vscsi)
2611 def xm_vnet_list(args):
2612 xenapi_unsupported()
2613 try:
2614 (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
2615 except getopt.GetoptError, opterr:
2616 err(opterr)
2617 usage('vnet-list')
2619 use_long = 0
2620 for (k, v) in options:
2621 if k in ['-l', '--long']:
2622 use_long = 1
2624 if params:
2625 use_long = 1
2626 vnets = params
2627 else:
2628 vnets = server.xend_vnets()
2630 for vnet in vnets:
2631 try:
2632 if use_long:
2633 info = server.xend_vnet(vnet)
2634 PrettyPrint.prettyprint(info)
2635 else:
2636 print vnet
2637 except Exception, ex:
2638 print vnet, ex
2640 def xm_vnet_create(args):
2641 xenapi_unsupported()
2642 arg_check(args, "vnet-create", 1)
2643 conf = args[0]
2644 if not os.access(conf, os.R_OK):
2645 print "File not found: %s" % conf
2646 sys.exit(1)
2648 server.xend_vnet_create(conf)
2650 def xm_vnet_delete(args):
2651 xenapi_unsupported()
2652 arg_check(args, "vnet-delete", 1)
2653 vnet = args[0]
2654 server.xend_vnet_delete(vnet)
2656 def xm_network_new(args):
2657 xenapi_only()
2658 arg_check(args, "network-new", 1)
2659 network = args[0]
2661 record = {
2662 "name_label": network,
2663 "name_description": "",
2664 "other_config": {},
2665 "default_gateway": "",
2666 "default_netmask": ""
2669 server.xenapi.network.create(record)
2671 def xm_network_del(args):
2672 xenapi_only()
2673 arg_check(args, "network-del", 1)
2674 network = args[0]
2676 networks = dict([(record['name_label'], ref)
2677 for ref, record in
2678 server.xenapi.network.get_all_records().items()])
2680 if network not in networks.keys():
2681 raise ValueError("'%s' is not a valid network name" % network)
2683 server.xenapi.network.destroy(networks[network])
2685 def xm_network_show(args):
2686 xenapi_only()
2687 arg_check(args, "network-show", 0)
2689 networks = server.xenapi.network.get_all_records()
2690 pifs = server.xenapi.PIF.get_all_records()
2691 vifs = server.xenapi.VIF.get_all_records()
2693 print '%-20s %-40s %-10s' % \
2694 ('Name', 'VIFs', 'PIFs')
2696 format2 = "%(name_label)-20s %(vif)-40s %(pif)-10s"
2698 for network_ref, network in networks.items():
2699 for i in range(max(len(network['PIFs']),
2700 len(network['VIFs']), 1)):
2701 if i < len(network['PIFs']):
2702 pif_uuid = network['PIFs'][i]
2703 else:
2704 pif_uuid = None
2706 if i < len(network['VIFs']):
2707 vif_uuid = network['VIFs'][i]
2708 else:
2709 vif_uuid = None
2711 pif = pifs.get(pif_uuid, None)
2712 vif = vifs.get(vif_uuid, None)
2714 if vif:
2715 dom_name = server.xenapi.VM.get_name_label(vif['VM'])
2716 vif = "%s.%s" % (dom_name, vif['device'])
2717 else:
2718 vif = ''
2720 if pif:
2721 if int(pif['VLAN']) > -1:
2722 pif = '%s.%s' % (pif['device'], pif['VLAN'])
2723 else:
2724 pif = pif['device']
2725 else:
2726 pif = ''
2728 if i == 0:
2729 r = {'name_label':network['name_label'],
2730 'vif':vif, 'pif':pif}
2731 else:
2732 r = {'name_label':'', 'vif':vif, 'pif':pif}
2734 print format2 % r
2737 commands = {
2738 "shell": xm_shell,
2739 "event-monitor": xm_event_monitor,
2740 # console commands
2741 "console": xm_console,
2742 "vncviewer": xm_vncviewer,
2743 # xenstat commands
2744 "top": xm_top,
2745 # domain commands
2746 "delete": xm_delete,
2747 "destroy": xm_destroy,
2748 "domid": xm_domid,
2749 "domname": xm_domname,
2750 "dump-core": xm_dump_core,
2751 "reboot": xm_reboot,
2752 "rename": xm_rename,
2753 "reset": xm_reset,
2754 "restore": xm_restore,
2755 "resume": xm_resume,
2756 "save": xm_save,
2757 "shutdown": xm_shutdown,
2758 "start": xm_start,
2759 "sysrq": xm_sysrq,
2760 "trigger": xm_trigger,
2761 "uptime": xm_uptime,
2762 "suspend": xm_suspend,
2763 "list": xm_list,
2764 # memory commands
2765 "mem-max": xm_mem_max,
2766 "mem-set": xm_mem_set,
2767 # cpu commands
2768 "vcpu-pin": xm_vcpu_pin,
2769 "vcpu-list": xm_vcpu_list,
2770 "vcpu-set": xm_vcpu_set,
2771 # special
2772 "pause": xm_pause,
2773 "unpause": xm_unpause,
2774 # host commands
2775 "debug-keys": xm_debug_keys,
2776 "dmesg": xm_dmesg,
2777 "info": xm_info,
2778 "log": xm_log,
2779 "serve": xm_serve,
2780 # scheduler
2781 "sched-sedf": xm_sched_sedf,
2782 "sched-credit": xm_sched_credit,
2783 # block
2784 "block-attach": xm_block_attach,
2785 "block-detach": xm_block_detach,
2786 "block-list": xm_block_list,
2787 "block-configure": xm_block_configure,
2788 # network (AKA vifs)
2789 "network-attach": xm_network_attach,
2790 "network-detach": xm_network_detach,
2791 "network-list": xm_network_list,
2792 # network (as in XenAPI)
2793 "network-new": xm_network_new,
2794 "network-del": xm_network_del,
2795 "network-show": xm_network_show,
2796 # vnet
2797 "vnet-list": xm_vnet_list,
2798 "vnet-create": xm_vnet_create,
2799 "vnet-delete": xm_vnet_delete,
2800 # vtpm
2801 "vtpm-list": xm_vtpm_list,
2802 #pci
2803 "pci-attach": xm_pci_attach,
2804 "pci-detach": xm_pci_detach,
2805 "pci-list": xm_pci_list,
2806 "pci-list-assignable-devices": xm_pci_list_assignable_devices,
2807 # vscsi
2808 "scsi-attach": xm_scsi_attach,
2809 "scsi-detach": xm_scsi_detach,
2810 "scsi-list": xm_scsi_list,
2813 ## The commands supported by a separate argument parser in xend.xm.
2814 IMPORTED_COMMANDS = [
2815 'create',
2816 'new',
2817 'migrate',
2818 'labels',
2819 'dumppolicy',
2820 'addlabel',
2821 'rmlabel',
2822 'getlabel',
2823 'dry-run',
2824 'resources',
2825 'getpolicy',
2826 'setpolicy',
2827 'resetpolicy',
2830 for c in IMPORTED_COMMANDS:
2831 commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c)
2833 aliases = {
2834 "balloon": "mem-set",
2835 "set-vcpus": "vcpu-set",
2836 "vif-list": "network-list",
2837 "vbd-create": "block-attach",
2838 "vbd-destroy": "block-detach",
2839 "vbd-list": "block-list",
2843 def xm_lookup_cmd(cmd):
2844 if commands.has_key(cmd):
2845 return commands[cmd]
2846 elif aliases.has_key(cmd):
2847 deprecated(cmd,aliases[cmd])
2848 return commands[aliases[cmd]]
2849 elif cmd == 'help':
2850 longHelp()
2851 sys.exit(0)
2852 else:
2853 # simulate getopt's prefix matching behaviour
2854 if len(cmd) > 1:
2855 same_prefix_cmds = [commands[c] for c in commands.keys() \
2856 if c[:len(cmd)] == cmd]
2857 # only execute if there is only 1 match
2858 if len(same_prefix_cmds) == 1:
2859 return same_prefix_cmds[0]
2860 return None
2862 def deprecated(old,new):
2863 print >>sys.stderr, (
2864 "Command %s is deprecated. Please use xm %s instead." % (old, new))
2866 def main(argv=sys.argv):
2867 if len(argv) < 2:
2868 usage()
2870 # intercept --help(-h) and output our own help
2871 for help in ['--help', '-h']:
2872 if help in argv[1:]:
2873 if help == argv[1]:
2874 longHelp()
2875 sys.exit(0)
2876 else:
2877 usage(argv[1])
2879 cmd_name = argv[1]
2880 cmd = xm_lookup_cmd(cmd_name)
2881 if cmd:
2882 # strip off prog name and subcmd
2883 args = argv[2:]
2884 _, rc = _run_cmd(cmd, cmd_name, args)
2885 sys.exit(rc)
2886 else:
2887 err('Subcommand %s not found!' % cmd_name)
2888 usage()
2890 def _run_cmd(cmd, cmd_name, args):
2891 global server
2893 try:
2894 if server is None:
2895 if serverType == SERVER_XEN_API:
2896 server = XenAPI.Session(serverURI)
2897 username, password = parseAuthentication()
2898 server.login_with_password(username, password)
2899 def logout():
2900 try:
2901 server.xenapi.session.logout()
2902 except:
2903 pass
2904 atexit.register(logout)
2905 else:
2906 server = ServerProxy(serverURI)
2908 return True, cmd(args)
2909 except socket.error, ex:
2910 if os.geteuid() != 0:
2911 err("Most commands need root access. Please try again as root.")
2912 else:
2913 err("Unable to connect to xend: %s. Is xend running?" % ex[1])
2914 except KeyboardInterrupt:
2915 print "Interrupted."
2916 return True, ''
2917 except IOError, ex:
2918 if os.geteuid() != 0:
2919 err("Most commands need root access. Please try again as root.")
2920 else:
2921 err("Unable to connect to xend: %s." % ex[1])
2922 except SystemExit, code:
2923 return code == 0, code
2924 except XenAPI.Failure, exn:
2925 for line in [''] + wrap(str(exn), 80) + ['']:
2926 print >>sys.stderr, line
2927 except xmlrpclib.Fault, ex:
2928 if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
2929 err("Domain '%s' does not exist." % ex.faultString)
2930 return False, ex.faultCode
2931 else:
2932 err(ex.faultString)
2933 _usage(cmd_name)
2934 except xmlrpclib.ProtocolError, ex:
2935 if ex.errcode == -1:
2936 print >>sys.stderr, (
2937 "Xend has probably crashed! Invalid or missing HTTP "
2938 "status code.")
2939 else:
2940 print >>sys.stderr, (
2941 "Xend has probably crashed! ProtocolError(%d, %s)." %
2942 (ex.errcode, ex.errmsg))
2943 except (ValueError, OverflowError):
2944 err("Invalid argument.")
2945 _usage(cmd_name)
2946 except OptionError, e:
2947 err(str(e))
2948 _usage(cmd_name)
2949 print e.usage
2950 except XenAPIUnsupportedException, e:
2951 err(str(e))
2952 except XSMError, e:
2953 err(str(e))
2954 except Exception, e:
2955 if serverType != SERVER_XEN_API:
2956 import xen.util.xsm.xsm as security
2957 if isinstance(e, security.XSMError):
2958 err(str(e))
2959 return False, 1
2960 print "Unexpected error:", sys.exc_info()[0]
2961 print
2962 print "Please report to xen-devel@lists.xensource.com"
2963 raise
2965 return False, 1
2967 if __name__ == "__main__":
2968 main()