ia64/xen-unstable

changeset 13168:e45948c4dba4

Added Xen-API-style error handling for INTERNAL_ERROR and
MESSAGE_METHOD_UNKNOWN. Only add the Xen-API methods to the official Xen-API
XML-RPC server, not to the legacy one.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Fri Dec 22 11:39:29 2006 +0000 (2006-12-22)
parents 0d0e13ff1adf
children 5675a2ac56e4
files tools/python/xen/util/xmlrpclib2.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/XMLRPCServer.py
line diff
     1.1 --- a/tools/python/xen/util/xmlrpclib2.py	Fri Dec 22 11:38:05 2006 +0000
     1.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Fri Dec 22 11:39:29 2006 +0000
     1.3 @@ -20,6 +20,7 @@
     1.4  An enhanced XML-RPC client/server interface for Python.
     1.5  """
     1.6  
     1.7 +import re
     1.8  import string
     1.9  import fcntl
    1.10  from types import *
    1.11 @@ -163,8 +164,10 @@ class ServerProxy(xmlrpclib.ServerProxy)
    1.12  class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
    1.13      allow_reuse_address = True
    1.14  
    1.15 -    def __init__(self, addr, allowed, requestHandler=None,
    1.16 +    def __init__(self, addr, allowed, xenapi, requestHandler=None,
    1.17                   logRequests = 1):
    1.18 +        self.xenapi = xenapi
    1.19 +        
    1.20          if requestHandler is None:
    1.21              requestHandler = XMLRPCRequestHandler
    1.22          SimpleXMLRPCServer.__init__(self, addr,
    1.23 @@ -182,7 +185,7 @@ class TCPXMLRPCServer(SocketServer.Threa
    1.24          flags |= fcntl.FD_CLOEXEC
    1.25          fcntl.fcntl(client.fileno(), fcntl.F_SETFD, flags)
    1.26          return (client, addr)
    1.27 -                                                                                
    1.28 +
    1.29      def _marshaled_dispatch(self, data, dispatch_method = None):
    1.30          params, method = xmlrpclib.loads(data)
    1.31          if False:
    1.32 @@ -214,12 +217,29 @@ class TCPXMLRPCServer(SocketServer.Threa
    1.33          except xmlrpclib.Fault, fault:
    1.34              response = xmlrpclib.dumps(fault)
    1.35          except Exception, exn:
    1.36 -            import xen.xend.XendClient
    1.37 -            log.exception(exn)
    1.38 -            response = xmlrpclib.dumps(
    1.39 -                xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
    1.40 +            if self.xenapi:
    1.41 +                if _is_not_supported(exn):
    1.42 +                    errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
    1.43 +                else:
    1.44 +                    log.exception('Internal error handling %s', method)
    1.45 +                    errdesc = ['INTERNAL_ERROR', str(exn)]
    1.46 +                response = xmlrpclib.dumps(
    1.47 +                    ({ "Status": "Failure",
    1.48 +                       "ErrorDescription": errdesc },),
    1.49 +                    methodresponse = 1)
    1.50 +            else:
    1.51 +                log.exception('Internal error handling %s', method)
    1.52 +                import xen.xend.XendClient
    1.53 +                response = xmlrpclib.dumps(
    1.54 +                    xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
    1.55 +        return response
    1.56  
    1.57 -        return response
    1.58 +
    1.59 +notSupportedRE = re.compile(r'method "(.*)" is not supported')
    1.60 +def _is_not_supported(exn):
    1.61 +    m = notSupportedRE.search(exn[0])
    1.62 +    return m is not None
    1.63 +
    1.64  
    1.65  # This is a XML-RPC server that sits on a Unix domain socket.
    1.66  # It implements proper support for allow_reuse_address by
    1.67 @@ -235,10 +255,10 @@ class UnixXMLRPCRequestHandler(XMLRPCReq
    1.68  class UnixXMLRPCServer(TCPXMLRPCServer):
    1.69      address_family = socket.AF_UNIX
    1.70  
    1.71 -    def __init__(self, addr, allowed, logRequests = 1):
    1.72 +    def __init__(self, addr, allowed, xenapi, logRequests = 1):
    1.73          mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
    1.74          if self.allow_reuse_address and os.path.exists(addr):
    1.75              os.unlink(addr)
    1.76  
    1.77 -        TCPXMLRPCServer.__init__(self, addr, allowed,
    1.78 +        TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
    1.79                                   UnixXMLRPCRequestHandler, logRequests)
     2.1 --- a/tools/python/xen/xend/server/SrvServer.py	Fri Dec 22 11:38:05 2006 +0000
     2.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Fri Dec 22 11:39:29 2006 +0000
     2.3 @@ -198,16 +198,18 @@ def _loadConfig(servers, root, reload):
     2.4  
     2.5                  if len(addrport) == 1:
     2.6                      if addrport[0] == 'unix':
     2.7 -                        servers.add(XMLRPCServer(auth,
     2.8 +                        servers.add(XMLRPCServer(auth, True,
     2.9                                                   path = XEN_API_SOCKET,
    2.10                                                   hosts_allowed = allowed))
    2.11                      else:
    2.12                          servers.add(
    2.13 -                            XMLRPCServer(auth, True, '', int(addrport[0]),
    2.14 +                            XMLRPCServer(auth, True, True, '',
    2.15 +                                         int(addrport[0]),
    2.16                                           hosts_allowed = allowed))
    2.17                  else:
    2.18                      addr, port = addrport
    2.19 -                    servers.add(XMLRPCServer(auth, True, addr, int(port),
    2.20 +                    servers.add(XMLRPCServer(auth, True, True, addr,
    2.21 +                                             int(port),
    2.22                                               hosts_allowed = allowed))
    2.23          except ValueError, exn:
    2.24              log.error('Xen-API server configuration %s is invalid.', api_cfg)
    2.25 @@ -215,10 +217,10 @@ def _loadConfig(servers, root, reload):
    2.26              log.error('Xen-API server configuration %s is invalid.', api_cfg)
    2.27  
    2.28      if xroot.get_xend_tcp_xmlrpc_server():
    2.29 -        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, True))
    2.30 +        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, True))
    2.31  
    2.32      if xroot.get_xend_unix_xmlrpc_server():
    2.33 -        servers.add(XMLRPCServer(XendAPI.AUTH_PAM))
    2.34 +        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
    2.35  
    2.36  
    2.37  def create():
     3.1 --- a/tools/python/xen/xend/server/XMLRPCServer.py	Fri Dec 22 11:38:05 2006 +0000
     3.2 +++ b/tools/python/xen/xend/server/XMLRPCServer.py	Fri Dec 22 11:39:29 2006 +0000
     3.3 @@ -89,8 +89,8 @@ methods = ['device_create', 'device_conf
     3.4  exclude = ['domain_create', 'domain_restore']
     3.5  
     3.6  class XMLRPCServer:
     3.7 -    def __init__(self, auth, use_tcp=False, host = "localhost", port = 8006,
     3.8 -                 path = XML_RPC_SOCKET, hosts_allowed = None):
     3.9 +    def __init__(self, auth, use_xenapi, use_tcp=False, host = "localhost",
    3.10 +                 port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None):
    3.11          self.use_tcp = use_tcp
    3.12          self.port = port
    3.13          self.host = host
    3.14 @@ -100,7 +100,7 @@ class XMLRPCServer:
    3.15          self.ready = False        
    3.16          self.running = True
    3.17          self.auth = auth
    3.18 -        self.xenapi = XendAPI.XendAPI(auth)
    3.19 +        self.xenapi = use_xenapi and XendAPI.XendAPI(auth) or None
    3.20          
    3.21      def run(self):
    3.22          authmsg = (self.auth == XendAPI.AUTH_NONE and 
    3.23 @@ -115,11 +115,13 @@ class XMLRPCServer:
    3.24                           self.port, authmsg)
    3.25                  self.server = TCPXMLRPCServer((self.host, self.port),
    3.26                                                self.hosts_allowed,
    3.27 +                                              self.xenapi is not None,
    3.28                                                logRequests = False)
    3.29              else:
    3.30                  log.info("Opening Unix domain socket XML-RPC server on %s%s",
    3.31                           self.path, authmsg)
    3.32                  self.server = UnixXMLRPCServer(self.path, self.hosts_allowed,
    3.33 +                                               self.xenapi is not None,
    3.34                                                 logRequests = False)
    3.35          except socket.error, exn:
    3.36              log.error('Cannot start server: %s!', exn.args[1])
    3.37 @@ -133,9 +135,10 @@ class XMLRPCServer:
    3.38          # and has the 'api' attribute.
    3.39          
    3.40          for meth_name in dir(self.xenapi):
    3.41 -            meth = getattr(self.xenapi, meth_name)
    3.42 -            if meth_name[0] != '_' and callable(meth) and hasattr(meth, 'api'):
    3.43 -                self.server.register_function(meth, getattr(meth, 'api'))
    3.44 +            if meth_name[0] != '_':
    3.45 +                meth = getattr(self.xenapi, meth_name)
    3.46 +                if callable(meth) and hasattr(meth, 'api'):
    3.47 +                    self.server.register_function(meth, getattr(meth, 'api'))
    3.48                  
    3.49          # Legacy deprecated xm xmlrpc api
    3.50          # --------------------------------------------------------------------