WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 2/2] Add XML-RPC support to Xend

To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 2/2] Add XML-RPC support to Xend
From: Anthony Liguori <aliguori@xxxxxxxxxx>
Date: Tue, 28 Feb 2006 16:24:50 -0600
Cc: Ewan Mellor <ewan@xxxxxxxxxxxxx>
Delivery-date: Tue, 28 Feb 2006 22:25:25 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4404CD0A.6000903@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <4404CD0A.6000903@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mail/News 1.5 (X11/20060213)
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
<Prev in Thread] Current Thread [Next in Thread>