ia64/xen-unstable

changeset 1481:5566ee00e69b

bitkeeper revision 1.959.1.3 (40cf2938j76NDs4xtyvevBrKpmogjA)

Initial checkin for grand unified management app xm.
author mjw@wray-m-3.hpl.hp.com
date Tue Jun 15 16:52:08 2004 +0000 (2004-06-15)
parents 459daba5f498
children 74aec78554a4
files .rootkeys tools/examples/Makefile tools/examples/xmdefaults tools/xenmgr/Makefile tools/xenmgr/lib/xm/create.py tools/xenmgr/lib/xm/main.py tools/xenmgr/lib/xm/opts.py tools/xenmgr/lib/xm/shutdown.py tools/xenmgr/xm
line diff
     1.1 --- a/.rootkeys	Tue Jun 15 09:42:19 2004 +0000
     1.2 +++ b/.rootkeys	Tue Jun 15 16:52:08 2004 +0000
     1.3 @@ -168,6 +168,7 @@ 401d7e16X4iojyKopo_j63AyzYZd2A tools/exa
     1.4  40c9c4684Wfg8VgMKtRFa_ULi2e_tQ tools/examples/xm_dom_control.py
     1.5  40c9c468pXANclL7slGaoD0kSrIwoQ tools/examples/xm_dom_create.py
     1.6  40c9c468QKoqBHjb5Qwrm60pNVcVng tools/examples/xm_vd_tool.py
     1.7 +40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmdefaults
     1.8  3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
     1.9  40ab2cfawIw8tsYo0dQKtp83h4qfTQ tools/misc/fakei386xen
    1.10  3f6dc136ZKOjd8PIqLbFBl_v-rnkGg tools/misc/miniterm/Makefile
    1.11 @@ -269,10 +270,15 @@ 40c9c469yrm31i60pGKslTi2Zgpotg tools/xen
    1.12  40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/xenmgr/lib/server/netif.py
    1.13  40c9c469ZqILEQ8x6yWy0_51jopiCg tools/xenmgr/lib/server/params.py
    1.14  40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/xenmgr/lib/sxp.py
    1.15 +40cf2937gKQcATgXKGtNeWb1PDH5nA tools/xenmgr/lib/xm/create.py
    1.16 +40cf2937isyS250zyd0Q2GuEDoNXfQ tools/xenmgr/lib/xm/main.py
    1.17 +40cf2937PSslwBliN1g7ofDy2H_RhA tools/xenmgr/lib/xm/opts.py
    1.18 +40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/xenmgr/lib/xm/shutdown.py
    1.19  40c9c469kT0H9COWzA4XzPBjWK0WsA tools/xenmgr/netfix
    1.20  40c9c469n2RRwCmjWdjdyyVRWKmgWg tools/xenmgr/setup.py
    1.21  40c9c4697z76HDfkCLdMhmaEwzFoNQ tools/xenmgr/xend
    1.22  40c9c469JkN47d1oXi-e0RjAP-C6uQ tools/xenmgr/xenmgrd
    1.23 +40cf2937dqM1jWW87O5OoOYND8leuA tools/xenmgr/xm
    1.24  403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile
    1.25  40a107afN60pFdURgBv9KwEzgRl5mQ tools/xentrace/formats
    1.26  4050c413PhhLNAYk3TEwP37i_iLw9Q tools/xentrace/xentrace.8
     2.1 --- a/tools/examples/Makefile	Tue Jun 15 09:42:19 2004 +0000
     2.2 +++ b/tools/examples/Makefile	Tue Jun 15 16:52:08 2004 +0000
     2.3 @@ -1,6 +1,6 @@
     2.4  
     2.5  INSTALL  = $(wildcard *.py)
     2.6 -ETC	 = defaults democd netbsd
     2.7 +ETC	 = defaults democd netbsd xmdefaults
     2.8  INITD    = init.d/xendomains init.d/xend
     2.9  
    2.10  all: 
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/examples/xmdefaults	Tue Jun 15 16:52:08 2004 +0000
     3.3 @@ -0,0 +1,96 @@
     3.4 +#  -*- mode: python; -*-
     3.5 +#============================================================================
     3.6 +# Python defaults setup for 'xm create'.
     3.7 +# Edit this file to reflect the configuration of your system.
     3.8 +# This file expects the variable 'vmid' to be set.
     3.9 +#============================================================================
    3.10 +
    3.11 +import sys
    3.12 +import xenctl.ip
    3.13 +
    3.14 +try:
    3.15 +    vmid = int(vmid) # convert to integer
    3.16 +except:
    3.17 +    raise ValueError, "Variable 'vmid' must be an integer"
    3.18 +
    3.19 +if vmid <= 0:
    3.20 +    raise ValueError, "Variable 'vmid' must be greater than 0" 
    3.21 +
    3.22 +
    3.23 +#----------------------------------------------------------------------------
    3.24 +# Kernel image file.
    3.25 +kernel = "../../../install/boot/vmlinuz-2.4.26-xen"
    3.26 +
    3.27 +# Optional ramdisk.
    3.28 +#ramdisk = "/boot/initrd.gz"
    3.29 +
    3.30 +# The domain build function. Default is 'linux'.
    3.31 +#builder='linux'
    3.32 +#builder='netbsd'
    3.33 +
    3.34 +# Initial memory allocation (in megabytes) for the new domain.
    3.35 +memory = 64
    3.36 +
    3.37 +# A handy name for your new domain.
    3.38 +name = "This is VM %d" % vmid
    3.39 +
    3.40 +# Which CPU to start domain on? 
    3.41 +#cpu = -1   # leave to Xen to pick
    3.42 +cpu = vmid  # set based on vmid (mod number of CPUs)
    3.43 +
    3.44 +#----------------------------------------------------------------------------
    3.45 +# Define network interfaces.
    3.46 +
    3.47 +# Number of network interfaces. Default is 1.
    3.48 +#nics=1
    3.49 +
    3.50 +# List of MAC addresses for the network interfaces.
    3.51 +# If there aren't enough addresses for all the interfaces
    3.52 +# the rest get random MACs.
    3.53 +#mac = [ "aa:00:00:00:00:11" ]
    3.54 +
    3.55 +#----------------------------------------------------------------------------
    3.56 +# Define the disk devices you want the domain to have access to, and
    3.57 +# what you want them accessible as.
    3.58 +# Each disk entry is of the form phy:DEV,VDEV,MODE
    3.59 +# where DEV is the device, VDEV is the device name the domain will see,
    3.60 +# and MODE is r for read-only, w for read-write.
    3.61 +
    3.62 +disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
    3.63 +         'phy:sda6,sda6,r' ]
    3.64 +
    3.65 +#----------------------------------------------------------------------------
    3.66 +# Set the kernel command line for the new domain.
    3.67 +# You only need to define the IP parameters and hostname if the domain's
    3.68 +# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
    3.69 +# You can use 'extra' to set the runlevel and custom environment
    3.70 +# variables used by custom rc scripts (e.g. VMID=, usr= ).
    3.71 +
    3.72 +# Set if you want dhcp to allocate the IP address.
    3.73 +#dhcp="dhcp"
    3.74 +# Set netmask.
    3.75 +#netmask=
    3.76 +# Set default gateway.
    3.77 +#gateway=
    3.78 +# Set the hostname.
    3.79 +#hostname= "vm%d" % vmid
    3.80 +
    3.81 +# Set root device.
    3.82 +root = "/dev/sda1 ro"
    3.83 +
    3.84 +# Root device for nfs.
    3.85 +#root = "/dev/nfs"
    3.86 +# The nfs server.
    3.87 +#nfs_server = '169.254.1.0'  
    3.88 +# Root directory on the nfs server.
    3.89 +#nfs_root   = '/full/path/to/root/directory'
    3.90 +
    3.91 +# Sets runlevel 4 and the device for /usr.
    3.92 +extra = "4 VMID=%d usr=/dev/sda6" % vmid
    3.93 +
    3.94 +#----------------------------------------------------------------------------
    3.95 +# Set according to whether you want the domain  restarted when it exits.
    3.96 +# The default is False.
    3.97 +#restart = True
    3.98 +
    3.99 +#============================================================================
     4.1 --- a/tools/xenmgr/Makefile	Tue Jun 15 09:42:19 2004 +0000
     4.2 +++ b/tools/xenmgr/Makefile	Tue Jun 15 16:52:08 2004 +0000
     4.3 @@ -11,9 +11,9 @@ install: all
     4.4  	    python setup.py install --root="$(prefix)"; \
     4.5  	fi
     4.6  	mkdir -p $(prefix)/usr/sbin
     4.7 -	install -m0755 xenmgrd $(prefix)/usr/sbin
     4.8  	install -m0755 xend $(prefix)/usr/sbin
     4.9  	install -m0755 netfix $(prefix)/usr/sbin
    4.10 +	install -m0755 xm $(prefix)/usr/sbin
    4.11  
    4.12  clean:
    4.13  	rm -rf build *.pyc *.pyo *.o *.a *~
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/xenmgr/lib/xm/create.py	Tue Jun 15 16:52:08 2004 +0000
     5.3 @@ -0,0 +1,287 @@
     5.4 +import string
     5.5 +import sys
     5.6 +
     5.7 +from xenmgr import sxp
     5.8 +from xenmgr import PrettyPrint
     5.9 +from xenmgr.XendClient import server
    5.10 +
    5.11 +from xenmgr.xm.opts import *
    5.12 +
    5.13 +opts = Opts(use="""[options]
    5.14 +
    5.15 +Create a domain.
    5.16 +""")
    5.17 +
    5.18 +opts.opt('help', short='h',
    5.19 +         fn=set_value, default=0,
    5.20 +         use="Print this help.")
    5.21 +
    5.22 +opts.opt('quiet', short='q',
    5.23 +         fn=set_true, default=0,
    5.24 +         use="Quiet.")
    5.25 +
    5.26 +opts.opt('path', val='PATH',
    5.27 +         fn=set_value, default='.:/etc/xc',
    5.28 +         use="Search path for default scripts.")
    5.29 +
    5.30 +opts.opt('defaults', short='f', val='FILE',
    5.31 +         fn=set_value, default='xmdefaults',
    5.32 +         use="Use the given default script.")
    5.33 +
    5.34 +opts.opt('config', short='F', val='FILE',
    5.35 +         fn=set_value, default=None,
    5.36 +         use='Domain configuration to use.')
    5.37 +
    5.38 +def set_var(opt, k, v):
    5.39 +    opt.set(v)
    5.40 +    for d in string.split(v, ';' ):
    5.41 +        (k, v) = string.split(d, '=')
    5.42 +        opt.opts.setvar(k, v)
    5.43 +
    5.44 +opts.opt('define', short='D', val='VAR=VAL',
    5.45 +         fn=set_var, default=None,
    5.46 +         use="Set a variable before loading defaults,e.g. '-D vmid=3;ip=1.2.3.4'.")
    5.47 +
    5.48 +opts.opt('dryrun', short='n',
    5.49 +         fn=set_true, default=0,
    5.50 +         use="Dry run - print the config but don't create the domain.")
    5.51 +
    5.52 +opts.opt('console', short='c',
    5.53 +         fn=set_true, default=0,
    5.54 +         use="Connect to console after domain is created.")
    5.55 +
    5.56 +opts.opt('kernel', short='k', val='FILE',
    5.57 +         use="Path to kernel image.")
    5.58 +
    5.59 +opts.opt('ramdisk', short='r', val='FILE',
    5.60 +         fn=set_value, default='',
    5.61 +         use="Path to ramdisk.")
    5.62 +
    5.63 +opts.opt('builder', short='b', val='FUNCTION',
    5.64 +         fn=set_value, default='linux',
    5.65 +         use="Function to use to build the domain.")
    5.66 +
    5.67 +opts.opt('memory', short='m', val='MEMORY',
    5.68 +         fn=set_value, default=128,
    5.69 +         use="Domain memory in MB.")
    5.70 +
    5.71 +opts.opt('disk', short='d', val='phy:DEV,VDEV,MODE',
    5.72 +         fn=append_value, default=[],
    5.73 +         use="""Add a disk device to a domain. The physical device is DEV, which
    5.74 +         is exported to the domain as VDEV. The disk is read-only if MODE is r,
    5.75 +         read-write if mode is 'w'.""")
    5.76 +
    5.77 +opts.opt('ipaddr', short='i', val="IPADDR",
    5.78 +         fn=append_value, default=[],
    5.79 +         use="Add an IP address to the domain.")
    5.80 +
    5.81 +opts.opt('mac', short='M', val="MAC",
    5.82 +         fn=append_value, default=[],
    5.83 +         use="""Add a network interface with the given mac address to the domain.
    5.84 +         More than one interface may be specified. Interfaces with unspecified MAC addresses
    5.85 +         are allocated a random address.""")
    5.86 +
    5.87 +opts.opt('nics', val="N",
    5.88 +         fn=set_int, default="1",
    5.89 +         use="Set the number of network interfaces.")
    5.90 +
    5.91 +opts.opt('vnet', val='VNET',
    5.92 +         fn=set_append_value, default=[],
    5.93 +         use="""Define the vnets for the network interfaces.
    5.94 +         More than one vnet may be given, they are used in order.
    5.95 +         """)
    5.96 +
    5.97 +opts.opt('root', short='R', val='DEVICE',
    5.98 +         fn=set_value, default='',
    5.99 +         use="""Set the root= parameter on the kernel command line.
   5.100 +         Use a device, e.g. /dev/sda1, or /dev/nfs for NFS root.""")
   5.101 +
   5.102 +opts.opt('extra', short='E', val="ARGS",
   5.103 +         fn=set_value, default='',
   5.104 +         use="Set extra arguments to append to the kernel command line.")
   5.105 +
   5.106 +opts.opt('ip', short='I', val='IPADDR',
   5.107 +         fn=set_value, default=[],
   5.108 +         use="Set the kernel IP interface address.")
   5.109 +
   5.110 +opts.opt('gateway', val="IPADDR",
   5.111 +         fn=set_value, default='',
   5.112 +         use="Set kernel IP gateway.")
   5.113 +
   5.114 +opts.opt('netmask', val="MASK",
   5.115 +         fn=set_value, default = '',
   5.116 +         use="Set kernel IP netmask.")
   5.117 +
   5.118 +opts.opt('hostname', val="NAME",
   5.119 +         fn=set_value, default='',
   5.120 +         use="Set kernel IP hostname.")
   5.121 +
   5.122 +opts.opt('interface', val="INTF",
   5.123 +         fn=set_value, default="eth0",
   5.124 +         use="Set the kernel IP interface name.")
   5.125 +
   5.126 +opts.opt('dhcp', val="off|dhcp",
   5.127 +         fn=set_value, default='off',
   5.128 +         use="Set kernel dhcp option.")
   5.129 +
   5.130 +opts.opt('nfs_server', val="IPADDR",
   5.131 +         fn=set_value, default=None,
   5.132 +         use="Set the address of the NFS server for NFS root.")
   5.133 +
   5.134 +opts.opt('nfs_root', val="PATH",
   5.135 +         fn=set_value, default=None,
   5.136 +         use="Set the path of the root NFS directory.")
   5.137 +
   5.138 +def strip(pre, s):
   5.139 +    if s.startswith(pre):
   5.140 +        return s[len(pre):]
   5.141 +    else:
   5.142 +        return s
   5.143 +
   5.144 +def make_domain_config(opts):
   5.145 +    
   5.146 +    config = ['config',
   5.147 +              ['name', opts.name ],
   5.148 +              ['memory', opts.memory ] ]
   5.149 +    if opts.cpu:
   5.150 +        config.append(['cpu', opts.cpu])
   5.151 +    
   5.152 +    config_image = [ opts.builder ]
   5.153 +    config_image.append([ 'kernel', os.path.abspath(opts.kernel) ])
   5.154 +    if opts.ramdisk:
   5.155 +        config_image.append([ 'ramdisk', os.path.abspath(opts.ramdisk) ])
   5.156 +    if opts.cmdline_ip:
   5.157 +        cmdline_ip = strip("ip=", opts.cmdline_ip)
   5.158 +        config_image.append(['ip', cmdline_ip])
   5.159 +    if opts.root:
   5.160 +        cmdline_root = strip("root=", opts.root)
   5.161 +        config_image.append(['root', opts.root])
   5.162 +    if opts.extra:
   5.163 +        config_image.append(['args', opts.extra])
   5.164 +    config.append(['image', config_image ])
   5.165 +    	
   5.166 +    config_devs = []
   5.167 +    for (uname, dev, mode) in opts.disk:
   5.168 +        config_vbd = ['vbd',
   5.169 +                      ['uname', uname],
   5.170 +                      ['dev', dev ],
   5.171 +                      ['mode', mode ] ]
   5.172 +        config_devs.append(['device', config_vbd])
   5.173 +
   5.174 +    for (bus, dev, func) in opts.pci:
   5.175 +        config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
   5.176 +        config_devs.append(['device', config_pci])
   5.177 +
   5.178 +    for idx in range(0, opts.nics):
   5.179 +        config_vif = ['vif' ['@', ['id', 'vif%d' % idx]]]
   5.180 +        if idx < len(opts.mac):
   5.181 +            config_vif.append(['mac', opts.mac[idx]])
   5.182 +        config_devs.append(['device', config_vif])
   5.183 +
   5.184 +    config += config_devs
   5.185 +
   5.186 +##     if vfr_ipaddr:
   5.187 +##         config_vfr = ['vfr']
   5.188 +##         idx = 0 # No way of saying which IP is for which vif?
   5.189 +##         for ip in vfr_ipaddr:
   5.190 +##             config_vfr.append(['vif', ['id', idx], ['ip', ip]])
   5.191 +##         config.append(config_vfr)
   5.192 +
   5.193 +    if opts.vnet:
   5.194 +        config_vnet = ['vnet']
   5.195 +        idx = 0
   5.196 +        for vnet in opts.vnet:
   5.197 +            config_vif = ['vif', ['id', 'vif%d' % idx], ['vnet', vnet]]
   5.198 +            config_vnet.append(config_vif)
   5.199 +            idx += 1
   5.200 +        config.append(config_vnet)
   5.201 +            
   5.202 +    return config
   5.203 +
   5.204 +def preprocess_disk(opts):
   5.205 +    if not opts.disk: return
   5.206 +    disk = []
   5.207 +    for v in opts.disk:
   5.208 +        d = v.split(',')
   5.209 +        if len(d) != 3:
   5.210 +            opts.err('Invalid disk specifier: ' + v)
   5.211 +        disk.append(d)
   5.212 +    opts.disk = d
   5.213 +
   5.214 +def preprocess_pci(opts):
   5.215 +    if not opts.pci: return
   5.216 +    pci = []
   5.217 +    for v in opts.pci:
   5.218 +        d = v.split(',')
   5.219 +        if len(d) != 3:
   5.220 +            opts.err('Invalid pci specifier: ' + v)
   5.221 +        pci.append(d)
   5.222 +    opts.pci = pci
   5.223 +
   5.224 +def preprocess_ip(opts):
   5.225 +    setip = (opts.hostname or opts.netmask
   5.226 +             or opts.gateway or opts.dhcp or opts.interface)
   5.227 +    if not setip: return
   5.228 +    ip = (opts.ip
   5.229 +          + ':'
   5.230 +          + ':' + opts.gateway
   5.231 +          + ':' + opts.netmask
   5.232 +          + ':' + opts.hostname
   5.233 +          + ':' : opts.interface
   5.234 +          + ':' + opts.dhcp)
   5.235 +    opts.cmdline_ip = ip
   5.236 +
   5.237 +def preprocess_nfs(opts):
   5.238 +    if (opts.nfs_root or opts.nfs_server):
   5.239 +        if (not opts.nfs_root) or (not opts.nfs_server):
   5.240 +            opts.err('Must set nfs root and nfs server')
   5.241 +    else:
   5.242 +        return
   5.243 +    nfs = 'nfsroot=' + opts.nfs_server + ':' + opts.nfs_root
   5.244 +    opts.extra = nfs + ' ' + opts.extra
   5.245 +    
   5.246 +def preprocess(opts):
   5.247 +    preprocess_disk(opts)
   5.248 +    preprocess_pci(opts)
   5.249 +    preprocess_ip(opts)
   5.250 +    preprocess_nfs(opts)
   5.251 +         
   5.252 +def make_domain(config):
   5.253 +    """Create, build and start a domain.
   5.254 +    Returns: [int] the ID of the new domain.
   5.255 +    """
   5.256 +    restore = 0 #todo
   5.257 +
   5.258 +    if restore:
   5.259 +        dominfo = server.xend_domain_restore(state_file, config)
   5.260 +    else:
   5.261 +        dominfo = server.xend_domain_create(config)
   5.262 +
   5.263 +    dom = int(sxp.child_value(dominfo, 'id'))
   5.264 +    console_info = sxp.child(dominfo, 'console')
   5.265 +    if console_info:
   5.266 +        console_port = int(sxp.child_value(console_info, 'port'))
   5.267 +    else:
   5.268 +        console_port = None
   5.269 +    
   5.270 +    if server.xend_domain_start(dom) < 0:
   5.271 +        server.xend_domain_halt(dom)
   5.272 +        opts.err("Failed to start domain %d" % dom)
   5.273 +    opts.info("Started domain %d, console on port %d"
   5.274 +              % (dom, console_port))
   5.275 +    return (dom, console_port)
   5.276 +
   5.277 +def main(argv):
   5.278 +    args = opts.parse(argv)
   5.279 +    if opts.config:
   5.280 +        pass
   5.281 +    else:
   5.282 +        opts.load_defaults()
   5.283 +    if opts.help:
   5.284 +        opts.usage()
   5.285 +    preprocess(opts)
   5.286 +    config = make_config(opts)
   5.287 +    make_domain(opts, config)
   5.288 +        
   5.289 +if __name__ == '__main__':
   5.290 +    main(sys.argv)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/xenmgr/lib/xm/main.py	Tue Jun 15 16:52:08 2004 +0000
     6.3 @@ -0,0 +1,161 @@
     6.4 +#!/usr/bin/python
     6.5 +import string
     6.6 +import sys
     6.7 +
     6.8 +from xenmgr.XendClient import server
     6.9 +
    6.10 +from xenmgr.xm import create, shutdown
    6.11 +
    6.12 +class Xm:
    6.13 +
    6.14 +    def __init__(self):
    6.15 +        self.prog = 'xm'
    6.16 +        pass
    6.17 +
    6.18 +    def err(self, msg):
    6.19 +        print >>sys.stderr, "Error:", msg
    6.20 +        sys.exit(1)
    6.21 +
    6.22 +    def main(self, args):
    6.23 +        self.prog = args[0]
    6.24 +        if len(args) < 2:
    6.25 +            self.err("Missing command\nTry '%s help' for more information."
    6.26 +                     % self.prog)
    6.27 +        prog = 'xm_' + args[1]
    6.28 +        help = self.helparg(args)
    6.29 +        fn = getattr(self, prog, self.unknown)
    6.30 +        fn(help, args[1:])
    6.31 +
    6.32 +    def helparg(self, args):
    6.33 +        for a in args:
    6.34 +            if a in ['-h', '--help']:
    6.35 +                return 1
    6.36 +        return 0
    6.37 +
    6.38 +    def unknown(self, args):
    6.39 +        self.err("Unknown command: %s\nTry '%s help' for more information."
    6.40 +                 % (args[0], self.prog))
    6.41 +
    6.42 +    def help(self, meth, args):
    6.43 +        name = meth[3:]
    6.44 +        f = getattr(self, meth)
    6.45 +        print "%s\t%s" % (name, f.__doc__ or '')
    6.46 +
    6.47 +    def xm_help(self, help, args):
    6.48 +        """Print help."""
    6.49 +        for k in dir(self):
    6.50 +            if not k.startswith('xm_'): continue
    6.51 +            self.help(k, args)
    6.52 +        print "\nTry '%s CMD -h' for help on CMD" % self.prog
    6.53 +                
    6.54 +    def xm_create(self, help, args):
    6.55 +        """Create a domain."""
    6.56 +        create.main(args)
    6.57 +
    6.58 +    def xm_save(self, help, args):
    6.59 +        """Save domain state to file."""
    6.60 +        if help:
    6.61 +            print "save DOM FILE"
    6.62 +            print "\nSave domain with id DOM to FILE."
    6.63 +            return
    6.64 +        if len(args) < 3: self.err("%s: Missing arguments" % args[0])
    6.65 +        dom = args[1]
    6.66 +        filename = args[2]
    6.67 +        server.xend_domain_save(dom, filename)
    6.68 +
    6.69 +    def xm_restore(self, help, args):
    6.70 +        """Create a domain from a saved state."""
    6.71 +        if help:
    6.72 +            print "restore FILE"
    6.73 +            print "\nRestore a domain from FILE."
    6.74 +        if len(args) < 2: self.err("%s: Missing file" % args[0])
    6.75 +        server.xend_domain_restore(dom, None, filename)
    6.76 +
    6.77 +    def xm_ls(self, help, args):
    6.78 +        """List domains."""
    6.79 +        if help: self.help('xm_ls'); return
    6.80 +        doms = server.xend_domains()
    6.81 +        for dom in doms:
    6.82 +            d = server.domain(dom)
    6.83 +            print d
    6.84 +
    6.85 +    def xm_halt(self, help, args):
    6.86 +        """Terminate a domain immediately."""
    6.87 +        if help:
    6.88 +            print 'halt DOM'
    6.89 +            print '\nTerminate domain DOM immediately.'
    6.90 +            return
    6.91 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
    6.92 +        dom = args[1]
    6.93 +        server.xend_domain_halt(dom)
    6.94 +
    6.95 +    def xm_shutdown(self, help, args):
    6.96 +        """Shutdown a domain."""
    6.97 +        shutdown.main(args)
    6.98 +
    6.99 +    def xm_stop(self, help, args):
   6.100 +        """Stop execution of a domain."""
   6.101 +        if help:
   6.102 +            print 'stop DOM'
   6.103 +            print '\nStop execution of domain DOM.'
   6.104 +            return
   6.105 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
   6.106 +        dom = args[1]
   6.107 +        server.xend_domain_stop(dom)
   6.108 +
   6.109 +    def xm_start(self, help, args):
   6.110 +        """Start execution of a domain."""
   6.111 +        if help:
   6.112 +            print 'start DOM'
   6.113 +            print '\nStart execution of domain DOM.'
   6.114 +            return
   6.115 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
   6.116 +        dom = args[1]
   6.117 +        server.xend_domain_start(dom)
   6.118 +
   6.119 +    def xm_pincpu(self, help, args):
   6.120 +        """Pin a domain to a cpu. """
   6.121 +        if help:
   6.122 +            print 'pincpu DOM CPU'
   6.123 +            print '\nPin domain DOM to cpu CPU.'
   6.124 +            return
   6.125 +        pass
   6.126 +
   6.127 +    def xm_bvt(self, help, args):
   6.128 +        pass
   6.129 +
   6.130 +    def xm_bvtslice(self, help, args):
   6.131 +        pass
   6.132 +
   6.133 +    def xm_atropos(self, help, args):
   6.134 +        pass
   6.135 +
   6.136 +    def xm_rrslice(self, help, args):
   6.137 +        pass
   6.138 +
   6.139 +    def xm_info(self, help, args):
   6.140 +        """Get information about the xen host."""
   6.141 +        if help: self.help('xm_info'); return
   6.142 +        info = server.xend_node()
   6.143 +        for x in info:
   6.144 +            print "%-23s:" % x[0], x[1]
   6.145 +
   6.146 +    def xm_console(self, help, args):
   6.147 +        """Open a console to a domain."""
   6.148 +        if help:
   6.149 +            print "console DOM"
   6.150 +            print "\nOpen a console to domain DOM."
   6.151 +            return
   6.152 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
   6.153 +        dom = args[1]
   6.154 +        info = server.xend_domain(dom)
   6.155 +        console = sxp.child(info, "console")
   6.156 +        if not console:
   6.157 +            self.err("No console information")
   6.158 +        port = sxp.child_value(console, "port")
   6.159 +        from xenctl import console_client
   6.160 +        console_client.connect("localhost", int(port))
   6.161 +
   6.162 +def main(args):
   6.163 +    xm = Xm()
   6.164 +    xm.main(args)
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/xenmgr/lib/xm/opts.py	Tue Jun 15 16:52:08 2004 +0000
     7.3 @@ -0,0 +1,183 @@
     7.4 +from getopt import getopt
     7.5 +import os
     7.6 +import os.path
     7.7 +import sys
     7.8 +
     7.9 +class Opt:
    7.10 +    def __init__(self, opts, name, short=None, long=None,
    7.11 +                 val=None, fn=None, use=None, default=None):
    7.12 +        self.opts = opts
    7.13 +        self.name = name
    7.14 +        self.short = short
    7.15 +        if long is None:
    7.16 +            long = name
    7.17 +        self.long = long
    7.18 +        self.val = val
    7.19 +        self.use = use
    7.20 +        self.default = default
    7.21 +        self.optkeys = []
    7.22 +        if self.short:
    7.23 +            self.optkeys.append('-' + self.short)
    7.24 +        if self.long:
    7.25 +            self.optkeys.append('--' + self.long)
    7.26 +        self.fn = fn
    7.27 +        self.specified_opt = None
    7.28 +        self.specified_val = None
    7.29 +        self.set(default)
    7.30 +
    7.31 +    def set(self, value):
    7.32 +        setattr(self.opts, self.name, value)
    7.33 +
    7.34 +    def get(self):
    7.35 +        return getattr(self.opts, self.name)
    7.36 +
    7.37 +    def append(self, value):
    7.38 +        self.set(self.get().append(value))
    7.39 +
    7.40 +    def short_opt(self):
    7.41 +        if self.short:
    7.42 +            if self.val:
    7.43 +                return self.short + ':'
    7.44 +            else:
    7.45 +                return self.short
    7.46 +        else:
    7.47 +            return None
    7.48 +
    7.49 +    def long_opt(self):
    7.50 +        if self.long:
    7.51 +            if self.val:
    7.52 +                return self.long + '='
    7.53 +            else:
    7.54 +                return self.long
    7.55 +        else:
    7.56 +            return None
    7.57 +
    7.58 +    def show(self):
    7.59 +        sep = ''
    7.60 +        for x in self.optkeys:
    7.61 +            print sep, x,
    7.62 +            sep = ','
    7.63 +        if self.val:
    7.64 +            print self.val,
    7.65 +        print
    7.66 +        if self.use:
    7.67 +            print '\t',
    7.68 +            print self.use
    7.69 +        if self.val:
    7.70 +            print '\tDefault', self.default or 'None'
    7.71 +
    7.72 +    def specify(self, k, v):
    7.73 +        if k in self.optkeys:
    7.74 +            if self.val is None and v:
    7.75 +                self.opts.err("Option '%s' does not take a value" % k)
    7.76 +            self.specified_opt = k
    7.77 +            self.specified_val = v
    7.78 +            if self.fn:
    7.79 +                self.fn(self, k, v)
    7.80 +            return 1
    7.81 +        else:
    7.82 +            return 0
    7.83 +
    7.84 +class Opts:
    7.85 +    def __init__(self, use=None):
    7.86 +        self._usage = use
    7.87 +        self._options = []
    7.88 +        self._argv = []
    7.89 +        self._vals = {}
    7.90 +        self._globals = {}
    7.91 +        self._locals = {}
    7.92 +
    7.93 +    def opt(self, name, **args):
    7.94 +        x = Opt(self, name, **args)
    7.95 +        self._options.append(x)
    7.96 +        return x
    7.97 +
    7.98 +    def setvar(self, name, val):
    7.99 +        self._globals[name] = val
   7.100 +
   7.101 +    def err(self, msg):
   7.102 +        print >>sys.stderr, "Error:", msg
   7.103 +        sys.exit(1)
   7.104 +
   7.105 +    def info(self, msg):
   7.106 +        if self.quiet: return
   7.107 +        print msg
   7.108 +
   7.109 +    def warn(self, msg):
   7.110 +        print >>sys.stderr, "Warning:", msg
   7.111 +
   7.112 +    def parse(self, argv):
   7.113 +        self._argv = argv
   7.114 +        (vals, args) = getopt(argv[1:], self.short_opts(), self.long_opts())
   7.115 +        self._args = args
   7.116 +        for (k, v) in vals:
   7.117 +            for opt in self._options:
   7.118 +                if opt.specify(k, v): break
   7.119 +            else:
   7.120 +                print >>sys.stderr, "Error: Unknown option:", k
   7.121 +                self.usage()
   7.122 +        return args
   7.123 +
   7.124 +    def short_opts(self):
   7.125 +        l = []
   7.126 +        for x in self._options:
   7.127 +            y = x.short_opt()
   7.128 +            if not y: continue
   7.129 +            l.append(y)
   7.130 +        return ''.join(l)
   7.131 +
   7.132 +    def long_opts(self):
   7.133 +        l = []
   7.134 +        for x in self._options:
   7.135 +            y = x.long_opt()
   7.136 +            if not y: continue
   7.137 +            l.append(y)
   7.138 +        return ''.join(l)
   7.139 +
   7.140 +    def usage(self):
   7.141 +        print 'Usage: ', self._argv[0], self._usage or 'OPTIONS'
   7.142 +        for opt in self._options:
   7.143 +            opt.show()
   7.144 +
   7.145 +    def load_defaults(self):
   7.146 +        print 'load_defaults>', 'defaults=', self.defaults
   7.147 +        print 'load_defaults>', 'path=', self.path
   7.148 +        for x in [ '' ] + self.path.split(':'):
   7.149 +            print 'load_defaults>', 'x=', x, 'defaults=', self.defaults
   7.150 +            if x:
   7.151 +                p = os.path.join(x, self.defaults)
   7.152 +            else:
   7.153 +                p = self.defaults
   7.154 +            if os.stat(p):
   7.155 +                self.load(p)
   7.156 +                break
   7.157 +        else:
   7.158 +            self.err("Cannot open defaults file %s" % self.defaults)
   7.159 +
   7.160 +    def load(self, defaults):
   7.161 +        print 'load>', 'defaults=', defaults
   7.162 +        self._globals['sys'] = sys
   7.163 +        self._globals['config_file'] = defaults
   7.164 +        execfile(defaults, self._globals, self._locals)
   7.165 +        print 'load>', 'globals=', self._globals
   7.166 +        print 'load>', 'locals=', self._locals
   7.167 +            
   7.168 +
   7.169 +def set_true(opt, k, v):
   7.170 +    opt.set(1)
   7.171 +
   7.172 +def set_false(opt, k, v):
   7.173 +    opt.set(0)
   7.174 +
   7.175 +def set_value(opt, k, v):
   7.176 +    opt.set(v)
   7.177 +
   7.178 +def set_int(opt, k, v):
   7.179 +    try:
   7.180 +        v = int(v)
   7.181 +    except:
   7.182 +        opt.opts.err('Invalid value: ' + str(v))
   7.183 +    opt.set(v)
   7.184 +
   7.185 +def append_value(opt, k, v):
   7.186 +    opt.append(v)
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/xenmgr/lib/xm/shutdown.py	Tue Jun 15 16:52:08 2004 +0000
     8.3 @@ -0,0 +1,65 @@
     8.4 +import string
     8.5 +import sys
     8.6 +import time
     8.7 +
     8.8 +from xenmgr.XendClient import server
     8.9 +from xenmgr.xm import opts
    8.10 +
    8.11 +opts = Opts(use="""[options] [DOM]
    8.12 +
    8.13 +Shutdown one or more domains gracefully.""")
    8.14 +
    8.15 +opts.opt('help', short='h',
    8.16 +         fn=set_value, default=0,
    8.17 +         use="Print this help.")
    8.18 +
    8.19 +opts.opt('all', short='a',
    8.20 +         fn=set_true, default=0,
    8.21 +         use="Shutdown all domains.")
    8.22 +
    8.23 +opts.opt('wait', short='w',
    8.24 +         fn=set_true, default=0,
    8.25 +         use='Wait for shutdown to complete.')
    8.26 +
    8.27 +def shutdown(opts, doms, wait):
    8.28 +    def domains():
    8.29 +        return [ int(a) for a in server.xend_domains() ]
    8.30 +    if doms == None: doms = domains()
    8.31 +    if 0 in doms:
    8.32 +        doms.remove(0)
    8.33 +    for d in doms:
    8.34 +        server.xend_domain_shutdown(dom)
    8.35 +    if wait:
    8.36 +        while doms:
    8.37 +            alive = domains()
    8.38 +            dead = []
    8.39 +            for d in doms:
    8.40 +                if d in alive: continue
    8.41 +                dead.append(d)
    8.42 +            for d in dead:
    8.43 +                opts.info("Domain %d terminated" % d)
    8.44 +                doms.remove(d)
    8.45 +            time.sleep(1)
    8.46 +        opts.info("All domains terminated")
    8.47 +
    8.48 +def main_all(opts, args):
    8.49 +    shutdown(opts, None, opts.wait)
    8.50 +
    8.51 +def main_dom(opts, args):
    8.52 +    if len(args) < 2: opts.err('Missing domain')
    8.53 +    dom = argv[1]
    8.54 +    try:
    8.55 +        domid = int(dom)
    8.56 +    except:
    8.57 +        opts.err('Invalid domain: ' + dom)
    8.58 +    shutdown(opts, [ domid ], opts.wait)
    8.59 +    
    8.60 +def main(argv):
    8.61 +    args = opts.parse(argv)
    8.62 +    if opts.help:
    8.63 +        opts.usage()
    8.64 +    if opts.all:
    8.65 +        main_all(opts, args)
    8.66 +    else:
    8.67 +        main_dom(opts, args)
    8.68 +        
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/xenmgr/xm	Tue Jun 15 16:52:08 2004 +0000
     9.3 @@ -0,0 +1,6 @@
     9.4 +#!/usr/bin/python
     9.5 +#  -*- mode: python; -*-
     9.6 +import sys
     9.7 +from xenmgr.xm import main
     9.8 +
     9.9 +main.main(sys.argv)