mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
bitkeeper revision 1.1041.3.2 (40e41cd2iveMByv37PKjiwl04MigLQ)
Help for defaults files.
This commit is contained in:
1 parent
76e8d2ff6a
commit
da4eba9f1e
8 files changed
+206
-290
No files matched your search
@@ -1,6 +1,11 @@
|
||||
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
|
||||
"""Client API for the HTTP interface on xend.
|
||||
Callable as a script - see main().
|
||||
|
||||
This API is the 'control-plane' for xend.
|
||||
The 'data-plane' is done separately. For example, consoles
|
||||
are accessed via sockets on xend, but the list of consoles
|
||||
is accessible via this API.
|
||||
"""
|
||||
import sys
|
||||
import httplib
|
||||
@@ -27,6 +32,8 @@ class Foo(httplib.HTTPResponse):
|
||||
|
||||
|
||||
def sxprio(sxpr):
|
||||
"""Convert an sxpr to a string.
|
||||
"""
|
||||
io = StringIO()
|
||||
sxp.show(sxpr, out=io)
|
||||
print >> io
|
||||
@@ -80,6 +87,12 @@ def eventurl(location, root, id=''):
|
||||
return urljoin(location, root, 'event/', id)
|
||||
|
||||
def xend_request(url, method, data=None):
|
||||
"""Make a request to xend.
|
||||
|
||||
url xend request url
|
||||
method http method: POST or GET
|
||||
data request argument data (dict)
|
||||
"""
|
||||
urlinfo = urlparse.urlparse(url)
|
||||
(uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo
|
||||
if DEBUG: print url, urlinfo
|
||||
@@ -122,20 +135,37 @@ def xend_request(url, method, data=None):
|
||||
return val
|
||||
|
||||
def xend_get(url, args=None):
|
||||
"""Make a xend request using GET.
|
||||
Requests using GET are 'safe' and may be repeated without
|
||||
nasty side-effects.
|
||||
"""
|
||||
return xend_request(url, "GET", args)
|
||||
|
||||
def xend_call(url, data):
|
||||
"""Make xend request using POST.
|
||||
Requests using POST potentially cause side-effects and should
|
||||
not be repeated unless it really is wanted to do the side
|
||||
effect again.
|
||||
"""
|
||||
return xend_request(url, "POST", data)
|
||||
|
||||
class Xend:
|
||||
|
||||
"""Default location of the xend server."""
|
||||
SRV_DEFAULT = "localhost:8000"
|
||||
|
||||
"""Default path to the xend root on the server."""
|
||||
ROOT_DEFAULT = "/xend/"
|
||||
|
||||
def __init__(self, srv=None, root=None):
|
||||
self.bind(srv, root)
|
||||
|
||||
def bind(self, srv=None, root=None):
|
||||
"""Bind to a given server.
|
||||
|
||||
srv server location (host:port)
|
||||
root server xend root path
|
||||
"""
|
||||
if srv is None: srv = self.SRV_DEFAULT
|
||||
if root is None: root = self.ROOT_DEFAULT
|
||||
if not root.endswith('/'): root += '/'
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
import struct
|
||||
|
||||
class Struct:
|
||||
|
||||
maxDepth = 10
|
||||
|
||||
base = ['x', 'B', 'H', 'I', 'L', 'Q', 'c', 'h', 'i', 'l', 'q', ]
|
||||
|
||||
sizes = {'B': 1,
|
||||
'H': 2,
|
||||
'I': 4,
|
||||
'L': 4,
|
||||
'Q': 8,
|
||||
'c': 1,
|
||||
'h': 2,
|
||||
'i': 4,
|
||||
'l': 4,
|
||||
'q': 8,
|
||||
'x': 1,
|
||||
}
|
||||
|
||||
formats = {
|
||||
'int8' : 'B',
|
||||
'int16' : 'H',
|
||||
'int32' : 'I',
|
||||
'int64' : 'Q',
|
||||
'u8' : 'B',
|
||||
'u16' : 'H',
|
||||
'u32' : 'I',
|
||||
'u64' : 'Q'
|
||||
}
|
||||
|
||||
def typedef(self, name, val):
|
||||
self.formats[name] = val
|
||||
|
||||
def struct(self, name, *f):
|
||||
self.typedef(name, StructInfo(self, f))
|
||||
|
||||
def getType(self, name):
|
||||
return self.formats[name]
|
||||
|
||||
def format(self, ty):
|
||||
d = 0
|
||||
f = ty
|
||||
while d < self.maxDepth:
|
||||
d += 1
|
||||
f = self.formats[f]
|
||||
if isinstance(f, StructInfo):
|
||||
return f.format()
|
||||
if f in self.base:
|
||||
return f
|
||||
return -1
|
||||
|
||||
def alignedformat(self, ty):
|
||||
fmt = self.format(ty)
|
||||
#print 'alignedformat> %s |%s|' %(ty, fmt)
|
||||
afmt = self.align(fmt)
|
||||
#print 'alignedformat< %s |%s| |%s|' % (ty, fmt, afmt)
|
||||
return afmt
|
||||
|
||||
def align(self, fmt):
|
||||
n1 = 0
|
||||
afmt = ''
|
||||
for a in fmt:
|
||||
n2 = self.getSize(a)
|
||||
m = n1 % n2
|
||||
if m:
|
||||
d = (n2 - m)
|
||||
afmt += 'x' * d
|
||||
n1 += d
|
||||
afmt += a
|
||||
n1 += n2
|
||||
return afmt
|
||||
|
||||
def fmtsize(self, fmt):
|
||||
s = 0
|
||||
for f in fmt:
|
||||
s += self.getSize(f)
|
||||
return s
|
||||
|
||||
def getSize(self, f):
|
||||
return self.sizes[f]
|
||||
|
||||
def pack(self, ty, data):
|
||||
return self.getType(ty).pack(data)
|
||||
|
||||
def unpack(self, ty, data):
|
||||
return self.getType(ty).unpack(data)
|
||||
|
||||
def show(self):
|
||||
l = self.formats.keys()
|
||||
l.sort()
|
||||
for v in l:
|
||||
print "%-35s %-10s %s" % (v, self.format(v), self.alignedformat(v))
|
||||
|
||||
|
||||
class StructInfo:
|
||||
|
||||
def __init__(self, s, f):
|
||||
self.fmt = None
|
||||
self.structs = s
|
||||
self.fields = f
|
||||
|
||||
def alignedformat(self):
|
||||
if self.afmt: return self.afmt
|
||||
self.afmt = self.structs.align(self.format())
|
||||
return self.afmt
|
||||
|
||||
def format(self):
|
||||
if self.fmt: return self.fmt
|
||||
fmt = ""
|
||||
for (ty, name) in self.fields:
|
||||
fmt += self.formatString(ty)
|
||||
self.fmt = fmt
|
||||
return fmt
|
||||
|
||||
def formatString(self, ty):
|
||||
if ty in self.fields:
|
||||
ty = self.fields[ty]
|
||||
return self.structs.format(ty)
|
||||
|
||||
def pack(self, *args):
|
||||
return struct.pack(self.alignedformat(), *args)
|
||||
|
||||
def unpack(self, data):
|
||||
return struct.unpack(self.alignedformat(), data)
|
||||
|
||||
types = Struct()
|
||||
|
||||
types.typedef('short' , 'h')
|
||||
types.typedef('int' , 'i')
|
||||
types.typedef('long' , 'l')
|
||||
types.typedef('unsigned short', 'H')
|
||||
types.typedef('unsigned int' , 'I')
|
||||
types.typedef('unsigned long' , 'L')
|
||||
types.typedef('domid_t' , 'u64')
|
||||
types.typedef('blkif_vdev_t' , 'u16')
|
||||
types.typedef('blkif_pdev_t' , 'u16')
|
||||
types.typedef('blkif_sector_t', 'u64')
|
||||
|
||||
types.struct('u8[6]',
|
||||
('u8', 'a1'),
|
||||
('u8', 'a2'),
|
||||
('u8', 'a3'),
|
||||
('u8', 'a4'),
|
||||
('u8', 'a5'),
|
||||
('u8', 'a6'))
|
||||
|
||||
types.struct('blkif_fe_interface_status_changed_t',
|
||||
('unsigned int', 'handle'),
|
||||
('unsigned int', 'status'),
|
||||
('unsigned int', 'evtchn'))
|
||||
|
||||
types.struct('blkif_fe_driver_status_changed_t',
|
||||
('unsigned int', 'status'),
|
||||
('unsigned int', 'nr_interfaces'))
|
||||
|
||||
types.struct('blkif_fe_interface_connect_t',
|
||||
('unsigned int' , 'handle'),
|
||||
('unsigned long', 'shmem_frame'))
|
||||
|
||||
types.struct('blkif_fe_interface_disconnect_t',
|
||||
('unsigned int', 'handle'))
|
||||
|
||||
types.struct('blkif_extent_t',
|
||||
('blkif_pdev_t' , 'device'),
|
||||
('blkif_sector_t', 'sector_start'),
|
||||
('blkif_sector_t', 'sector_length'))
|
||||
|
||||
types.struct('blkif_be_create_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'blkif_handle'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('blkif_be_destroy_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'blkif_handle'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('blkif_be_connect_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int' , 'blkif_handle'),
|
||||
('unsigned int' , 'evtchn'),
|
||||
('unsigned long', 'shmem_frame'),
|
||||
('unsigned int' , 'status'))
|
||||
|
||||
types.struct('blkif_be_disconnect_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'blkif_handle'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('blkif_be_vbd_create_t',
|
||||
('domid_t' , 'domid'), #Q
|
||||
('unsigned int', 'blkif_handle'), #I
|
||||
('blkif_vdev_t', 'vdevice'), #H
|
||||
('int' , 'readonly'), #i
|
||||
('unsigned int', 'status')) #I
|
||||
|
||||
types.struct('blkif_be_vbd_destroy_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'blkif_handle'),
|
||||
('blkif_vdev_t', 'vdevice'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('blkif_be_vbd_grow_t',
|
||||
('domid_t' , 'domid'), #Q
|
||||
('unsigned int' , 'blkif_handle'), #I
|
||||
('blkif_vdev_t' , 'vdevice'), #H
|
||||
('blkif_extent_t', 'extent'), #HQQ
|
||||
('unsigned int' , 'status')) #I
|
||||
|
||||
types.struct('blkif_be_vbd_shrink_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'blkif_handle'),
|
||||
('blkif_vdev_t', 'vdevice'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('blkif_be_driver_status_changed_t',
|
||||
('unsigned int', 'status'),
|
||||
('unsigned int', 'nr_interfaces'))
|
||||
|
||||
types.struct('netif_fe_interface_status_changed_t',
|
||||
('unsigned int', 'handle'),
|
||||
('unsigned int', 'status'),
|
||||
('unsigned int', 'evtchn'),
|
||||
('u8[6]', 'mac'))
|
||||
|
||||
types.struct('netif_fe_driver_status_changed_t',
|
||||
('unsigned int', 'status'),
|
||||
('unsigned int', 'nr_interfaces'))
|
||||
|
||||
types.struct('netif_fe_interface_connect_t',
|
||||
('unsigned int', 'handle'),
|
||||
('unsigned long', 'tx_shmem_frame'),
|
||||
('unsigned long', 'rx_shmem_frame'))
|
||||
|
||||
types.struct('netif_fe_interface_disconnect_t',
|
||||
('unsigned int', 'handle'))
|
||||
|
||||
types.struct('netif_be_create_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'netif_handle'),
|
||||
('u8[6]' , 'mac'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('netif_be_destroy_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'netif_handle'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('netif_be_connect_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int' , 'netif_handle'),
|
||||
('unsigned int' , 'evtchn'),
|
||||
('unsigned long', 'tx_shmem_frame'),
|
||||
('unsigned long', 'rx_shmem_frame'),
|
||||
('unsigned int' , 'status'))
|
||||
|
||||
types.struct('netif_be_disconnect_t',
|
||||
('domid_t' , 'domid'),
|
||||
('unsigned int', 'netif_handle'),
|
||||
('unsigned int', 'status'))
|
||||
|
||||
types.struct('netif_be_driver_status_changed_t',
|
||||
('unsigned int', 'status'),
|
||||
('unsigned int', 'nr_interfaces'))
|
||||
|
||||
if 1 or __name__ == "__main__":
|
||||
types.show()
|
||||
@@ -1,4 +1,5 @@
|
||||
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
|
||||
|
||||
"""Domain creation.
|
||||
"""
|
||||
import string
|
||||
@@ -15,12 +16,22 @@ from xen.xm.opts import *
|
||||
gopts = Opts(use="""[options]
|
||||
|
||||
Create a domain.
|
||||
|
||||
Domain creation parameters can be set by command-line switches, from
|
||||
a python configuration script or an SXP config file. See documentation
|
||||
for --defaults, --config. Configuration variables can be set using
|
||||
VAR=VAL on the command line. For example vmid=3 sets vmid to 3.
|
||||
|
||||
""")
|
||||
|
||||
gopts.opt('help', short='h',
|
||||
fn=set_true, default=0,
|
||||
use="Print this help.")
|
||||
|
||||
gopts.opt('help_config',
|
||||
fn=set_true, default=0,
|
||||
use="Print help for configuration file.")
|
||||
|
||||
gopts.opt('quiet', short='q',
|
||||
fn=set_true, default=0,
|
||||
use="Quiet.")
|
||||
@@ -31,24 +42,40 @@ gopts.opt('path', val='PATH',
|
||||
|
||||
gopts.opt('defaults', short='f', val='FILE',
|
||||
fn=set_value, default='xmdefaults',
|
||||
use="Use the given default script.")
|
||||
use="""Use the given Python defaults script.
|
||||
The defaults script is loaded after arguments have been processed.
|
||||
Each command-line option sets a configuration variable named after
|
||||
its long option name, and these variables are placed in the
|
||||
environment of the script before it is loaded.
|
||||
Variables for options that may be repeated have list values.
|
||||
Other variables can be set using VAR=VAL on the command line.
|
||||
|
||||
After the script is loaded, option values that were not set on the
|
||||
command line are replaced by the values set in the script.
|
||||
""")
|
||||
|
||||
gopts.opt('config', short='F', val='FILE',
|
||||
fn=set_value, default=None,
|
||||
use='Domain configuration to use (SXP).')
|
||||
use="""Domain configuration to use (SXP).
|
||||
SXP is the underlying configuration format used by Xen.
|
||||
SXP configs can be hand-written or generated from Python defaults
|
||||
scripts, using the -n (dryrun) option to print the config.
|
||||
""")
|
||||
|
||||
gopts.opt('load', short='L', val='FILE',
|
||||
fn=set_value, default=None,
|
||||
use='Domain saved state to load.')
|
||||
|
||||
gopts.opt('define', short='D', val='VAR=VAL',
|
||||
fn=set_var, default=None,
|
||||
use="""Set a variable before loading defaults, e.g. '-D vmid=3'
|
||||
to set vmid. May be repeated to set more thanone variable.""")
|
||||
#gopts.opt('define', short='D', val='VAR=VAL',
|
||||
# fn=set_var, default=None,
|
||||
# use="""Set a variable before loading defaults, e.g. '-D vmid=3'
|
||||
# to set vmid. May be repeated to set more than one variable.""")
|
||||
|
||||
gopts.opt('dryrun', short='n',
|
||||
fn=set_true, default=0,
|
||||
use="Dry run - print the config but don't create the domain.")
|
||||
use="""Dry run - print the config but don't create the domain.
|
||||
The defaults file is loaded and the SXP configuration is created and printed.
|
||||
""")
|
||||
|
||||
gopts.opt('name', short='N', val='NAME',
|
||||
fn=set_value, default=None,
|
||||
@@ -352,7 +379,15 @@ def main(argv):
|
||||
args = opts.parse(argv)
|
||||
if opts.vals.help:
|
||||
opts.usage()
|
||||
if opts.vals.help or opts.vals.help_config:
|
||||
opts.load_defaults(help=1)
|
||||
if opts.vals.help or opts.vals.help_config:
|
||||
return
|
||||
# Process remaining args as config variables.
|
||||
for arg in args:
|
||||
if '=' in arg:
|
||||
(var, val) = arg.strip().split('=')
|
||||
gopts.setvar(var.strip(), val.strip())
|
||||
if opts.vals.config:
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
|
||||
|
||||
"""Variable definition and help support for Python defaults files.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
class Vars:
|
||||
"""A set of configuration variables.
|
||||
"""
|
||||
|
||||
def __init__(self, name, help, env):
|
||||
"""Create a variable set.
|
||||
|
||||
name name of the defaults file
|
||||
help help flag
|
||||
env local environment
|
||||
"""
|
||||
self.name = name
|
||||
self.help = help
|
||||
self.env = env
|
||||
self.vars = []
|
||||
|
||||
def var(self, name, use=None, check=None):
|
||||
"""Define a configuration variable.
|
||||
If provided, the check function will be called as check(var, val)
|
||||
where var is the variable name and val is its value (string).
|
||||
It should return a new value for the variable, or raise ValueError if
|
||||
the value is not acceptable.
|
||||
|
||||
name variable name
|
||||
use variable usage string
|
||||
check variable check function
|
||||
"""
|
||||
self.vars.append(Var(name, use, check))
|
||||
|
||||
def check(self):
|
||||
"""Execute the variable checks or print help, depending on the value
|
||||
of the help flag passed to the constructor.
|
||||
"""
|
||||
if self.help:
|
||||
self.doHelp()
|
||||
else:
|
||||
for v in self.vars:
|
||||
v.doCheck(self.env)
|
||||
|
||||
def doHelp(self, out=sys.stderr):
|
||||
"""Print help for the variables.
|
||||
"""
|
||||
if self.vars:
|
||||
print >>out, "\nConfiguration variables for %s:\n" % self.name
|
||||
for v in self.vars:
|
||||
v.doHelp(out)
|
||||
print >>out
|
||||
|
||||
class Var:
|
||||
"""A single variable.
|
||||
"""
|
||||
|
||||
def __init__(self, name, use, check):
|
||||
"""Create a variable.
|
||||
|
||||
name variable name
|
||||
use variable use string
|
||||
check variable value check function
|
||||
"""
|
||||
self.name = name
|
||||
self.use = use or ''
|
||||
self.check = check
|
||||
|
||||
def doCheck(self, env):
|
||||
"""Execute the check and set the variable to the new value.
|
||||
"""
|
||||
if not self.check: return
|
||||
env[self.name] = self.check(self.name, env.get(self.name))
|
||||
|
||||
def doHelp(self, out):
|
||||
"""Print help for the variable.
|
||||
"""
|
||||
print >>out, "%-12s" % self.name, self.use
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ import os
|
||||
import os.path
|
||||
import sys
|
||||
from getopt import getopt
|
||||
import socket
|
||||
|
||||
from xen.xend import PrettyPrint
|
||||
from xen.xend import sxp
|
||||
from xen.xend.XendClient import server
|
||||
from xen.xend.XendClient import main as xend_client_main
|
||||
from xen.xm import create, shutdown
|
||||
|
||||
class Prog:
|
||||
@@ -65,6 +67,13 @@ class Xm:
|
||||
sys.exit(1)
|
||||
|
||||
def main(self, args):
|
||||
try:
|
||||
self.main_call(args)
|
||||
except socket.error, ex:
|
||||
print >>sys.stderr, ex
|
||||
self.err("Error connecting to xend, is xend running?")
|
||||
|
||||
def main_call(self, args):
|
||||
"""Main entry point. Dispatches to the progs.
|
||||
"""
|
||||
self.name = args[0]
|
||||
@@ -444,5 +453,21 @@ class ProgConsole(Prog):
|
||||
|
||||
xm.prog(ProgConsole)
|
||||
|
||||
class ProgCall(Prog):
|
||||
name = "call"
|
||||
info = "Call xend api functions."
|
||||
|
||||
def help (self, args):
|
||||
print "call fn argss..."
|
||||
print """
|
||||
Call a xend HTTP API function. The leading 'xend_' on the function
|
||||
can be omitted. See xen.xend.XendClient for the API functions.
|
||||
"""
|
||||
|
||||
def main(self, args):
|
||||
xend_client_main(args)
|
||||
|
||||
xm.prog(ProgCall)
|
||||
|
||||
def main(args):
|
||||
xm.main(args)
|
||||
@@ -259,7 +259,7 @@ class Opts:
|
||||
for opt in self.options:
|
||||
opt.show()
|
||||
|
||||
def load_defaults(self):
|
||||
def load_defaults(self, help=0):
|
||||
"""Load a defaults script. Assumes these options set:
|
||||
'path' search path
|
||||
'default' script name
|
||||
@@ -270,12 +270,12 @@ class Opts:
|
||||
else:
|
||||
p = self.vals.defaults
|
||||
if os.path.exists(p):
|
||||
self.load(p)
|
||||
self.load(p, help)
|
||||
break
|
||||
else:
|
||||
self.err("Cannot open defaults file %s" % self.vals.defaults)
|
||||
|
||||
def load(self, defaults, help=0):
|
||||
def load(self, defaults, help):
|
||||
"""Load a defaults file. Local variables in the file
|
||||
are used to set options with the same names.
|
||||
Variables are not used to set options that are already specified.
|
||||
@@ -290,11 +290,17 @@ class Opts:
|
||||
cmd = '\n'.join(["import sys",
|
||||
"import os",
|
||||
"import os.path",
|
||||
"import xen.util.ip",
|
||||
"from xen.xm.help import Vars",
|
||||
"from xen.util import ip",
|
||||
"xm_file = '%s'" % defaults,
|
||||
"xm_help = %d" % help ])
|
||||
"xm_help = %d" % help,
|
||||
"xm_vars = Vars(xm_file, xm_help, locals())",
|
||||
])
|
||||
exec cmd in globals, locals
|
||||
execfile(defaults, globals, locals)
|
||||
try:
|
||||
execfile(defaults, globals, locals)
|
||||
except:
|
||||
if not help: raise
|
||||
if help: return
|
||||
# Extract the values set by the script and set the corresponding
|
||||
# options, if not set on the command line.
|
||||
|
||||