direct-io.hg

changeset 1655:6edc06968b87

bitkeeper revision 1.1041.3.2 (40e41cd2iveMByv37PKjiwl04MigLQ)

Help for defaults files.
author mjw@wray-m-3.hpl.hp.com
date Thu Jul 01 14:16:50 2004 +0000 (2004-07-01)
parents 90b354900bbf
children 11fc1027833b 2e084d76fbf4
files .rootkeys tools/examples/xmdefaults tools/python/xen/xend/XendClient.py tools/python/xen/xend/server/cstruct.py tools/python/xen/xm/create.py tools/python/xen/xm/help.py tools/python/xen/xm/main.py tools/python/xen/xm/opts.py
line diff
     1.1 --- a/.rootkeys	Thu Jul 01 12:06:02 2004 +0000
     1.2 +++ b/.rootkeys	Thu Jul 01 14:16:50 2004 +0000
     1.3 @@ -259,7 +259,6 @@ 40c9c4692hckPol_EK0EGB16ZyDsyQ tools/pyt
     1.4  40c9c469N2-b3GqpLHHHPZykJPLVvA tools/python/xen/xend/server/channel.py
     1.5  40c9c469hJ_IlatRne-9QEa0-wlquw tools/python/xen/xend/server/console.py
     1.6  40c9c469UcNJh_NuLU0ytorM0Lk5Ow tools/python/xen/xend/server/controller.py
     1.7 -40c9c469vHh-qLiiubdbKEQbJf18Zw tools/python/xen/xend/server/cstruct.py
     1.8  40d83983OXjt-y3HjSCcuoPp9rzvmw tools/python/xen/xend/server/domain.py
     1.9  40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py
    1.10  40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py
    1.11 @@ -267,6 +266,7 @@ 40c9c469ZqILEQ8x6yWy0_51jopiCg tools/pyt
    1.12  40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py
    1.13  40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py
    1.14  40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
    1.15 +40e41cd2w0I4En6qrJn4em8HkK_oxQ tools/python/xen/xm/help.py
    1.16  40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py
    1.17  40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py
    1.18  40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/python/xen/xm/shutdown.py
     2.1 --- a/tools/examples/xmdefaults	Thu Jul 01 12:06:02 2004 +0000
     2.2 +++ b/tools/examples/xmdefaults	Thu Jul 01 14:16:50 2004 +0000
     2.3 @@ -2,17 +2,24 @@
     2.4  #============================================================================
     2.5  # Python defaults setup for 'xm create'.
     2.6  # Edit this file to reflect the configuration of your system.
     2.7 -# This file expects the variable 'vmid' to be set.
     2.8 +
     2.9  #============================================================================
    2.10  
    2.11 -try:
    2.12 -    vmid = int(vmid) # convert to integer
    2.13 -except:
    2.14 -    raise ValueError, "Variable 'vmid' must be an integer"
    2.15 +# Define script variables here.
    2.16 +# xm_vars is defined automatically, use xm_vars.var() to define a variable.
    2.17  
    2.18 -if vmid <= 0:
    2.19 -    raise ValueError, "Variable 'vmid' must be greater than 0" 
    2.20 +def vmid_check(var, val):
    2.21 +    val = int(val)
    2.22 +    if val <= 0:
    2.23 +        raise ValueError
    2.24 +    return val
    2.25 +    
    2.26 +xm_vars.var('vmid',
    2.27 +            use="Virtual machine id. Integer greater than 0.",
    2.28 +            check=vmid_check)
    2.29  
    2.30 +# This checks the script variables.
    2.31 +xm_vars.check()
    2.32  
    2.33  #----------------------------------------------------------------------------
    2.34  # Kernel image file.
     3.1 --- a/tools/python/xen/xend/XendClient.py	Thu Jul 01 12:06:02 2004 +0000
     3.2 +++ b/tools/python/xen/xend/XendClient.py	Thu Jul 01 14:16:50 2004 +0000
     3.3 @@ -1,6 +1,11 @@
     3.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     3.5  """Client API for the HTTP interface on xend.
     3.6  Callable as a script - see main().
     3.7 +
     3.8 +This API is the 'control-plane' for xend.
     3.9 +The 'data-plane' is done separately. For example, consoles
    3.10 +are accessed via sockets on xend, but the list of consoles
    3.11 +is accessible via this API.
    3.12  """
    3.13  import sys
    3.14  import httplib
    3.15 @@ -27,6 +32,8 @@ class Foo(httplib.HTTPResponse):
    3.16  
    3.17  
    3.18  def sxprio(sxpr):
    3.19 +    """Convert an sxpr to a string.
    3.20 +    """
    3.21      io = StringIO()
    3.22      sxp.show(sxpr, out=io)
    3.23      print >> io
    3.24 @@ -80,6 +87,12 @@ def eventurl(location, root, id=''):
    3.25      return urljoin(location, root, 'event/', id)
    3.26  
    3.27  def xend_request(url, method, data=None):
    3.28 +    """Make a request to xend.
    3.29 +
    3.30 +    url    xend request url
    3.31 +    method http method: POST or GET
    3.32 +    data   request argument data (dict)
    3.33 +    """
    3.34      urlinfo = urlparse.urlparse(url)
    3.35      (uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo
    3.36      if DEBUG: print url, urlinfo
    3.37 @@ -122,20 +135,37 @@ def xend_request(url, method, data=None)
    3.38      return val
    3.39  
    3.40  def xend_get(url, args=None):
    3.41 +    """Make a xend request using GET.
    3.42 +    Requests using GET are 'safe' and may be repeated without
    3.43 +    nasty side-effects.
    3.44 +    """
    3.45      return xend_request(url, "GET", args)
    3.46  
    3.47  def xend_call(url, data):
    3.48 +    """Make xend request using POST.
    3.49 +    Requests using POST potentially cause side-effects and should
    3.50 +    not be repeated unless it really is wanted to do the side
    3.51 +    effect again.
    3.52 +    """
    3.53      return xend_request(url, "POST", data)
    3.54  
    3.55  class Xend:
    3.56  
    3.57 +    """Default location of the xend server."""
    3.58      SRV_DEFAULT = "localhost:8000"
    3.59 +
    3.60 +    """Default path to the xend root on the server."""
    3.61      ROOT_DEFAULT = "/xend/"
    3.62  
    3.63      def __init__(self, srv=None, root=None):
    3.64          self.bind(srv, root)
    3.65  
    3.66      def bind(self, srv=None, root=None):
    3.67 +        """Bind to a given server.
    3.68 +
    3.69 +        srv  server location (host:port)
    3.70 +        root server xend root path
    3.71 +        """
    3.72          if srv is None: srv = self.SRV_DEFAULT
    3.73          if root is None: root = self.ROOT_DEFAULT
    3.74          if not root.endswith('/'): root += '/'
     4.1 --- a/tools/python/xen/xend/server/cstruct.py	Thu Jul 01 12:06:02 2004 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,269 +0,0 @@
     4.4 -import struct
     4.5 -
     4.6 -class Struct:
     4.7 -
     4.8 -    maxDepth = 10
     4.9 -
    4.10 -    base = ['x', 'B', 'H', 'I', 'L', 'Q', 'c', 'h', 'i', 'l', 'q', ]
    4.11 -
    4.12 -    sizes = {'B': 1,
    4.13 -            'H': 2,
    4.14 -            'I': 4,
    4.15 -            'L': 4,
    4.16 -            'Q': 8,
    4.17 -            'c': 1,
    4.18 -            'h': 2,
    4.19 -            'i': 4,
    4.20 -            'l': 4,
    4.21 -            'q': 8,
    4.22 -            'x': 1,
    4.23 -            }
    4.24 -
    4.25 -    formats = {
    4.26 -        'int8'          : 'B',
    4.27 -        'int16'         : 'H',
    4.28 -        'int32'         : 'I',
    4.29 -        'int64'         : 'Q',
    4.30 -        'u8'            : 'B',
    4.31 -        'u16'           : 'H',
    4.32 -        'u32'           : 'I',
    4.33 -        'u64'           : 'Q'
    4.34 -        }
    4.35 -
    4.36 -    def typedef(self, name, val):
    4.37 -        self.formats[name] = val
    4.38 -
    4.39 -    def struct(self, name, *f):
    4.40 -        self.typedef(name, StructInfo(self, f))
    4.41 -        
    4.42 -    def getType(self, name):
    4.43 -        return self.formats[name]
    4.44 -
    4.45 -    def format(self, ty):
    4.46 -        d = 0
    4.47 -        f = ty
    4.48 -        while d < self.maxDepth:
    4.49 -            d += 1
    4.50 -            f = self.formats[f]
    4.51 -            if isinstance(f, StructInfo):
    4.52 -                return f.format()
    4.53 -            if f in self.base:
    4.54 -                return f
    4.55 -        return -1
    4.56 -
    4.57 -    def alignedformat(self, ty):
    4.58 -        fmt = self.format(ty)
    4.59 -        #print 'alignedformat> %s |%s|' %(ty, fmt)
    4.60 -        afmt = self.align(fmt)
    4.61 -        #print 'alignedformat< %s |%s| |%s|' % (ty, fmt, afmt)
    4.62 -        return afmt
    4.63 -
    4.64 -    def align(self, fmt):
    4.65 -        n1 = 0
    4.66 -        afmt = ''
    4.67 -        for a in fmt:
    4.68 -            n2 = self.getSize(a)
    4.69 -            m = n1 % n2
    4.70 -            if m:
    4.71 -                d = (n2 - m)
    4.72 -                afmt += 'x' * d
    4.73 -                n1 += d
    4.74 -            afmt += a
    4.75 -            n1 += n2
    4.76 -        return afmt
    4.77 -
    4.78 -    def fmtsize(self, fmt):
    4.79 -        s = 0
    4.80 -        for f in fmt:
    4.81 -            s += self.getSize(f)
    4.82 -        return s
    4.83 -
    4.84 -    def getSize(self, f):
    4.85 -        return self.sizes[f]
    4.86 -
    4.87 -    def pack(self, ty, data):
    4.88 -        return self.getType(ty).pack(data)
    4.89 -
    4.90 -    def unpack(self, ty, data):
    4.91 -        return self.getType(ty).unpack(data)
    4.92 -
    4.93 -    def show(self):
    4.94 -        l = self.formats.keys()
    4.95 -        l.sort()
    4.96 -        for v in l:
    4.97 -            print "%-35s %-10s %s" % (v, self.format(v), self.alignedformat(v))
    4.98 -
    4.99 -
   4.100 -class StructInfo:
   4.101 -
   4.102 -    def __init__(self, s, f):
   4.103 -        self.fmt = None
   4.104 -        self.structs = s
   4.105 -        self.fields = f
   4.106 -
   4.107 -    def alignedformat(self):
   4.108 -        if self.afmt: return self.afmt
   4.109 -        self.afmt = self.structs.align(self.format())
   4.110 -        return self.afmt
   4.111 -    
   4.112 -    def format(self):
   4.113 -        if self.fmt: return self.fmt
   4.114 -        fmt = ""
   4.115 -        for (ty, name) in self.fields:
   4.116 -            fmt += self.formatString(ty)
   4.117 -        self.fmt = fmt
   4.118 -        return fmt
   4.119 -
   4.120 -    def formatString(self, ty):
   4.121 -        if ty in self.fields:
   4.122 -            ty = self.fields[ty]
   4.123 -        return self.structs.format(ty)
   4.124 -
   4.125 -    def pack(self, *args):
   4.126 -        return struct.pack(self.alignedformat(), *args)
   4.127 -
   4.128 -    def unpack(self, data):
   4.129 -        return struct.unpack(self.alignedformat(), data)
   4.130 -
   4.131 -types = Struct()
   4.132 -
   4.133 -types.typedef('short'         , 'h')
   4.134 -types.typedef('int'           , 'i')
   4.135 -types.typedef('long'          , 'l')
   4.136 -types.typedef('unsigned short', 'H')
   4.137 -types.typedef('unsigned int'  , 'I')
   4.138 -types.typedef('unsigned long' , 'L')
   4.139 -types.typedef('domid_t'       , 'u64')
   4.140 -types.typedef('blkif_vdev_t'  , 'u16')
   4.141 -types.typedef('blkif_pdev_t'  , 'u16')
   4.142 -types.typedef('blkif_sector_t', 'u64')
   4.143 -
   4.144 -types.struct('u8[6]',
   4.145 -             ('u8', 'a1'),
   4.146 -             ('u8', 'a2'),
   4.147 -             ('u8', 'a3'),
   4.148 -             ('u8', 'a4'),
   4.149 -             ('u8', 'a5'),
   4.150 -             ('u8', 'a6'))
   4.151 -             
   4.152 -types.struct('blkif_fe_interface_status_changed_t',
   4.153 -    ('unsigned int',    'handle'),
   4.154 -    ('unsigned int',    'status'),
   4.155 -    ('unsigned int',    'evtchn'))
   4.156 -
   4.157 -types.struct('blkif_fe_driver_status_changed_t',
   4.158 -    ('unsigned int',    'status'),
   4.159 -    ('unsigned int',    'nr_interfaces'))
   4.160 -
   4.161 -types.struct('blkif_fe_interface_connect_t',
   4.162 -    ('unsigned int' ,   'handle'),
   4.163 -    ('unsigned long',   'shmem_frame'))
   4.164 -
   4.165 -types.struct('blkif_fe_interface_disconnect_t',
   4.166 -    ('unsigned int',   'handle'))
   4.167 -
   4.168 -types.struct('blkif_extent_t',
   4.169 -    ('blkif_pdev_t'  , 'device'),
   4.170 -    ('blkif_sector_t', 'sector_start'),
   4.171 -    ('blkif_sector_t', 'sector_length'))
   4.172 -
   4.173 -types.struct('blkif_be_create_t', 
   4.174 -    ('domid_t'     ,   'domid'),
   4.175 -    ('unsigned int',   'blkif_handle'),
   4.176 -    ('unsigned int',   'status'))
   4.177 -             
   4.178 -types.struct('blkif_be_destroy_t',
   4.179 -    ('domid_t'     ,   'domid'),
   4.180 -    ('unsigned int',   'blkif_handle'),
   4.181 -    ('unsigned int',   'status'))
   4.182 -
   4.183 -types.struct('blkif_be_connect_t',
   4.184 -    ('domid_t'      ,  'domid'),
   4.185 -    ('unsigned int' ,  'blkif_handle'),
   4.186 -    ('unsigned int' ,  'evtchn'),
   4.187 -    ('unsigned long',  'shmem_frame'),
   4.188 -    ('unsigned int' ,  'status'))
   4.189 -
   4.190 -types.struct('blkif_be_disconnect_t',
   4.191 -    ('domid_t'     ,   'domid'),
   4.192 -    ('unsigned int',   'blkif_handle'),
   4.193 -    ('unsigned int',   'status'))
   4.194 -
   4.195 -types.struct('blkif_be_vbd_create_t', 
   4.196 -    ('domid_t'     ,   'domid'),         #Q
   4.197 -    ('unsigned int',   'blkif_handle'),  #I
   4.198 -    ('blkif_vdev_t',   'vdevice'),       #H
   4.199 -    ('int'         ,   'readonly'),      #i
   4.200 -    ('unsigned int',   'status'))        #I
   4.201 -
   4.202 -types.struct('blkif_be_vbd_destroy_t', 
   4.203 -    ('domid_t'     ,   'domid'),
   4.204 -    ('unsigned int',   'blkif_handle'),
   4.205 -    ('blkif_vdev_t',   'vdevice'),
   4.206 -    ('unsigned int',   'status'))
   4.207 -
   4.208 -types.struct('blkif_be_vbd_grow_t', 
   4.209 -    ('domid_t'       , 'domid'),         #Q
   4.210 -    ('unsigned int'  , 'blkif_handle'),  #I
   4.211 -    ('blkif_vdev_t'  , 'vdevice'),       #H   
   4.212 -    ('blkif_extent_t', 'extent'),        #HQQ
   4.213 -    ('unsigned int'  , 'status'))        #I
   4.214 -
   4.215 -types.struct('blkif_be_vbd_shrink_t', 
   4.216 -    ('domid_t'     ,   'domid'),
   4.217 -    ('unsigned int',   'blkif_handle'),
   4.218 -    ('blkif_vdev_t',   'vdevice'),
   4.219 -    ('unsigned int',   'status'))
   4.220 -
   4.221 -types.struct('blkif_be_driver_status_changed_t',
   4.222 -    ('unsigned int',   'status'),
   4.223 -    ('unsigned int',   'nr_interfaces'))
   4.224 -
   4.225 -types.struct('netif_fe_interface_status_changed_t',
   4.226 -    ('unsigned int',   'handle'),
   4.227 -    ('unsigned int',   'status'),
   4.228 -    ('unsigned int',   'evtchn'),
   4.229 -    ('u8[6]',          'mac'))
   4.230 -
   4.231 -types.struct('netif_fe_driver_status_changed_t',
   4.232 -    ('unsigned int',   'status'),
   4.233 -    ('unsigned int',   'nr_interfaces'))
   4.234 -
   4.235 -types.struct('netif_fe_interface_connect_t',
   4.236 -    ('unsigned int',   'handle'),
   4.237 -    ('unsigned long',  'tx_shmem_frame'),
   4.238 -    ('unsigned long',  'rx_shmem_frame'))
   4.239 -
   4.240 -types.struct('netif_fe_interface_disconnect_t',
   4.241 -    ('unsigned int',   'handle'))
   4.242 -
   4.243 -types.struct('netif_be_create_t', 
   4.244 -    ('domid_t'     ,   'domid'),
   4.245 -    ('unsigned int',   'netif_handle'),
   4.246 -    ('u8[6]'       ,   'mac'),
   4.247 -    ('unsigned int',   'status'))
   4.248 -
   4.249 -types.struct('netif_be_destroy_t',
   4.250 -    ('domid_t'     ,   'domid'),
   4.251 -    ('unsigned int',   'netif_handle'),
   4.252 -    ('unsigned int',   'status'))
   4.253 -
   4.254 -types.struct('netif_be_connect_t', 
   4.255 -    ('domid_t'      ,  'domid'),
   4.256 -    ('unsigned int' ,  'netif_handle'),
   4.257 -    ('unsigned int' ,  'evtchn'),
   4.258 -    ('unsigned long',  'tx_shmem_frame'),
   4.259 -    ('unsigned long',  'rx_shmem_frame'),
   4.260 -    ('unsigned int' ,  'status'))
   4.261 -
   4.262 -types.struct('netif_be_disconnect_t',
   4.263 -    ('domid_t'     ,   'domid'),
   4.264 -    ('unsigned int',   'netif_handle'),
   4.265 -    ('unsigned int',   'status'))
   4.266 -
   4.267 -types.struct('netif_be_driver_status_changed_t',
   4.268 -    ('unsigned int',   'status'),
   4.269 -    ('unsigned int',   'nr_interfaces'))
   4.270 -
   4.271 -if 1 or __name__ == "__main__":
   4.272 -    types.show()
     5.1 --- a/tools/python/xen/xm/create.py	Thu Jul 01 12:06:02 2004 +0000
     5.2 +++ b/tools/python/xen/xm/create.py	Thu Jul 01 14:16:50 2004 +0000
     5.3 @@ -1,4 +1,5 @@
     5.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     5.5 +
     5.6  """Domain creation.
     5.7  """
     5.8  import string
     5.9 @@ -15,12 +16,22 @@ from xen.xm.opts import *
    5.10  gopts = Opts(use="""[options]
    5.11  
    5.12  Create a domain.
    5.13 +
    5.14 +Domain creation parameters can be set by command-line switches, from
    5.15 +a python configuration script or an SXP config file. See documentation
    5.16 +for --defaults, --config. Configuration variables can be set using
    5.17 +VAR=VAL on the command line. For example vmid=3 sets vmid to 3.
    5.18 +
    5.19  """)
    5.20  
    5.21  gopts.opt('help', short='h',
    5.22           fn=set_true, default=0,
    5.23           use="Print this help.")
    5.24  
    5.25 +gopts.opt('help_config',
    5.26 +          fn=set_true, default=0,
    5.27 +          use="Print help for configuration file.")
    5.28 +
    5.29  gopts.opt('quiet', short='q',
    5.30           fn=set_true, default=0,
    5.31           use="Quiet.")
    5.32 @@ -31,24 +42,40 @@ gopts.opt('path', val='PATH',
    5.33  
    5.34  gopts.opt('defaults', short='f', val='FILE',
    5.35           fn=set_value, default='xmdefaults',
    5.36 -         use="Use the given default script.")
    5.37 +         use="""Use the given Python defaults script.
    5.38 +The defaults script is loaded after arguments have been processed.
    5.39 +Each command-line option sets a configuration variable named after
    5.40 +its long option name, and these variables are placed in the
    5.41 +environment of the script before it is loaded.
    5.42 +Variables for options that may be repeated have list values.
    5.43 +Other variables can be set using VAR=VAL on the command line.
    5.44 +
    5.45 +After the script is loaded, option values that were not set on the
    5.46 +command line are replaced by the values set in the script.
    5.47 +""")
    5.48  
    5.49  gopts.opt('config', short='F', val='FILE',
    5.50           fn=set_value, default=None,
    5.51 -         use='Domain configuration to use (SXP).')
    5.52 +         use="""Domain configuration to use (SXP).
    5.53 +SXP is the underlying configuration format used by Xen.
    5.54 +SXP configs can be hand-written or generated from Python defaults
    5.55 +scripts, using the -n (dryrun) option to print the config.
    5.56 +""")
    5.57  
    5.58  gopts.opt('load', short='L', val='FILE',
    5.59            fn=set_value, default=None,
    5.60            use='Domain saved state to load.')
    5.61  
    5.62 -gopts.opt('define', short='D', val='VAR=VAL',
    5.63 -         fn=set_var, default=None,
    5.64 -         use="""Set a variable before loading defaults, e.g. '-D vmid=3'
    5.65 -         to set vmid. May be repeated to set more thanone variable.""")
    5.66 +#gopts.opt('define', short='D', val='VAR=VAL',
    5.67 +#         fn=set_var, default=None,
    5.68 +#         use="""Set a variable before loading defaults, e.g. '-D vmid=3'
    5.69 +#         to set vmid. May be repeated to set more than one variable.""")
    5.70  
    5.71  gopts.opt('dryrun', short='n',
    5.72           fn=set_true, default=0,
    5.73 -         use="Dry run - print the config but don't create the domain.")
    5.74 +         use="""Dry run - print the config but don't create the domain.
    5.75 +The defaults file is loaded and the SXP configuration is created and printed.         
    5.76 +""")
    5.77  
    5.78  gopts.opt('name', short='N', val='NAME',
    5.79            fn=set_value, default=None,
    5.80 @@ -352,7 +379,15 @@ def main(argv):
    5.81      args = opts.parse(argv)
    5.82      if opts.vals.help:
    5.83          opts.usage()
    5.84 +    if opts.vals.help or opts.vals.help_config:
    5.85 +        opts.load_defaults(help=1)
    5.86 +    if opts.vals.help or opts.vals.help_config:
    5.87          return
    5.88 +    # Process remaining args as config variables.
    5.89 +    for arg in args:
    5.90 +        if '=' in arg:
    5.91 +            (var, val) = arg.strip().split('=')
    5.92 +            gopts.setvar(var.strip(), val.strip())
    5.93      if opts.vals.config:
    5.94          pass
    5.95      else:
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/python/xen/xm/help.py	Thu Jul 01 14:16:50 2004 +0000
     6.3 @@ -0,0 +1,82 @@
     6.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     6.5 +
     6.6 +"""Variable definition and help support for Python defaults files.
     6.7 +"""
     6.8 +
     6.9 +import sys
    6.10 +
    6.11 +class Vars:
    6.12 +    """A set of configuration variables.
    6.13 +    """
    6.14 +
    6.15 +    def __init__(self, name, help, env):
    6.16 +        """Create a variable set.
    6.17 +
    6.18 +        name name of the defaults file
    6.19 +        help help flag
    6.20 +        env  local environment
    6.21 +        """
    6.22 +        self.name = name
    6.23 +        self.help = help
    6.24 +        self.env = env
    6.25 +        self.vars = []
    6.26 +
    6.27 +    def var(self, name, use=None, check=None):
    6.28 +        """Define a configuration variable.
    6.29 +        If provided, the check function will be called as check(var, val)
    6.30 +        where var is the variable name and val is its value (string).
    6.31 +        It should return a new value for the variable, or raise ValueError if
    6.32 +        the value is not acceptable.
    6.33 +
    6.34 +        name  variable name
    6.35 +        use   variable usage string
    6.36 +        check variable check function
    6.37 +        """
    6.38 +        self.vars.append(Var(name, use, check))
    6.39 +
    6.40 +    def check(self):
    6.41 +        """Execute the variable checks or print help, depending on the value
    6.42 +        of the help flag passed to the constructor.
    6.43 +        """
    6.44 +        if self.help:
    6.45 +            self.doHelp()
    6.46 +        else:
    6.47 +            for v in self.vars:
    6.48 +                v.doCheck(self.env)
    6.49 +
    6.50 +    def doHelp(self, out=sys.stderr):
    6.51 +        """Print help for the variables.
    6.52 +        """
    6.53 +        if self.vars:
    6.54 +            print >>out, "\nConfiguration variables for %s:\n" % self.name
    6.55 +            for v in self.vars:
    6.56 +                v.doHelp(out)
    6.57 +            print >>out
    6.58 +
    6.59 +class Var:
    6.60 +    """A single variable.
    6.61 +    """
    6.62 +
    6.63 +    def __init__(self, name, use, check):
    6.64 +        """Create a variable.
    6.65 +
    6.66 +        name  variable name
    6.67 +        use   variable use string
    6.68 +        check variable value check function
    6.69 +        """
    6.70 +        self.name = name
    6.71 +        self.use = use or ''
    6.72 +        self.check = check
    6.73 +
    6.74 +    def doCheck(self, env):
    6.75 +        """Execute the check and set the variable to the new value.
    6.76 +        """
    6.77 +        if not self.check: return
    6.78 +        env[self.name] = self.check(self.name, env.get(self.name))
    6.79 +
    6.80 +    def doHelp(self, out):
    6.81 +        """Print help for the variable.
    6.82 +        """
    6.83 +        print >>out, "%-12s" % self.name, self.use
    6.84 +
    6.85 +        
     7.1 --- a/tools/python/xen/xm/main.py	Thu Jul 01 12:06:02 2004 +0000
     7.2 +++ b/tools/python/xen/xm/main.py	Thu Jul 01 14:16:50 2004 +0000
     7.3 @@ -5,10 +5,12 @@ import os
     7.4  import os.path
     7.5  import sys
     7.6  from getopt import getopt
     7.7 +import socket
     7.8  
     7.9  from xen.xend import PrettyPrint
    7.10  from xen.xend import sxp
    7.11  from xen.xend.XendClient import server
    7.12 +from xen.xend.XendClient import main as xend_client_main
    7.13  from xen.xm import create, shutdown
    7.14  
    7.15  class Prog:
    7.16 @@ -65,6 +67,13 @@ class Xm:
    7.17          sys.exit(1)
    7.18  
    7.19      def main(self, args):
    7.20 +        try:
    7.21 +            self.main_call(args)
    7.22 +        except socket.error, ex:
    7.23 +            print >>sys.stderr, ex
    7.24 +            self.err("Error connecting to xend, is xend running?")
    7.25 +
    7.26 +    def main_call(self, args):
    7.27          """Main entry point. Dispatches to the progs.
    7.28          """
    7.29          self.name = args[0]
    7.30 @@ -444,5 +453,21 @@ class ProgConsole(Prog):
    7.31  
    7.32  xm.prog(ProgConsole)
    7.33  
    7.34 +class ProgCall(Prog):
    7.35 +    name = "call"
    7.36 +    info = "Call xend api functions."
    7.37 +
    7.38 +    def help (self, args):
    7.39 +        print "call fn argss..."
    7.40 +        print """
    7.41 +        Call a xend HTTP API function. The leading 'xend_' on the function
    7.42 +can be omitted. See xen.xend.XendClient for the API functions.
    7.43 +"""
    7.44 +
    7.45 +    def main(self, args):
    7.46 +        xend_client_main(args)
    7.47 +
    7.48 +xm.prog(ProgCall)
    7.49 +
    7.50  def main(args):
    7.51      xm.main(args)
     8.1 --- a/tools/python/xen/xm/opts.py	Thu Jul 01 12:06:02 2004 +0000
     8.2 +++ b/tools/python/xen/xm/opts.py	Thu Jul 01 14:16:50 2004 +0000
     8.3 @@ -259,7 +259,7 @@ class Opts:
     8.4          for opt in self.options:
     8.5              opt.show()
     8.6  
     8.7 -    def load_defaults(self):
     8.8 +    def load_defaults(self, help=0):
     8.9          """Load a defaults script. Assumes these options set:
    8.10          'path'    search path
    8.11          'default' script name
    8.12 @@ -270,12 +270,12 @@ class Opts:
    8.13              else:
    8.14                  p = self.vals.defaults
    8.15              if os.path.exists(p):
    8.16 -                self.load(p)
    8.17 +                self.load(p, help)
    8.18                  break
    8.19          else:
    8.20              self.err("Cannot open defaults file %s" % self.vals.defaults)
    8.21  
    8.22 -    def load(self, defaults, help=0):
    8.23 +    def load(self, defaults, help):
    8.24          """Load a defaults file. Local variables in the file
    8.25          are used to set options with the same names.
    8.26          Variables are not used to set options that are already specified.
    8.27 @@ -290,11 +290,17 @@ class Opts:
    8.28          cmd = '\n'.join(["import sys",
    8.29                           "import os",
    8.30                           "import os.path",
    8.31 -                         "import xen.util.ip",
    8.32 +                         "from xen.xm.help import Vars",
    8.33 +                         "from xen.util import ip",
    8.34                           "xm_file = '%s'" % defaults,
    8.35 -                         "xm_help = %d" % help ])
    8.36 +                         "xm_help = %d" % help,
    8.37 +                         "xm_vars = Vars(xm_file, xm_help, locals())",
    8.38 +                         ])
    8.39          exec cmd in globals, locals
    8.40 -        execfile(defaults, globals, locals)
    8.41 +        try:
    8.42 +            execfile(defaults, globals, locals)
    8.43 +        except:
    8.44 +            if not help: raise
    8.45          if help: return
    8.46          # Extract the values set by the script and set the corresponding
    8.47          # options, if not set on the command line.