[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/3] Add XML-RPC support to Xend
# HG changeset patch # User anthony@xxxxxxxxxxxxxxxxxxxxx # Node ID 095ac0d95d9cc154ec8fc3dba1a67f02f79771ac # Parent c369d960f96ba4fd7c9c6920cfa60c46a764323c Add an XML-RPC interface to Xend. This introduces a enhanced client library (xmlrpclib2) that supports XML-RPC over a domain socket (also working around a bug in Python's handling of NIL). This also introduces a new server that runs along side of the existing S-Expression/HTTP server. This changeset makes no change to the normal operation of Xend. xm still goes through S-Expression/HTTP -- there's just another option for interacting with Xend. Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx> diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py Tue Feb 28 16:45:20 2006 +++ b/tools/python/xen/xend/server/SrvServer.py Tue Feb 28 22:08:47 2006 @@ -51,6 +51,7 @@ from xen.web.SrvDir import SrvDir from SrvRoot import SrvRoot +from XMLRPCServer import XMLRPCServer xroot = XendRoot.instance() @@ -113,4 +114,5 @@ path = xroot.get_xend_unix_path() log.info('unix path=' + path) servers.add(UnixHttpServer(path=path, root=root)) + servers.add(XMLRPCServer()) return servers diff -r c369d960f96b -r 095ac0d95d9c tools/python/xen/util/xmlrpclib2.py --- /dev/null Tue Feb 28 16:45:20 2006 +++ b/tools/python/xen/util/xmlrpclib2.py Tue Feb 28 22:08:47 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 problem 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 = uri.split(':')[0] + if protocol == 'httpu': + uri = 'http:' + ':'.join(uri.split(':')[1:]) + 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(exc) + 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 c369d960f96b -r 095ac0d95d9c tools/python/xen/xend/server/XMLRPCServer.py --- /dev/null Tue Feb 28 16:45:20 2006 +++ b/tools/python/xen/xend/server/XMLRPCServer.py Tue Feb 28 22:08:47 2006 @@ -0,0 +1,97 @@ +#============================================================================ +# 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 + +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') + ret = f.read() + f.close() + return ret + +methods = ['device_create', 'destroyDevice', 'getDeviceSxprs', + 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown', + 'send_sysrq', 'getVCPUInfo', 'waitForDevices'] + +exclude = ['domain_create', 'domain_restore'] + +class XMLRPCServer: + def __init__(self): + self.ready = False + + def run(self): + self.server = UnixXMLRPCServer("/var/run/xend-xmlrpc.sock") + + # 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-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |