direct-io.hg

changeset 12740:92127156ec49

Added server proxy and session manager for Xen-API clients.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Wed Dec 06 10:47:31 2006 +0000 (2006-12-06)
parents c4824dcd57c4
children cf1ca0615414
files tools/python/xen/xm/XenAPI.py
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/python/xen/xm/XenAPI.py	Wed Dec 06 10:47:31 2006 +0000
     1.3 @@ -0,0 +1,132 @@
     1.4 +#============================================================================
     1.5 +# This library is free software; you can redistribute it and/or
     1.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
     1.7 +# License as published by the Free Software Foundation.
     1.8 +#
     1.9 +# This library is distributed in the hope that it will be useful,
    1.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.12 +# Lesser General Public License for more details.
    1.13 +#
    1.14 +# You should have received a copy of the GNU Lesser General Public
    1.15 +# License along with this library; if not, write to the Free Software
    1.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.17 +#============================================================================
    1.18 +# Copyright (C) 2006 XenSource Inc.
    1.19 +#============================================================================
    1.20 +#
    1.21 +# Parts of this file are based upon xmlrpclib.py, the XML-RPC client
    1.22 +# interface included in the Python distribution.
    1.23 +#
    1.24 +# Copyright (c) 1999-2002 by Secret Labs AB
    1.25 +# Copyright (c) 1999-2002 by Fredrik Lundh
    1.26 +#
    1.27 +# By obtaining, using, and/or copying this software and/or its
    1.28 +# associated documentation, you agree that you have read, understood,
    1.29 +# and will comply with the following terms and conditions:
    1.30 +#
    1.31 +# Permission to use, copy, modify, and distribute this software and
    1.32 +# its associated documentation for any purpose and without fee is
    1.33 +# hereby granted, provided that the above copyright notice appears in
    1.34 +# all copies, and that both that copyright notice and this permission
    1.35 +# notice appear in supporting documentation, and that the name of
    1.36 +# Secret Labs AB or the author not be used in advertising or publicity
    1.37 +# pertaining to distribution of the software without specific, written
    1.38 +# prior permission.
    1.39 +#
    1.40 +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
    1.41 +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
    1.42 +# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
    1.43 +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    1.44 +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
    1.45 +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
    1.46 +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
    1.47 +# OF THIS SOFTWARE.
    1.48 +# --------------------------------------------------------------------
    1.49 +
    1.50 +import xmlrpclib
    1.51 +
    1.52 +import xen.util.xmlrpclib2
    1.53 +
    1.54 +
    1.55 +class Failure(Exception):
    1.56 +    def __init__(self, details):
    1.57 +        self.details = details
    1.58 +
    1.59 +    def __str__(self):
    1.60 +        return "Xen-API failure: %s" % str(self.details)
    1.61 +
    1.62 +
    1.63 +class Session(xen.util.xmlrpclib2.ServerProxy):
    1.64 +    """A server proxy and session manager for communicating with Xend using
    1.65 +    the Xen-API.
    1.66 +
    1.67 +    Example:
    1.68 +
    1.69 +    session = Session('http://localhost:9363/')
    1.70 +    session.login_with_password('me', 'mypassword')
    1.71 +    session.xenapi.VM.start(vm_uuid)
    1.72 +    session.xenapi.session.logout()
    1.73 +
    1.74 +    For now, this class also supports the legacy XML-RPC API, using
    1.75 +    session.xend.domain('Domain-0') and similar.  This support will disappear
    1.76 +    once there is a working Xen-API replacement for every call in the legacy
    1.77 +    API.
    1.78 +    """
    1.79 +
    1.80 +    def __init__(self, uri, transport=None, encoding=None, verbose=0,
    1.81 +                 allow_none=1):
    1.82 +        xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
    1.83 +                                                 encoding, verbose,
    1.84 +                                                 allow_none)
    1.85 +        self._session = None
    1.86 +
    1.87 +
    1.88 +    def _xen_request(self, methodname, params):
    1.89 +        full_params = (self._session,) + params
    1.90 +        return _parse_result(getattr(self, methodname)(*full_params))
    1.91 +
    1.92 +
    1.93 +    def _login(self, method, username, password):
    1.94 +        self._session = _parse_result(
    1.95 +            getattr(self, 'session.%s' % method)(username, password))
    1.96 +
    1.97 +
    1.98 +    def __getattr__(self, name):
    1.99 +        if name == 'xenapi':
   1.100 +            return _Dispatcher(self._xen_request, None)
   1.101 +        elif name.startswith('login'):
   1.102 +            return lambda u, p: self._login(name, u, p)
   1.103 +        else:
   1.104 +            return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
   1.105 +
   1.106 +
   1.107 +def _parse_result(result):
   1.108 +    if 'Status' not in result:
   1.109 +        raise xmlrpclib.Fault(500, 'Missing Status in response from server')
   1.110 +    if result['Status'] == 'Success':
   1.111 +        if 'Value' in result:
   1.112 +            return result['Value']
   1.113 +        else:
   1.114 +            raise xmlrpclib.Fault(500,
   1.115 +                                  'Missing Value in response from server')
   1.116 +    else:
   1.117 +        if 'ErrorDescription' in result:
   1.118 +            raise Failure(result['ErrorDescription'])
   1.119 +        else:
   1.120 +            raise xmlrpclib.Fault(
   1.121 +                500, 'Missing ErrorDescription in response from server')
   1.122 +
   1.123 +
   1.124 +# Based upon _Method from xmlrpclib.
   1.125 +class _Dispatcher:
   1.126 +    def __init__(self, send, name):
   1.127 +        self.__send = send
   1.128 +        self.__name = name
   1.129 +    def __getattr__(self, name):
   1.130 +        if self.__name is None:
   1.131 +            return _Dispatcher(self.__send, name)
   1.132 +        else:
   1.133 +            return _Dispatcher(self.__send, "%s.%s" % (self.__name, name))
   1.134 +    def __call__(self, *args):
   1.135 +        return self.__send(self.__name, args)