[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Use XML-RPC as a transport for Xend instead of S-Expression/HTTP.
# HG changeset patch # User anthony@xxxxxxxxxxxxxxxxxxxxx # Node ID 5c9c44fc1c39dc6b08535e33b34c12d684c27d77 # Parent 2c77d26871f7463dd1ebb347cd615f18045ed8da Use XML-RPC as a transport for Xend instead of S-Expression/HTTP. This changeset introduces a new XML-RPC service that runs in Xend and the required changes to have xm use this new service by default. Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx> diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendClient.py --- a/tools/python/xen/xend/XendClient.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xend/XendClient.py Thu Mar 23 10:25:37 2006 @@ -14,403 +14,11 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #============================================================================ # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx> +# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx> #============================================================================ -"""Client API for the HTTP interface on xend. -Callable as a script - see main(). -Supports inet or unix connection to xend. +from xen.util.xmlrpclib2 import ServerProxy -This API is the 'control-plane' for xend. -The 'data-plane' is done separately. -""" -import os -import sys -import types +XML_RPC_SOCKET = "/var/run/xend-xmlrpc.sock" -import sxp -import PrettyPrint -from XendProtocol import HttpXendClientProtocol, \ - UnixXendClientProtocol, \ - XendError - -def fileof(val): - """Converter for passing configs or other 'large' data. - Handles lists, files directly. - Assumes a string is a file name and passes its contents. - """ - if isinstance(val, types.ListType): - return sxp.to_string(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) - -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) - - def xend_node(self): - return self.xendGet(self.nodeurl()) - - 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')) - - def xend_node_clear_dmesg(self): - return self.xendPost(self.nodeurl('dmesg'), - {'op' : 'clear' } ) - - def xend_node_log(self): - return self.xendGet(self.nodeurl('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 }) - - def xend_domains(self): - return self.xendGet(self.domainurl()) - - def xend_list_domains(self, detail = True): - return self.xendGet(self.domainurl(), - {'detail': detail and '1' or '0'}) - - def xend_domain_vcpuinfo(self, dom): - return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'}) - - def xend_domain_create(self, conf): - return self.xendPost(self.domainurl(), - {'op' : 'create', - 'config' : fileof(conf) }) - - def xend_domain_restore(self, filename): - return self.xendPost(self.domainurl(), - {'op' : 'restore', - 'file' : filename }) - - def xend_domain_configure(self, id, conf): - return self.xendPost(self.domainurl(id), - {'op' : 'configure', - 'config' : fileof(conf) }) - - def xend_domain(self, id): - return self.xendGet(self.domainurl(id)) - - def xend_domain_wait_for_devices(self, id): - return self.xendPost(self.domainurl(id), - {'op' : 'wait_for_devices' }) - - def xend_domain_unpause(self, id): - return self.xendPost(self.domainurl(id), - {'op' : 'unpause' }) - - def xend_domain_pause(self, id): - return self.xendPost(self.domainurl(id), - {'op' : 'pause' }) - - def xend_domain_rename(self, id, name): - return self.xendPost(self.domainurl(id), - {'op' : 'rename', - 'name' : name}) - - def xend_domain_shutdown(self, id, reason): - return self.xendPost(self.domainurl(id), - {'op' : 'shutdown', - 'reason' : reason}) - - def xend_domain_sysrq(self, id, key): - return self.xendPost(self.domainurl(id), - {'op' : 'sysrq', - 'key' : key}) - - def xend_domain_destroy(self, id): - return self.xendPost(self.domainurl(id), - {'op' : 'destroy' }) - - def xend_domain_save(self, id, filename): - return self.xendPost(self.domainurl(id), - {'op' : 'save', - 'file' : 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 }) - - def xend_domain_pincpu(self, id, vcpu, cpumap): - return self.xendPost(self.domainurl(id), - {'op' : 'pincpu', - 'vcpu' : vcpu, - 'cpumap' : 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 }) - - def xend_domain_cpu_sedf_get(self, id): - return self.xendPost(self.domainurl(id), - {'op' : 'cpu_sedf_get'}) - - 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 }) - - def xend_domain_maxmem_set(self, id, memory): - return self.xendPost(self.domainurl(id), - { 'op' : 'maxmem_set', - 'memory' : 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 - - def xend_domain_set_vcpus(self, dom, vcpus): - return self.xendPost(self.domainurl(dom), - {'op' : 'set_vcpus', - 'vcpus' : vcpus }) - - def xend_domain_devices(self, id, type): - return self.xendPost(self.domainurl(id), - {'op' : 'devices', - 'type' : 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 }) - - def xend_domain_device_destroy(self, id, type, dev): - return self.xendPost(self.domainurl(id), - {'op' : 'device_destroy', - 'type' : type, - 'dev' : 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 = ServerProxy('httpu:///var/run/xend-xmlrpc.sock') diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xend/XendDomain.py Thu Mar 23 10:25:37 2006 @@ -355,7 +355,7 @@ def domain_unpause(self, domid): """Unpause domain execution.""" try: - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) log.info("Domain %s (%d) unpaused.", dominfo.getName(), dominfo.getDomid()) return dominfo.unpause() @@ -366,7 +366,7 @@ def domain_pause(self, domid): """Pause domain execution.""" try: - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) log.info("Domain %s (%d) paused.", dominfo.getName(), dominfo.getDomid()) return dominfo.pause() @@ -377,10 +377,10 @@ def domain_destroy(self, domid): """Terminate domain immediately.""" - if domid == PRIV_DOMAIN: - raise XendError("Cannot destroy privileged domain %i" % domid) - - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) + if dominfo and dominfo.getDomid() == PRIV_DOMAIN: + raise XendError("Cannot destroy privileged domain %s" % domid) + if dominfo: val = dominfo.destroy() else: @@ -393,7 +393,7 @@ def domain_migrate(self, domid, dst, live=False, resource=0, port=0): """Start domain migration.""" - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) if dominfo.getDomid() == PRIV_DOMAIN: raise XendError("Cannot migrate privileged domain %i" % domid) @@ -418,7 +418,7 @@ """ try: - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) if dominfo.getDomid() == PRIV_DOMAIN: raise XendError("Cannot save privileged domain %i" % domid) @@ -438,7 +438,7 @@ @param cpumap: string repr of list of usable cpus """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) # convert cpumap string into a list of ints cpumap = map(lambda x: int(x), cpumap.replace("[", "").replace("]", "").split(",")) @@ -451,7 +451,7 @@ warpu): """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain. """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) try: return xc.bvtsched_domain_set(dom=dominfo.getDomid(), mcuadv=mcuadv, @@ -464,7 +464,7 @@ def domain_cpu_bvt_get(self, domid): """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain. """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) try: return xc.bvtsched_domain_get(dominfo.getDomid()) except Exception, ex: @@ -475,7 +475,7 @@ weight): """Set Simple EDF scheduler parameters for a domain. """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) try: return xc.sedf_domain_set(dominfo.getDomid(), period, slice_, latency, extratime, weight) @@ -485,7 +485,7 @@ def domain_cpu_sedf_get(self, domid): """Get Simple EDF scheduler parameters for a domain. """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) try: sedf_info = xc.sedf_domain_get(dominfo.getDomid()) @@ -507,7 +507,7 @@ @param mem: memory limit (in MiB) @return: 0 on success, -1 on error """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) maxmem = int(mem) * 1024 try: return xc.domain_setmaxmem(dominfo.getDomid(), maxmem) @@ -521,7 +521,7 @@ @param last: last IO port @return: 0 on success, -1 on error """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) nr_ports = last - first + 1 try: return xc.domain_ioport_permission(dominfo.getDomid(), @@ -538,7 +538,7 @@ @param last: last IO port @return: 0 on success, -1 on error """ - dominfo = self.domain_lookup(domid) + dominfo = self.domain_lookup_by_name_or_id_nr(domid) nr_ports = last - first + 1 try: return xc.domain_ioport_permission(dominfo.getDomid(), diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendError.py --- a/tools/python/xen/xend/XendError.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xend/XendError.py Thu Mar 23 10:25:37 2006 @@ -15,9 +15,12 @@ # Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx> #============================================================================ -class XendError(ValueError): +from xmlrpclib import Fault + +class XendError(Fault): def __init__(self, value): + Fault.__init__(self, 2, value) self.value = value def __str__(self): diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/XendRoot.py --- a/tools/python/xen/xend/XendRoot.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xend/XendRoot.py Thu Mar 23 10:25:37 2006 @@ -59,6 +59,10 @@ """Default for the flag indicating whether xend should run an http server.""" xend_http_server_default = 'no' + + xend_tcp_xmlrpc_server_default = 'no' + + xend_unix_xmlrpc_server_default = 'yes' """Default interface address xend listens at. """ xend_address_default = '' @@ -180,6 +184,12 @@ """ return self.get_config_bool("xend-http-server", self.xend_http_server_default) + def get_xend_tcp_xmlrpc_server(self): + return self.get_config_bool("xend-tcp-xmlrpc-server", self.xend_tcp_xmlrpc_server_default) + + def get_xend_unix_xmlrpc_server(self): + return self.get_config_bool("xend-unix-xmlrpc-server", self.xend_unix_xmlrpc_server_default) + def get_xend_relocation_server(self): """Get the flag indicating whether xend should run a relocation server. """ diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xend/server/SrvServer.py Thu Mar 23 10:25:37 2006 @@ -52,6 +52,7 @@ from xen.web.SrvDir import SrvDir from SrvRoot import SrvRoot +from XMLRPCServer import XMLRPCServer xroot = XendRoot.instance() @@ -114,4 +115,10 @@ path = xroot.get_xend_unix_path() log.info('unix path=' + path) servers.add(UnixHttpServer(root, path)) + + if xroot.get_xend_tcp_xmlrpc_server(): + servers.add(XMLRPCServer(True)) + + if xroot.get_xend_unix_xmlrpc_server(): + servers.add(XMLRPCServer()) return servers diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xm/create.py Thu Mar 23 10:25:37 2006 @@ -30,7 +30,7 @@ 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 @@ -813,8 +813,8 @@ """ try: - dominfo = server.xend_domain_create(config) - except XendError, ex: + dominfo = server.xend.domain.create(config) + except Exception, ex: import signal if vncpid: os.kill(vncpid, signal.SIGKILL) @@ -822,13 +822,17 @@ dom = sxp.child_value(dominfo, 'name') - if server.xend_domain_wait_for_devices(dom) < 0: - server.xend_domain_destroy(dom) + try: + server.xend.domain.waitForDevices(dom) + except: + server.xend.domain.destroy(dom) err("Device creation failed for domain %s" % dom) if not opts.vals.paused: - if server.xend_domain_unpause(dom) < 0: - server.xend_domain_destroy(dom) + try: + server.xend.domain.unpause(dom) + except: + server.xend.domain.destroy(dom) err("Failed to unpause domain %s" % dom) opts.info("Started domain %s" % (dom)) return int(sxp.child_value(dominfo, 'domid')) diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xm/main.py Thu Mar 23 10:25:37 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 @@ -39,6 +39,7 @@ import console +from xen.xend.XendClient import server # getopt.gnu_getopt is better, but only exists in Python 2.3+. Use # getopt.getopt if gnu_getopt is not available. This will mean that options @@ -319,8 +320,7 @@ err("xm save: Unable to create file %s" % savefile) sys.exit(1) - from xen.xend.XendClient import server - server.xend_domain_save(dom, savefile) + server.xend.domain.save(dom, savefile) def xm_restore(args): arg_check(args, "restore", 1) @@ -331,16 +331,14 @@ err("xm restore: Unable to read file %s" % savefile) sys.exit(1) - from xen.xend.XendClient import server - server.xend_domain_restore(savefile) + server.xend.domain.restore(savefile) def getDomains(domain_names): - from xen.xend.XendClient import server if domain_names: - return map(server.xend_domain, domain_names) - else: - return server.xend_list_domains() + return map(server.xend.domain, domain_names) + else: + return server.xend.domains(1) def xm_list(args): @@ -416,12 +414,11 @@ def xm_vcpu_list(args): - from xen.xend.XendClient import server if args: - dominfo = map(server.xend_domain_vcpuinfo, args) - else: - doms = server.xend_list_domains(False) - dominfo = map(server.xend_domain_vcpuinfo, doms) + dominfo = map(server.xend.domain.getVCPUInfo, args) + else: + doms = server.xend.domains(False) + dominfo = map(server.xend.domain.getVCPUInfo, doms) print 'Name ID VCPU CPU State Time(s) CPU Affinity' @@ -475,8 +472,7 @@ cpumap = map(lambda x: int(x), cpumap) cpumap.sort() - from xen.xend.XendClient import server - for x in server.xend_node()[1:]: + for x in server.xend.node.info()[1:]: if len(x) > 1 and x[0] == 'nr_cpus': nr_cpus = int(x[1]) # normalize cpumap by modulus nr_cpus, and drop duplicates @@ -532,21 +528,18 @@ arg_check(args, "pause", 1) dom = args[0] - from xen.xend.XendClient import server - server.xend_domain_pause(dom) + server.xend.domain.pause(dom) def xm_unpause(args): arg_check(args, "unpause", 1) dom = args[0] - from xen.xend.XendClient import server - server.xend_domain_unpause(dom) + server.xend.domain.unpause(dom) def xm_rename(args): arg_check(args, "rename", 2) - from xen.xend.XendClient import server - server.xend_domain_rename(args[0], args[1]) + server.xend.domain.setName(args[0], args[1]) def xm_subcommand(command, args): cmd = __import__(command, globals(), locals(), 'xen.xm') @@ -574,8 +567,7 @@ vcpu = int(args[1]) cpumap = cpu_make_map(args[2]) - from xen.xend.XendClient import server - server.xend_domain_pincpu(dom, vcpu, cpumap) + server.xend.domain.pincpu(dom, vcpu, cpumap) def xm_mem_max(args): arg_check(args, "mem-max", 2) @@ -583,8 +575,7 @@ dom = args[0] mem = int_unit(args[1], 'm') - from xen.xend.XendClient import server - server.xend_domain_maxmem_set(dom, mem) + server.xend.domain.maxmem_set(dom, mem) def xm_mem_set(args): arg_check(args, "mem-set", 2) @@ -592,20 +583,17 @@ dom = args[0] mem_target = int_unit(args[1], 'm') - from xen.xend.XendClient import server - server.xend_domain_mem_target_set(dom, mem_target) + server.xend.domain.setMemoryTarget(dom, mem_target) def xm_vcpu_set(args): arg_check(args, "vcpu-set", 2) - from xen.xend.XendClient import server - server.xend_domain_set_vcpus(args[0], int(args[1])) + server.xend.domain.setVCpuCount(args[0], int(args[1])) def xm_destroy(args): arg_check(args, "destroy", 1) - from xen.xend.XendClient import server - server.xend_domain_destroy(args[0]) + server.xend.domain.destroy(args[0]) def xm_domid(args): @@ -613,8 +601,7 @@ name = args[0] - from xen.xend.XendClient import server - dom = server.xend_domain(name) + dom = server.xend.domain(name) print sxp.child_value(dom, 'domid') def xm_domname(args): @@ -622,23 +609,20 @@ name = args[0] - from xen.xend.XendClient import server - dom = server.xend_domain(name) + dom = server.xend.domain(name) print sxp.child_value(dom, 'name') def xm_sched_bvt(args): arg_check(args, "sched-bvt", 6) dom = args[0] v = map(long, args[1:6]) - from xen.xend.XendClient import server - server.xend_domain_cpu_bvt_set(dom, *v) + server.xend.domain.cpu_bvt_set(dom, *v) def xm_sched_bvt_ctxallow(args): arg_check(args, "sched-bvt-ctxallow", 1) slice = int(args[0]) - from xen.xend.XendClient import server - server.xend_node_cpu_bvt_slice_set(slice) + server.xend.node.cpu_bvt_slice_set(slice) def xm_sched_sedf(args): def ns_to_ms(val): @@ -695,13 +679,12 @@ 'Slice(ms)', 'Lat(ms)', 'Extra','Weight') - from xen.xend.XendClient import server doms = filter(lambda x : domid_match(domid, x), [parse_doms_info(dom) for dom in getDomains("")]) for d in doms: # fetch current values so as not to clobber them sedf_info = \ - parse_sedf_info(server.xend_domain_cpu_sedf_get(d['dom'])) + parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom'])) sedf_info['name'] = d['name'] # update values in case of call to set @@ -713,7 +696,7 @@ v = map(int, [sedf_info['period'], sedf_info['slice'], sedf_info['latency'],sedf_info['extratime'], sedf_info['weight']]) - rv = server.xend_domain_cpu_sedf_set(d['dom'], *v) + rv = server.xend.domain.cpu_sedf_set(d['dom'], *v) if int(rv) != 0: err("Failed to set sedf parameters (rv=%d)."%(rv)) @@ -725,8 +708,7 @@ def xm_info(args): arg_check(args, "info", 0) - from xen.xend.XendClient import server - info = server.xend_node() + info = server.xend.node.info() for x in info[1:]: if len(x) < 2: @@ -738,8 +720,7 @@ arg_check(args, "console", 1) dom = args[0] - from xen.xend.XendClient import server - info = server.xend_domain(dom) + info = server.xend.domain(dom) domid = int(sxp.child_value(info, 'domid', '-1')) console.execConsole(domid) @@ -768,17 +749,15 @@ if not (1 <= len(myargs) <= 2): err('Invalid arguments: ' + str(myargs)) - from xen.xend.XendClient import server if not gopts.vals.clear: - print server.xend_node_get_dmesg() - else: - server.xend_node_clear_dmesg() + print server.xend.node.dmesg.info() + else: + server.xend.node.dmesg.clear() def xm_log(args): arg_check(args, "log", 0) - from xen.xend.XendClient import server - print server.xend_node_log() + print server.xend.node.log() def parse_dev_info(info): def get_info(n, t, d): @@ -826,13 +805,12 @@ print 'No domain parameter given' sys.exit(1) dom = params[0] - from xen.xend.XendClient import server if use_long: - devs = server.xend_domain_devices(dom, 'vif') + devs = server.xend.domain.getDeviceSxprs(dom, 'vif') map(PrettyPrint.prettyprint, devs) else: hdr = 0 - for x in server.xend_domain_devices(dom, 'vif'): + for x in server.xend.domain.getDeviceSxprs(dom, 'vif'): if hdr == 0: print 'Idx BE MAC Addr. handle state evt-ch tx-/rx-ring-ref BE-path' hdr = 1 @@ -857,13 +835,12 @@ print 'No domain parameter given' sys.exit(1) dom = params[0] - from xen.xend.XendClient import server if use_long: - devs = server.xend_domain_devices(dom, 'vbd') + devs = server.xend.domain.getDeviceSxprs(dom, 'vbd') map(PrettyPrint.prettyprint, devs) else: hdr = 0 - for x in server.xend_domain_devices(dom, 'vbd'): + for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'): if hdr == 0: print 'Vdev BE handle state evt-ch ring-ref BE-path' hdr = 1 @@ -887,13 +864,12 @@ print 'No domain parameter given' sys.exit(1) dom = params[0] - from xen.xend.XendClient import server if use_long: - devs = server.xend_domain_devices(dom, 'vtpm') + devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm') map(PrettyPrint.prettyprint, devs) else: hdr = 0 - for x in server.xend_domain_devices(dom, 'vtpm'): + for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'): if hdr == 0: print 'Idx BE handle state evt-ch ring-ref BE-path' hdr = 1 @@ -919,8 +895,7 @@ if len(args) == 5: vbd.append(['backend', args[4]]) - from xen.xend.XendClient import server - server.xend_domain_device_create(dom, vbd) + server.xend.domain.device_create(dom, vbd) def xm_network_attach(args): @@ -932,8 +907,7 @@ for a in args[1:]: vif.append(a.split("=")) - from xen.xend.XendClient import server - server.xend_domain_device_create(dom, vif) + server.xend.domain.device_create(dom, vif) def detach(args, command, deviceClass): @@ -942,8 +916,7 @@ dom = args[0] dev = args[1] - from xen.xend.XendClient import server - server.xend_domain_device_destroy(dom, deviceClass, dev) + server.xend.domain.destroyDevice(dom, deviceClass, dev) def xm_block_detach(args): @@ -955,7 +928,6 @@ def xm_vnet_list(args): - from xen.xend.XendClient import server try: (options, params) = getopt.gnu_getopt(args, 'l', ['long']) except getopt.GetoptError, opterr: @@ -990,13 +962,11 @@ print "File not found: %s" % conf sys.exit(1) - from xen.xend.XendClient import server server.xend_vnet_create(conf) def xm_vnet_delete(args): arg_check(args, "vnet-delete", 1) vnet = args[0] - from xen.xend.XendClient import server server.xend_vnet_delete(vnet) commands = { @@ -1132,23 +1102,10 @@ 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: %s" % ex.faultString sys.exit(1) except: print "Unexpected error:", sys.exc_info()[0] diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/migrate.py --- a/tools/python/xen/xm/migrate.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xm/migrate.py Thu Mar 23 10:25:37 2006 @@ -60,4 +60,4 @@ opts.err('Invalid arguments: ' + str(args)) dom = args[0] dst = args[1] - server.xend_domain_migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port) + server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port) diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/shutdown.py --- a/tools/python/xen/xm/shutdown.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xm/shutdown.py Thu Mar 23 10:25:37 2006 @@ -53,8 +53,8 @@ use='Shutdown and reboot.') def shutdown(opts, doms, mode, wait): - if doms == None: doms = server.xend_domains() - dom0_name = sxp.child_value(server.xend_domain(0), 'name') + if doms == None: doms = server.xend.domains(0) + dom0_name = sxp.child_value(server.xend.domain(0), 'name') for x in [dom0_name, DOM0_ID]: if x in doms: if opts.vals.all: @@ -62,10 +62,10 @@ else: opts.err("Can't specify Domain-0") for d in doms: - server.xend_domain_shutdown(d, mode) + server.xend.domain.shutdown(d, mode) if wait: while doms: - alive = server.xend_domains() + alive = server.xend.domains(0) dead = [] for d in doms: if d in alive: continue diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xm/sysrq.py --- a/tools/python/xen/xm/sysrq.py Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xm/sysrq.py Thu Mar 23 10:25:37 2006 @@ -28,4 +28,4 @@ if len(args) < 2: opts.err('Missing sysrq character') dom = args[0] req = ord(args[1][0]) - server.xend_domain_sysrq(dom, req) + server.xend.domain.sysrq(dom, req) diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/util/xmlrpclib2.py --- /dev/null Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/util/xmlrpclib2.py Thu Mar 23 10:25:37 2006 @@ -0,0 +1,109 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx> +#============================================================================ + +""" +An enhanced XML-RPC client/server interface for Python. +""" + +from httplib import HTTPConnection, HTTP +from xmlrpclib import Transport +from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler +import xmlrpclib, socket, os, traceback + +# A new ServerProxy that also supports httpu urls. An http URL comes in the +# form: +# +# httpu:///absolute/path/to/socket.sock +# +# It assumes that the RPC handler is /RPC2. This probably needs to be improved + +class HTTPUnixConnection(HTTPConnection): + def connect(self): + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.sock.connect(self.host) + +class HTTPUnix(HTTP): + _connection_class = HTTPUnixConnection + +class UnixTransport(Transport): + def request(self, host, handler, request_body, verbose=0): + self.__handler = handler + return Transport.request(self, host, '/RPC2', request_body, verbose) + def make_connection(self, host): + return HTTPUnix(self.__handler) + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, transport=None, encoding=None, verbose=0, + allow_none=1): + if transport == None: + (protocol, rest) = uri.split(':', 1) + if protocol == 'httpu': + uri = 'http:' + rest + transport = UnixTransport() + xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding, + verbose, allow_none) + +# This is a base XML-RPC server for TCP. It sets allow_reuse_address to +# true, and has an improved marshaller that serializes unknown exceptions +# with full traceback information. + +class TCPXMLRPCServer(SimpleXMLRPCServer): + allow_reuse_address = True + + def _marshaled_dispatch(self, data, dispatch_method = None): + params, method = xmlrpclib.loads(data) + try: + if dispatch_method is not None: + response = dispatch_method(method, params) + else: + response = self._dispatch(method, params) + + response = (response,) + response = xmlrpclib.dumps(response, + methodresponse=1, + allow_none=1) + except xmlrpclib.Fault, fault: + response = xmlrpclib.dumps(fault) + except: + response = xmlrpclib.dumps( + xmlrpclib.Fault(1, traceback.format_exc()) + ) + + return response + +# This is a XML-RPC server that sits on a Unix domain socket. +# It implements proper support for allow_reuse_address by +# unlink()'ing an existing socket. + +class UnixXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): + def address_string(self): + try: + return SimpleXMLRPCRequestHandler.address_string(self) + except ValueError, e: + return self.client_address[:2] + +class UnixXMLRPCServer(TCPXMLRPCServer): + address_family = socket.AF_UNIX + + def __init__(self, addr, requestHandler=UnixXMLRPCRequestHandler, + logRequests=1): + if self.allow_reuse_address: + try: + os.unlink(addr) + except OSError, exc: + pass + TCPXMLRPCServer.__init__(self, addr, requestHandler, logRequests) diff -r 2c77d26871f7 -r 5c9c44fc1c39 tools/python/xen/xend/server/XMLRPCServer.py --- /dev/null Thu Mar 23 09:58:39 2006 +++ b/tools/python/xen/xend/server/XMLRPCServer.py Thu Mar 23 10:25:37 2006 @@ -0,0 +1,106 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx> +#============================================================================ + +from xen.xend import XendDomain, XendDomainInfo, XendNode, \ + XendLogging, XendDmesg +from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer + +from xen.xend.XendClient import XML_RPC_SOCKET + +def lookup(domid): + return XendDomain.instance().domain_lookup_by_name_or_id(domid) + +def dispatch(domid, fn, args): + info = lookup(domid) + return getattr(info, fn)(*args) + +def domain(domid): + info = lookup(domid) + return info.sxpr() + +def domains(detail=1): + if detail < 1: + return XendDomain.instance().list_names() + else: + domains = XendDomain.instance().list_sorted() + return map(lambda dom: dom.sxpr(), domains) + +def domain_create(config): + info = XendDomain.instance().domain_create(config) + return info.sxpr() + +def domain_restore(src): + info = XendDomain.instance().domain_restore(src) + return info.sxpr() + +def get_log(): + f = open(XendLogging.getLogFilename(), 'r') + try: + return f.read() + finally: + f.close() + +methods = ['device_create', 'destroyDevice', 'getDeviceSxprs', + 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown', + 'send_sysrq', 'getVCPUInfo', 'waitForDevices'] + +exclude = ['domain_create', 'domain_restore'] + +class XMLRPCServer: + def __init__(self, use_tcp=False): + self.ready = False + self.use_tcp = use_tcp + + def run(self): + if self.use_tcp: + # bind to something fixed for now as we may eliminate + # tcp support completely. + self.server = TCPXMLRPCServer(("localhost", 8005)) + else: + self.server = UnixXMLRPCServer(XML_RPC_SOCKET) + + # Functions in XendDomainInfo + for name in methods: + fn = eval("lambda domid, *args: dispatch(domid, '%s', args)"%name) + self.server.register_function(fn, "xend.domain.%s" % name) + + # Functions in XendDomain + inst = XendDomain.instance() + for name in dir(inst): + fn = getattr(inst, name) + if name.startswith("domain_") and callable(fn): + if name not in exclude: + self.server.register_function(fn, "xend.domain.%s" % name[7:]) + + # Functions in XendNode and XendDmesg + for type, lst, n in [(XendNode, ['info', 'cpu_bvt_slice_set'], 'node'), + (XendDmesg, ['info', 'clear'], 'node.dmesg')]: + inst = type.instance() + for name in lst: + self.server.register_function(getattr(inst, name), + "xend.%s.%s" % (n, name)) + + # A few special cases + self.server.register_function(domain, 'xend.domain') + self.server.register_function(domains, 'xend.domains') + self.server.register_function(get_log, 'xend.node.log') + self.server.register_function(domain_create, 'xend.domain.create') + self.server.register_function(domain_restore, 'xend.domain.restore') + + self.server.register_introspection_functions() + self.ready = True + self.server.serve_forever() _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |