[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] Add XML-RPC support to Xend
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |