[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [RFC] Xend XML-RPC Refactoring



Ian Pratt wrote:
would also like to standardize this XML-RPC interface so that third-parties write apps to this interface without worrying about massive breakage.

Anothony, have you an updated version of this patch? How much testing
has it had?
Yes, I sent those to xen-devel just the other day. They are attached to this note for your convenience.

I've done a bunch of testing (via xm-test) on x86-32 and limited on x86-64.
Should we be looking to get it in prior to 3.0.2?
I think the patch that adds an XML-RPC interface to Xend ought to go in. It doesn't change any of the normally executed code paths for xm and only listens on a domain socket. This would give us a chance to start supporting XML-RPC in libvirt and to bang on the interface a little more.

If 3.0.2 is going out shortly, I'd say hold off on the second patch until after it goes out. There's no real benefit with the second patch other than getting more people to exercise the code so it's probably not worth taking the risk (although as I said, I've tested it pretty heavily).
 In principle I think
this would be a good thing, but we may have left it too late. I expect
2.6.16 final will be out fairly soon, and then we'll want to be pushing
a release out in the following week or so.
I split up the patches specifically with this in mind. The first one should be very low-risk.

Regards,

Anthony Liguori
Thanks,
Ian

# 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()
# 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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.