There's no 3/3, sorry, I can't count apparently :-)
# HG changeset patch
# User anthony@xxxxxxxxxxxxxxxxxxxxx
# Node ID 951f0d589164e0cffc785cf23d82118b3e0b0495
# Parent 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac
This changeset is a major refactoring of XendClient to use the XML-RPC
transport for Xend and also to make a few changes to xm so that it knows about
the new Exception types.
xm-test has been passing with this changeset for the past couple of weeks.
Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xend/XendClient.py Tue Feb 28 22:10:14 2006
@@ -16,22 +16,8 @@
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx>
#============================================================================
-"""Client API for the HTTP interface on xend.
-Callable as a script - see main().
-Supports inet or unix connection to xend.
-
-This API is the 'control-plane' for xend.
-The 'data-plane' is done separately.
-"""
-import os
-import sys
-import types
-
-import sxp
-import PrettyPrint
-from XendProtocol import HttpXendClientProtocol, \
- UnixXendClientProtocol, \
- XendError
+import types, sxp
+from xen.util.xmlrpclib2 import ServerProxy
def fileof(val):
"""Converter for passing configs or other 'large' data.
@@ -39,377 +25,120 @@
Assumes a string is a file name and passes its contents.
"""
if isinstance(val, types.ListType):
- return sxp.to_string(val)
+ return val
if isinstance(val, types.StringType):
- return file(val)
- if hasattr(val, 'readlines'):
- return val
- raise XendError('cannot convert value')
-
-class URL:
- """A URL.
- """
-
- def __init__(self, proto='http', host='localhost', port=None, path='',
query=None, frag=None):
- self.proto = proto
- self.host = host
- if port: port = int(port)
- self.port = port
- self.path = path
- self.query = query
- self.frag = frag
-
- def url(self):
- """Get the full URL string including protocol, location and the full
path.
- """
- return self.proto + '://' + self.location() + self.fullpath()
-
- def location(self):
- """Get the location part of the URL, including host and port, if
present.
- """
- if self.port:
- return self.host + ':' + str(self.port)
- else:
- return self.host
-
- def fullpath(self):
- """Get the full path part of the URL, including query and fragment if
present.
- """
- u = [ self.path ]
- if self.query:
- u.append('?')
- u.append(self.query)
- if self.frag:
- u.append('#')
- u.append(self.frag)
- return ''.join(u)
-
- def relative(self, path='', query=None, frag=None):
- """Create a URL relative to this one.
- """
- return URL(proto=self.proto,
- host=self.host,
- port=self.port,
- path=self.path + path,
- query=query,
- frag=frag)
+ return sxp.from_string(val)
+ raise ValueError('invalid value for config')
class Xend:
"""Client interface to Xend.
"""
- """Default location of the xend server."""
- SRV_DEFAULT = "localhost:8000"
-
- """Environment variable to set the location of xend."""
- SRV_VAR = "XEND"
-
- """Default path to the xend root on the server."""
- ROOT_DEFAULT = "/xend/"
-
- """Environment variable to set the xend root path."""
- ROOT_VAR = "XEND_ROOT"
-
def __init__(self, client=None, srv=None, root=None):
- """Create a xend client interface.
- If the client protocol is not specified, the default
- is to use a synchronous protocol.
-
- @param client: client protocol to use
- @param srv: server host, and optional port (format host:port)
- @param root: xend root path on the server
- """
- if client is None:
- client = HttpXendClientProtocol()
- self.client = client
- self.bind(srv, root)
-
- def default_server(self):
- """Get the default location of the xend server.
- """
- return os.getenv(self.SRV_VAR, self.SRV_DEFAULT)
-
- def default_root(self):
- """Get the default root path on the xend server.
- """
- return os.getenv(self.ROOT_VAR, self.ROOT_DEFAULT)
-
- def bind(self, srv=None, root=None):
- """Bind to a given server.
-
- @param srv: server location (host:port)
- @param root: xend root path on the server
- """
- if srv is None: srv = self.default_server()
- if root is None: root = self.default_root()
- if not root.endswith('/'): root += '/'
- (host, port) = srv.split(':', 1)
- self.url = URL(host=host, port=port, path=root)
-
- def xendGet(self, url, args=None):
- return self.client.xendGet(url, args)
-
- def xendPost(self, url, data):
- return self.client.xendPost(url, data)
-
- def nodeurl(self, id=''):
- return self.url.relative('node/' + str(id))
-
- def domainurl(self, id=''):
- return self.url.relative('domain/' + str(id))
-
- def deviceurl(self, id=''):
- return self.url.relative('device/' + str(id))
-
- def vneturl(self, id=''):
- return self.url.relative('vnet/' + str(id))
-
- def xend(self):
- return self.xendGet(self.url)
+ self.srv = ServerProxy('httpu:///var/run/xend-xmlrpc.sock')
def xend_node(self):
- return self.xendGet(self.nodeurl())
+ return self.srv.xend.node.info()
- def xend_node_shutdown(self):
- return self.xendPost(self.nodeurl(),
- {'op' : 'shutdown'})
-
- def xend_node_restart(self):
- return self.xendPost(self.nodeurl(),
- {'op' : 'reboot'})
-
def xend_node_get_dmesg(self):
- return self.xendGet(self.nodeurl('dmesg'))
+ return self.srv.xend.node.dmesg.info()
def xend_node_clear_dmesg(self):
- return self.xendPost(self.nodeurl('dmesg'),
- {'op' : 'clear' } )
+ return self.srv.xend.node.dmesg.clear()
def xend_node_log(self):
- return self.xendGet(self.nodeurl('log'))
+ return self.srv.xend.node.log()
def xend_node_cpu_bvt_slice_set(self, ctx_allow):
- return self.xendPost(self.nodeurl(),
- {'op' : 'cpu_bvt_slice_set',
- 'ctx_allow' : ctx_allow })
+ return self.srv.xend.node.cpu_bvt_slice_set(ctx_allow)
def xend_domains(self):
- return self.xendGet(self.domainurl())
+ return self.srv.xend.domains(0)
def xend_list_domains(self):
- return self.xendGet(self.domainurl(), {'detail': '1'})
+ return self.srv.xend.domains(1)
def xend_domain_vcpuinfo(self, dom):
- return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'})
+ return self.srv.xend.domain.getVCPUInfo(dom)
def xend_domain_create(self, conf):
- return self.xendPost(self.domainurl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
+ return self.srv.xend.domain.create(fileof(conf))
+ # FIXME
def xend_domain_restore(self, filename):
- return self.xendPost(self.domainurl(),
- {'op' : 'restore',
- 'file' : filename })
+ return self.srv.xend.domain.restore(filename)
def xend_domain_configure(self, id, conf):
- return self.xendPost(self.domainurl(id),
- {'op' : 'configure',
- 'config' : fileof(conf) })
+ return self.srv.xend.domain.configure(id, fileof(conf))
def xend_domain(self, id):
- return self.xendGet(self.domainurl(id))
+ return self.srv.xend.domain(id)
def xend_domain_wait_for_devices(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'wait_for_devices' })
+ try:
+ self.srv.xend.domain.waitForDevices(id)
+ return 0
+ except:
+ return -1
+
+ def lookup(self, id):
+ info = self.srv.xend.domain(id)
+ return int(sxp.child_value(info, 'domid'))
def xend_domain_unpause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'unpause' })
+ self.srv.xend.domain.unpause(self.lookup(id))
+ return 0
def xend_domain_pause(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pause' })
+ self.srv.xend.domain.pause(self.lookup(id))
+ return 0
def xend_domain_rename(self, id, name):
- return self.xendPost(self.domainurl(id),
- {'op' : 'rename',
- 'name' : name})
+ return self.srv.xend.domain.setName(id, name)
def xend_domain_shutdown(self, id, reason):
- return self.xendPost(self.domainurl(id),
- {'op' : 'shutdown',
- 'reason' : reason})
+ return self.srv.xend.domain.shutdown(id, reason)
def xend_domain_sysrq(self, id, key):
- return self.xendPost(self.domainurl(id),
- {'op' : 'sysrq',
- 'key' : key})
+ return self.srv.xend.domain.send_sysrq(self.lookup(id), key)
def xend_domain_destroy(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'destroy' })
+ return self.srv.xend.domain.destroy(self.lookup(id))
def xend_domain_save(self, id, filename):
- return self.xendPost(self.domainurl(id),
- {'op' : 'save',
- 'file' : filename })
+ return self.srv.xend.domain.save(self.lookup(id), filename)
def xend_domain_migrate(self, id, dst, live=0, resource=0, port=0):
- return self.xendPost(self.domainurl(id),
- {'op' : 'migrate',
- 'destination': dst,
- 'live' : live,
- 'resource' : resource,
- 'port' : port })
+ return self.srv.xend.domain.migrate(self.lookup(id), dst, live,
resource, port)
def xend_domain_pincpu(self, id, vcpu, cpumap):
- return self.xendPost(self.domainurl(id),
- {'op' : 'pincpu',
- 'vcpu' : vcpu,
- 'cpumap' : str(cpumap) })
+ return self.srv.xend.domain.pincpu(self.lookup(id), vcpu, str(cpumap))
def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl,
warpu):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_bvt_set',
- 'mcuadv' : mcuadv,
- 'warpback' : warpback,
- 'warpvalue': warpvalue,
- 'warpl' : warpl,
- 'warpu' : warpu })
+ return self.srv.xend.domain.cpu_bvt_set(mcuadv, warpback, warpvalue,
warpl, warpu)
def xend_domain_cpu_sedf_get(self, id):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_get'})
+ return self.srv.xend.domain.cpu_sedf_get(self.lookup(id))
def xend_domain_cpu_sedf_set(self, id, period, slice, latency, extratime,
weight):
- return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_sedf_set',
- 'period' : period,
- 'slice' : slice,
- 'latency' : latency,
- 'extratime' : extratime,
- 'weight' : weight })
+ return self.srv.xend.domain.cpu_sedf_set(self.lookup(id), period,
slice, latency, extratime, weight)
def xend_domain_maxmem_set(self, id, memory):
- return self.xendPost(self.domainurl(id),
- { 'op' : 'maxmem_set',
- 'memory' : memory })
+ return self.srv.xend.domain.maxmem_set(self.lookup(id), memory)
def xend_domain_mem_target_set(self, id, mem_target):
- val = self.xendPost(self.domainurl(id),
- {'op' : 'mem_target_set',
- 'target' : mem_target })
- return val
+ return self.srv.xend.domain.setMemoryTarget(id, mem_target)
def xend_domain_set_vcpus(self, dom, vcpus):
- return self.xendPost(self.domainurl(dom),
- {'op' : 'set_vcpus',
- 'vcpus' : vcpus })
+ return self.srv.xend.domain.setVCpuCount(self.lookup(dom), vcpus)
def xend_domain_devices(self, id, type):
- return self.xendPost(self.domainurl(id),
- {'op' : 'devices',
- 'type' : type })
+ return self.srv.xend.domain.getDeviceSxprs(id, type)
def xend_domain_device_create(self, id, config):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_create',
- 'config' : fileof(config) })
-
- def xend_domain_device_refresh(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_refresh',
- 'type' : type,
- 'dev' : dev })
+ return self.srv.xend.domain.device_create(id, fileof(config))
def xend_domain_device_destroy(self, id, type, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_destroy',
- 'type' : type,
- 'dev' : dev })
+ return self.srv.xend.domain.destroyDevice(id, type, dev)
- def xend_domain_device_configure(self, id, config, dev):
- return self.xendPost(self.domainurl(id),
- {'op' : 'device_configure',
- 'dev' : dev,
- 'config' : fileof(config) })
-
- def xend_vnets(self):
- return self.xendGet(self.vneturl())
-
- def xend_vnet_create(self, conf):
- return self.xendPost(self.vneturl(),
- {'op' : 'create',
- 'config' : fileof(conf) })
-
- def xend_vnet(self, id):
- return self.xendGet(self.vneturl(id))
-
- def xend_vnet_delete(self, id):
- return self.xendPost(self.vneturl(id),
- {'op' : 'delete' })
-
-def getHttpServer(srv=None):
- """Create and return a xend client.
- """
- return Xend(srv=srv, client=HttpXendClientProtocol())
-
-def getUnixServer(srv=None):
- """Create and return a unix-domain xend client.
- """
- return Xend(client=UnixXendClientProtocol(srv))
-
-def xendmain(srv, fn, args, unix=False):
- if unix:
- xend = getUnixServer(srv)
- else:
- xend = getHttpServer(srv)
- xend.rc = 0
- try:
- v = getattr(xend, fn)(*args)
- PrettyPrint.prettyprint(v)
- return 0
- except XendError, err:
- print 'ERROR:', err
- return 1
-
-def main(argv):
- """Call an API function:
-
- python XendClient.py fn args...
-
- The leading 'xend_' on the function can be omitted.
- Example:
-
-python XendClient.py domains
- (0 8)
-python XendClient.py domain 0
- (domain (id 0) (name Domain-0) (memory 128))
- """
- from getopt import getopt
- short_options = 'x:au:d'
- long_options = ['xend=', 'unix=', 'debug']
- (options, args) = getopt(argv[1:], short_options, long_options)
- srv = None
- unix = 1
- for k, v in options:
- if k in ['-x', '--xend']:
- srv = v
- elif k in ['-u', '--unix']:
- unix = int(v)
- if len(args):
- fn = args[0]
- args = args[1:]
- else:
- fn = 'xend'
- args = []
- if not fn.startswith('xend'):
- fn = 'xend_' + fn
- sys.exit(xendmain(srv, fn, args, unix=unix))
-
-if __name__ == "__main__":
- main(sys.argv)
-else:
- server = getUnixServer()
+server = Xend()
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xend/XendDomain.py Tue Feb 28 22:10:14 2006
@@ -385,7 +385,7 @@
val = dominfo.destroy()
else:
try:
- val = xc.domain_destroy(domid)
+ val = xc.domain_destroy(int(domid))
except Exception, ex:
raise XendError(str(ex))
return val
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xm/create.py Tue Feb 28 22:10:14 2006
@@ -28,11 +28,9 @@
import time
import re
-import xen.lowlevel.xc
-
from xen.xend import sxp
from xen.xend import PrettyPrint
-from xen.xend.XendClient import server, XendError
+from xen.xend.XendClient import server
from xen.xend.XendBootloader import bootloader
from xen.util import blkif
@@ -416,6 +414,8 @@
def err(msg):
"""Print an error to stderr and exit.
"""
+ import traceback
+ traceback.print_exc()
print >>sys.stderr, "Error:", msg
sys.exit(1)
@@ -810,7 +810,7 @@
dominfo = server.xend_domain_restore(filename, config)
else:
dominfo = server.xend_domain_create(config)
- except XendError, ex:
+ except Exception, ex:
import signal
if vncpid:
os.kill(vncpid, signal.SIGKILL)
diff -r 095ac0d95d9c -r 951f0d589164 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Tue Feb 28 22:08:47 2006
+++ b/tools/python/xen/xm/main.py Tue Feb 28 22:10:14 2006
@@ -29,8 +29,8 @@
import socket
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
-
-import xen.xend.XendError
+import xmlrpclib
+
import xen.xend.XendProtocol
from xen.xend import PrettyPrint
@@ -1036,23 +1036,13 @@
else:
err("Error connecting to xend: %s." % ex[1])
sys.exit(1)
- except xen.xend.XendError.XendError, ex:
- if len(args) > 0:
- handle_xend_error(argv[1], args, ex)
- else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
- raise
- except xen.xend.XendProtocol.XendError, ex:
- if len(args) > 0:
- handle_xend_error(argv[1], args, ex)
- else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
- raise
except SystemExit:
+ sys.exit(1)
+ except xmlrpclib.Fault, ex:
+# print "Xend generated an internal fault:"
+# sys.stderr.write(ex.faultString)
+# sys.exit(1)
+ print "Error: Internal Xend error"
sys.exit(1)
except:
print "Unexpected error:", sys.exc_info()[0]
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|