[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


 


Rackspace

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