debuggers.hg

annotate tools/python/xen/xm/create.py @ 3639:ef59b38283a5

bitkeeper revision 1.1159.212.64 (42000361XrdUoEK_vD6RMga2eLmwZg)

Allow specification of backend vif MAC addresses. If a backend
MAC is not provided, generate one as before

Signed-off-by: Jody Belka <knew-xen@pimb.org>
Signed-off-by: ian.pratt@cl.cam.ac.uk
author iap10@labyrinth.cl.cam.ac.uk
date Tue Feb 01 22:32:01 2005 +0000 (2005-02-01)
parents 3ced9b0f4dab
children bbe8541361dd
rev   line source
mjw@1661 1 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
mjw@1693 2
mjw@1661 3 """Domain creation.
mjw@1661 4 """
mjw@1761 5 import random
mjw@1661 6 import string
mjw@1661 7 import sys
mjw@1661 8
mjw@1661 9 from xen.xend import sxp
mjw@1661 10 from xen.xend import PrettyPrint
mjw@1759 11 from xen.xend.XendClient import server, XendError
mjw@1661 12
kaf24@1676 13 from xen.util import console_client
kaf24@1676 14
mjw@1661 15 from xen.xm.opts import *
mjw@1661 16
mjw@1719 17 gopts = Opts(use="""[options] [vars]
mjw@1661 18
mjw@1661 19 Create a domain.
mjw@1693 20
mjw@1693 21 Domain creation parameters can be set by command-line switches, from
mjw@1693 22 a python configuration script or an SXP config file. See documentation
mjw@2327 23 for --defconfig, --config. Configuration variables can be set using
mjw@1693 24 VAR=VAL on the command line. For example vmid=3 sets vmid to 3.
mjw@1693 25
mjw@1661 26 """)
mjw@1661 27
mjw@1661 28 gopts.opt('help', short='h',
mjw@2327 29 fn=set_true, default=0,
mjw@2327 30 use="Print this help.")
mjw@1661 31
mjw@1693 32 gopts.opt('help_config',
mjw@1693 33 fn=set_true, default=0,
mjw@2327 34 use="Print help for the configuration script.")
mjw@1693 35
mjw@1661 36 gopts.opt('quiet', short='q',
mjw@2327 37 fn=set_true, default=0,
mjw@2327 38 use="Quiet.")
mjw@1661 39
mjw@1661 40 gopts.opt('path', val='PATH',
mjw@2327 41 fn=set_value, default='.:/etc/xen',
mjw@2327 42 use="""Search path for configuration scripts.
mjw@2327 43 The value of PATH is a colon-separated directory list.""")
mjw@1661 44
mjw@2327 45 gopts.opt('defconfig', short='f', val='FILE',
mjw@2327 46 fn=set_value, default='xmdefconfig',
mjw@2327 47 use="""Use the given Python configuration script.
mjw@2327 48 The configuration script is loaded after arguments have been processed.
mjw@2327 49 Each command-line option sets a configuration variable named after
mjw@2327 50 its long option name, and these variables are placed in the
mjw@2327 51 environment of the script before it is loaded.
mjw@2327 52 Variables for options that may be repeated have list values.
mjw@2327 53 Other variables can be set using VAR=VAL on the command line.
mjw@2327 54
mjw@2327 55 After the script is loaded, option values that were not set on the
mjw@2327 56 command line are replaced by the values set in the script.""")
mjw@1661 57
cl349@2793 58 gopts.default('defconfig')
cl349@2793 59
mjw@1661 60 gopts.opt('config', short='F', val='FILE',
mjw@2327 61 fn=set_value, default=None,
mjw@2327 62 use="""Domain configuration to use (SXP).
mjw@2327 63 SXP is the underlying configuration format used by Xen.
mjw@2327 64 SXP configurations can be hand-written or generated from Python configuration
mjw@2327 65 scripts, using the -n (dryrun) option to print the configuration.""")
mjw@1661 66
mjw@1661 67 gopts.opt('load', short='L', val='FILE',
mjw@1661 68 fn=set_value, default=None,
mjw@1661 69 use='Domain saved state to load.')
mjw@1661 70
mjw@1661 71 gopts.opt('dryrun', short='n',
mjw@1824 72 fn=set_true, default=0,
mjw@2327 73 use="""Dry run - print the configuration but don't create the domain.
mjw@2327 74 Loads the configuration script, creates the SXP configuration and prints it.""")
mjw@1661 75
mjw@2242 76 gopts.opt('paused', short='p',
mjw@2242 77 fn=set_true, default=0,
mjw@2242 78 use='Leave the domain paused after it is created.')
mjw@2242 79
kaf24@1676 80 gopts.opt('console_autoconnect', short='c',
mjw@1824 81 fn=set_true, default=0,
mjw@2242 82 use="Connect to the console after the domain is created.")
mjw@1661 83
mjw@1719 84 gopts.var('name', val='NAME',
mjw@1719 85 fn=set_value, default=None,
mjw@2327 86 use="Domain name. Must be unique.")
mjw@1719 87
mjw@1719 88 gopts.var('kernel', val='FILE',
mjw@1824 89 fn=set_value, default=None,
mjw@1824 90 use="Path to kernel image.")
mjw@1661 91
mjw@1719 92 gopts.var('ramdisk', val='FILE',
mjw@1824 93 fn=set_value, default='',
mjw@1824 94 use="Path to ramdisk.")
mjw@1661 95
mjw@1719 96 gopts.var('builder', val='FUNCTION',
mjw@1824 97 fn=set_value, default='linux',
mjw@1824 98 use="Function to use to build the domain.")
mjw@1661 99
mjw@1719 100 gopts.var('memory', val='MEMORY',
mjw@2327 101 fn=set_int, default=128,
mjw@1824 102 use="Domain memory in MB.")
mjw@1824 103
mjw@2441 104 gopts.var('maxmem', val='MEMORY',
mjw@2441 105 fn=set_int, default=None,
mjw@2441 106 use="Maximum domain memory in MB.")
mjw@2441 107
mjw@2327 108 gopts.var('cpu', val='CPU',
mjw@2327 109 fn=set_int, default=None,
mjw@2327 110 use="CPU to run the domain on.")
mjw@2327 111
cl349@3489 112 gopts.var('vcpus', val='VCPUS',
cl349@3489 113 fn=set_int, default=1,
cl349@3489 114 use="# of Virtual CPUS in domain.")
cl349@3489 115
mjw@2288 116 gopts.var('cpu_weight', val='WEIGHT',
mjw@2327 117 fn=set_float, default=None,
mjw@2327 118 use="""Set the new domain's cpu weight.
mjw@2327 119 WEIGHT is a float that controls the domain's share of the cpu.""")
gm281@2274 120
mjw@1824 121 gopts.var('console', val='PORT',
mjw@1824 122 fn=set_int, default=None,
mjw@1824 123 use="Console port to use. Default is 9600 + domain id.")
mjw@1661 124
mjw@1823 125 gopts.var('restart', val='onreboot|always|never',
mjw@1824 126 fn=set_value, default=None,
mjw@1824 127 use="""Whether the domain should be restarted on exit.
mjw@2327 128 - onreboot: restart on exit with shutdown code reboot
mjw@2327 129 - always: always restart on exit, ignore exit code
mjw@2327 130 - never: never restart on exit, ignore exit code""")
mjw@1711 131
mjw@1719 132 gopts.var('blkif', val='no|yes',
mjw@1719 133 fn=set_bool, default=0,
mjw@1661 134 use="Make the domain a block device backend.")
mjw@1661 135
mjw@1719 136 gopts.var('netif', val='no|yes',
mjw@1719 137 fn=set_bool, default=0,
mjw@1661 138 use="Make the domain a network interface backend.")
mjw@1661 139
mjw@2305 140 gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
mjw@1824 141 fn=append_value, default=[],
mjw@1824 142 use="""Add a disk device to a domain. The physical device is DEV,
mjw@2327 143 which is exported to the domain as VDEV. The disk is read-only if MODE
mjw@2327 144 is 'r', read-write if MODE is 'w'. If DOM is specified it defines the
mjw@2327 145 backend driver domain to use for the disk.
mjw@2327 146 The option may be repeated to add more than one disk.""")
mjw@1661 147
mjw@1719 148 gopts.var('pci', val='BUS,DEV,FUNC',
mjw@1824 149 fn=append_value, default=[],
mjw@1824 150 use="""Add a PCI device to a domain, using given params (in hex).
mjw@1661 151 For example '-pci c0,02,1a'.
mjw@2327 152 The option may be repeated to add more than one pci device.""")
mjw@1661 153
mwilli2@3501 154 gopts.var('usb', val='PATH',
mwilli2@3501 155 fn=append_value, default=[],
mwilli2@3501 156 use="""Add a physical USB port to a domain, as specified by the path
mwilli2@3501 157 to that port. This option may be repeated to add more than one port.""")
mwilli2@3501 158
mjw@1719 159 gopts.var('ipaddr', val="IPADDR",
mjw@1824 160 fn=append_value, default=[],
mjw@1824 161 use="Add an IP address to the domain.")
mjw@1661 162
iap10@3639 163 gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
mjw@1824 164 fn=append_value, default=[],
mjw@1824 165 use="""Add a network interface with the given MAC address and bridge.
mjw@2327 166 The vif is configured by calling the given configuration script.
mjw@2327 167 If mac is not specified a random MAC address is used.
iap10@3639 168 The MAC address of the backend interface can be selected with be_mac.
iap10@3639 169 If not specified then the network backend chooses it's own MAC address.
mjw@2327 170 If bridge is not specified the default bridge is used.
mjw@2327 171 If script is not specified the default script is used.
mjw@2327 172 If backend is not specified the default backend driver domain is used.
mjw@2327 173 This option may be repeated to add more than one vif.
mjw@2327 174 Specifying vifs will increase the number of interfaces as needed.""")
mjw@1661 175
mjw@1719 176 gopts.var('nics', val="NUM",
mjw@1824 177 fn=set_int, default=1,
mjw@1824 178 use="""Set the number of network interfaces.
mjw@2327 179 Use the vif option to define interface parameters, otherwise
mjw@2327 180 defaults are used. Specifying vifs will increase the
mjw@2327 181 number of interfaces as needed.""")
mjw@1661 182
mjw@1719 183 gopts.var('root', val='DEVICE',
mjw@1824 184 fn=set_value, default='',
mjw@1824 185 use="""Set the root= parameter on the kernel command line.
mjw@2327 186 Use a device, e.g. /dev/sda1, or /dev/nfs for NFS root.""")
mjw@1661 187
mjw@1719 188 gopts.var('extra', val="ARGS",
mjw@1824 189 fn=set_value, default='',
mjw@1824 190 use="Set extra arguments to append to the kernel command line.")
mjw@1661 191
mjw@1719 192 gopts.var('ip', val='IPADDR',
mjw@1824 193 fn=set_value, default='',
mjw@1824 194 use="Set the kernel IP interface address.")
mjw@1661 195
mjw@1719 196 gopts.var('gateway', val="IPADDR",
mjw@1824 197 fn=set_value, default='',
mjw@1824 198 use="Set the kernel IP gateway.")
mjw@1661 199
mjw@1719 200 gopts.var('netmask', val="MASK",
mjw@1824 201 fn=set_value, default = '',
mjw@1824 202 use="Set the kernel IP netmask.")
mjw@1661 203
mjw@1719 204 gopts.var('hostname', val="NAME",
mjw@1824 205 fn=set_value, default='',
mjw@1824 206 use="Set the kernel IP hostname.")
mjw@1661 207
mjw@1719 208 gopts.var('interface', val="INTF",
mjw@1824 209 fn=set_value, default="eth0",
mjw@1824 210 use="Set the kernel IP interface name.")
mjw@1661 211
mjw@1719 212 gopts.var('dhcp', val="off|dhcp",
mjw@1824 213 fn=set_value, default='off',
mjw@1824 214 use="Set the kernel dhcp option.")
mjw@1661 215
mjw@1719 216 gopts.var('nfs_server', val="IPADDR",
mjw@1824 217 fn=set_value, default=None,
mjw@1824 218 use="Set the address of the NFS server for NFS root.")
mjw@1661 219
mjw@1719 220 gopts.var('nfs_root', val="PATH",
mjw@1824 221 fn=set_value, default=None,
mjw@1824 222 use="Set the path of the root NFS directory.")
mjw@1661 223
iap10@3428 224 gopts.var('memmap', val='FILE',
iap10@3428 225 fn=set_value, default='',
iap10@3428 226 use="Path to memap SXP file.")
iap10@3428 227
iap10@3428 228 gopts.var('device_model', val='FILE',
iap10@3428 229 fn=set_value, default='',
iap10@3428 230 use="Path to device model program.")
iap10@3428 231
iap10@3428 232 gopts.var('device_config', val='FILE',
iap10@3428 233 fn=set_value, default='',
iap10@3428 234 use="Path to device model configuration.")
iap10@3428 235
mjw@1661 236 def strip(pre, s):
mjw@1661 237 """Strip prefix 'pre' if present.
mjw@1661 238 """
mjw@1661 239 if s.startswith(pre):
mjw@1661 240 return s[len(pre):]
mjw@1661 241 else:
mjw@1661 242 return s
mjw@1661 243
mjw@1746 244 def configure_image(config, vals):
mjw@1661 245 """Create the image config.
mjw@1661 246 """
mjw@1746 247 config_image = [ vals.builder ]
mjw@1746 248 config_image.append([ 'kernel', os.path.abspath(vals.kernel) ])
mjw@1746 249 if vals.ramdisk:
mjw@1746 250 config_image.append([ 'ramdisk', os.path.abspath(vals.ramdisk) ])
mjw@1746 251 if vals.cmdline_ip:
mjw@1746 252 cmdline_ip = strip('ip=', vals.cmdline_ip)
mjw@1661 253 config_image.append(['ip', cmdline_ip])
mjw@1746 254 if vals.root:
mjw@1746 255 cmdline_root = strip('root=', vals.root)
mjw@1661 256 config_image.append(['root', cmdline_root])
mjw@1746 257 if vals.extra:
mjw@1746 258 config_image.append(['args', vals.extra])
cl349@3489 259 if vals.vcpus:
cl349@3489 260 config_image.append(['vcpus', vals.vcpus])
mjw@1661 261 config.append(['image', config_image ])
cl349@3489 262
mjw@1661 263
mjw@1746 264 def configure_disks(config_devs, vals):
mjw@1661 265 """Create the config for disks (virtual block devices).
mjw@1661 266 """
mjw@2305 267 for (uname, dev, mode, backend) in vals.disk:
mjw@1661 268 config_vbd = ['vbd',
mjw@1661 269 ['uname', uname],
mjw@1661 270 ['dev', dev ],
mjw@1661 271 ['mode', mode ] ]
mjw@2305 272 if backend:
mjw@2305 273 config_vbd.append(['backend', backend])
mjw@1661 274 config_devs.append(['device', config_vbd])
mjw@1661 275
mjw@1746 276 def configure_pci(config_devs, vals):
mjw@1661 277 """Create the config for pci devices.
mjw@1661 278 """
mjw@1746 279 for (bus, dev, func) in vals.pci:
mjw@1661 280 config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
mjw@1661 281 config_devs.append(['device', config_pci])
mjw@1661 282
mwilli2@3501 283 def configure_usb(config_devs, vals):
mwilli2@3501 284 for path in vals.usb:
mwilli2@3501 285 config_usb = ['usb', ['path', path]]
mwilli2@3501 286 config_devs.append(['device', config_usb])
mwilli2@3501 287
mjw@1761 288 def randomMAC():
mjw@1761 289 """Generate a random MAC address.
mjw@1761 290
mjw@1761 291 Uses OUI (Organizationally Unique Identifier) AA:00:00, an
mjw@1761 292 unassigned one that used to belong to DEC. The OUI list is
mjw@1761 293 available at 'standards.ieee.org'.
mjw@1761 294
mjw@1761 295 The remaining 3 fields are random, with the first bit of the first
mjw@1761 296 random field set 0.
mjw@1761 297
mjw@2327 298 @return: MAC address string
mjw@1761 299 """
kaf24@2674 300 random.seed()
mjw@1761 301 mac = [ 0xaa, 0x00, 0x00,
mjw@1761 302 random.randint(0x00, 0x7f),
mjw@1761 303 random.randint(0x00, 0xff),
mjw@1761 304 random.randint(0x00, 0xff) ]
mjw@1808 305 return ':'.join(map(lambda x: "%02x" % x, mac))
mjw@1761 306
mjw@1746 307 def configure_vifs(config_devs, vals):
mjw@1661 308 """Create the config for virtual network interfaces.
mjw@1661 309 """
mjw@1746 310 vifs = vals.vif
mjw@1746 311 vifs_n = max(vals.nics, len(vifs))
mjw@1661 312
mjw@1661 313 for idx in range(0, vifs_n):
mjw@1661 314 if idx < len(vifs):
mjw@1661 315 d = vifs[idx]
mjw@1661 316 mac = d.get('mac')
kaf24@3469 317 if not mac:
kaf24@3469 318 mac = randomMAC()
iap10@3639 319 be_mac = d.get('be_mac')
mjw@1661 320 bridge = d.get('bridge')
mjw@1761 321 script = d.get('script')
mjw@2305 322 backend = d.get('backend')
kaf24@3469 323 ip = d.get('ip')
mjw@1661 324 else:
mjw@1761 325 mac = randomMAC()
iap10@3639 326 be_mac = None
mjw@1661 327 bridge = None
mjw@1761 328 script = None
mjw@2305 329 backend = None
kaf24@3469 330 ip = None
mjw@1661 331 config_vif = ['vif']
mjw@1761 332 config_vif.append(['mac', mac])
iap10@3639 333 if be_mac:
iap10@3639 334 config_vif.append(['be_mac', be_mac])
mjw@1661 335 if bridge:
mjw@1661 336 config_vif.append(['bridge', bridge])
mjw@1761 337 if script:
mjw@1761 338 config_vif.append(['script', script])
mjw@2305 339 if backend:
mjw@2305 340 config_vif.append(['backend', backend])
kaf24@3469 341 if ip:
kaf24@3469 342 config_vif.append(['ip', ip])
mjw@1661 343 config_devs.append(['device', config_vif])
mjw@1661 344
mjw@1746 345 def configure_vfr(config, vals):
mjw@1746 346 if not vals.ipaddr: return
mjw@1661 347 config_vfr = ['vfr']
mjw@1661 348 idx = 0 # No way of saying which IP is for which vif?
mjw@1746 349 for ip in vals.ipaddr:
mjw@1661 350 config_vfr.append(['vif', ['id', idx], ['ip', ip]])
mjw@1661 351 config.append(config_vfr)
mjw@1661 352
iap10@3428 353 def configure_vmx(config_devs, vals):
iap10@3428 354 """Create the config for VMX devices.
iap10@3428 355 """
iap10@3428 356 memmap = vals.memmap
iap10@3428 357 device_model = vals.device_model
iap10@3428 358 device_config = vals.device_config
iap10@3428 359 config_devs.append(['memmap', memmap])
iap10@3428 360 config_devs.append(['device_model', device_model])
iap10@3428 361 config_devs.append(['device_config', device_config])
mjw@1661 362
mjw@1746 363 def make_config(vals):
mjw@1661 364 """Create the domain configuration.
mjw@1661 365 """
mjw@1661 366
mjw@1661 367 config = ['vm',
mjw@1746 368 ['name', vals.name ],
mjw@2327 369 ['memory', vals.memory ]]
mjw@2441 370 if vals.maxmem:
mjw@2441 371 config.append(['maxmem', vals.maxmem])
mjw@2327 372 if vals.cpu is not None:
mjw@1746 373 config.append(['cpu', vals.cpu])
mjw@2327 374 if vals.cpu_weight is not None:
mjw@2327 375 config.append(['cpu_weight', vals.cpu_weight])
mjw@1746 376 if vals.blkif:
mjw@1661 377 config.append(['backend', ['blkif']])
mjw@1746 378 if vals.netif:
mjw@1661 379 config.append(['backend', ['netif']])
mjw@1823 380 if vals.restart:
mjw@1823 381 config.append(['restart', vals.restart])
mjw@1824 382 if vals.console:
mjw@1824 383 config.append(['console', vals.console])
mjw@1661 384
mjw@1746 385 configure_image(config, vals)
mjw@1661 386 config_devs = []
mjw@1746 387 configure_disks(config_devs, vals)
mjw@1746 388 configure_pci(config_devs, vals)
mjw@1746 389 configure_vifs(config_devs, vals)
mwilli2@3501 390 configure_usb(config_devs, vals)
iap10@3428 391 configure_vmx(config_devs, vals)
mjw@1661 392 config += config_devs
mjw@1661 393 return config
mjw@1661 394
mjw@1746 395 def preprocess_disk(opts, vals):
mjw@1746 396 if not vals.disk: return
mjw@1661 397 disk = []
mjw@1746 398 for v in vals.disk:
mjw@1661 399 d = v.split(',')
mjw@2305 400 n = len(d)
mjw@2305 401 if n == 3:
mjw@2307 402 d.append(None)
mjw@2305 403 elif n == 4:
mjw@2305 404 pass
mjw@2305 405 else:
mjw@1661 406 opts.err('Invalid disk specifier: ' + v)
mjw@1661 407 disk.append(d)
mjw@1746 408 vals.disk = disk
mjw@1661 409
mjw@1746 410 def preprocess_pci(opts, vals):
mjw@1746 411 if not vals.pci: return
mjw@1661 412 pci = []
mjw@1746 413 for v in vals.pci:
mjw@1661 414 d = v.split(',')
mjw@1661 415 if len(d) != 3:
mjw@1661 416 opts.err('Invalid pci specifier: ' + v)
mjw@1661 417 # Components are in hex: add hex specifier.
mjw@1661 418 hexd = map(lambda v: '0x'+v, d)
mjw@1661 419 pci.append(hexd)
mjw@1746 420 vals.pci = pci
mjw@1661 421
mjw@1746 422 def preprocess_vifs(opts, vals):
mjw@1746 423 if not vals.vif: return
mjw@1661 424 vifs = []
mjw@1746 425 for vif in vals.vif:
mjw@1661 426 d = {}
mjw@1661 427 a = vif.split(',')
mjw@1661 428 for b in a:
mjw@1719 429 (k, v) = b.strip().split('=', 1)
mjw@1661 430 k = k.strip()
mjw@1661 431 v = v.strip()
iap10@3639 432 if k not in ['mac', 'be_mac', 'bridge', 'script', 'backend', 'ip']:
mjw@1661 433 opts.err('Invalid vif specifier: ' + vif)
mjw@1661 434 d[k] = v
mjw@1661 435 vifs.append(d)
mjw@1746 436 vals.vif = vifs
mjw@1661 437
mjw@1746 438 def preprocess_ip(opts, vals):
iap10@2075 439 if vals.ip or vals.dhcp != 'off':
iap10@2075 440 dummy_nfs_server = '1.2.3.4'
iap10@2075 441 ip = (vals.ip
mjw@1804 442 + ':' + (vals.nfs_server or dummy_nfs_server)
mjw@1746 443 + ':' + vals.gateway
mjw@1746 444 + ':' + vals.netmask
mjw@1746 445 + ':' + vals.hostname
mjw@1746 446 + ':' + vals.interface
mjw@1746 447 + ':' + vals.dhcp)
iap10@2075 448 else:
iap10@2075 449 ip = ''
mjw@1746 450 vals.cmdline_ip = ip
mjw@1661 451
mjw@1746 452 def preprocess_nfs(opts, vals):
mjw@1804 453 if not vals.nfs_root: return
mjw@1804 454 if not vals.nfs_server:
mjw@1804 455 opts.err('Must set nfs root and nfs server')
mjw@1746 456 nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root
mjw@1746 457 vals.extra = nfs + ' ' + vals.extra
mjw@1661 458
mjw@1746 459 def preprocess(opts, vals):
mjw@1746 460 if not vals.kernel:
mjw@1661 461 opts.err("No kernel specified")
mjw@1746 462 preprocess_disk(opts, vals)
mjw@1746 463 preprocess_pci(opts, vals)
mjw@1746 464 preprocess_vifs(opts, vals)
mjw@1746 465 preprocess_ip(opts, vals)
mjw@1746 466 preprocess_nfs(opts, vals)
mjw@1661 467
mjw@1661 468 def make_domain(opts, config):
mjw@1661 469 """Create, build and start a domain.
mjw@1759 470
mjw@1759 471 @param opts: options
mjw@1759 472 @param config: configuration
mjw@1759 473 @return: domain id, console port
mjw@1759 474 @rtype: (int, int)
mjw@1661 475 """
mjw@1759 476
mjw@1759 477 try:
mjw@1759 478 if opts.vals.load:
mjw@1759 479 filename = os.path.abspath(opts.vals.load)
mjw@1759 480 dominfo = server.xend_domain_restore(filename, config)
mjw@1759 481 else:
mjw@1759 482 dominfo = server.xend_domain_create(config)
mjw@1759 483 except XendError, ex:
mjw@1759 484 opts.err(str(ex))
mjw@1661 485
mjw@2013 486 dom = sxp.child_value(dominfo, 'name')
mjw@1661 487 console_info = sxp.child(dominfo, 'console')
mjw@1661 488 if console_info:
mjw@1931 489 console_port = int(sxp.child_value(console_info, 'console_port'))
mjw@1661 490 else:
mjw@1661 491 console_port = None
mjw@2242 492
mjw@2242 493 if not opts.vals.paused:
mjw@2242 494 if server.xend_domain_unpause(dom) < 0:
mjw@2242 495 server.xend_domain_destroy(dom)
mjw@2242 496 opts.err("Failed to unpause domain %s" % dom)
mjw@2013 497 opts.info("Started domain %s, console on port %d"
mjw@1661 498 % (dom, console_port))
mjw@1661 499 return (dom, console_port)
mjw@1661 500
mjw@1661 501 def main(argv):
mjw@1661 502 opts = gopts
mjw@1661 503 args = opts.parse(argv)
mjw@1661 504 if opts.vals.help:
mjw@1661 505 opts.usage()
mjw@1693 506 if opts.vals.help or opts.vals.help_config:
mjw@2327 507 opts.load_defconfig(help=1)
mjw@1693 508 if opts.vals.help or opts.vals.help_config:
mjw@1661 509 return
mjw@1693 510 # Process remaining args as config variables.
mjw@1693 511 for arg in args:
mjw@1693 512 if '=' in arg:
mjw@1719 513 (var, val) = arg.strip().split('=', 1)
mjw@1693 514 gopts.setvar(var.strip(), val.strip())
mjw@1661 515 if opts.vals.config:
mjw@1942 516 config = opts.vals.config
mjw@1661 517 else:
mjw@2327 518 opts.load_defconfig()
mjw@1942 519 preprocess(opts, opts.vals)
cl349@2794 520 if not opts.getopt('name') and opts.getopt('defconfig'):
cl349@2794 521 opts.setopt('name', os.path.basename(opts.getopt('defconfig')))
mjw@1942 522 config = make_config(opts.vals)
mjw@1661 523 if opts.vals.dryrun:
mjw@1661 524 PrettyPrint.prettyprint(config)
mjw@1661 525 else:
mjw@1759 526 (dom, console) = make_domain(opts, config)
kaf24@1676 527 if opts.vals.console_autoconnect:
mjw@1759 528 console_client.connect('localhost', console)
mjw@1661 529
mjw@1661 530 if __name__ == '__main__':
mjw@1661 531 main(sys.argv)