direct-io.hg

changeset 10463:7d6fe353cda4

Move the SSHTransport class to its own file, so that we may disable SSH
transport when running on Python <2.4. SSHTransport uses the new subprocess
class, and so it doesn't work on older versions.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Tue Jun 20 13:32:21 2006 +0100 (2006-06-20)
parents c5da6b25744a
children 674890dc1ee2
files tools/python/xen/util/SSHTransport.py tools/python/xen/util/xmlrpclib2.py tools/python/xen/xend/XendClient.py
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/python/xen/util/SSHTransport.py	Tue Jun 20 13:32:21 2006 +0100
     1.3 @@ -0,0 +1,102 @@
     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 Anthony Liguori <aliguori@us.ibm.com>
    1.19 +# Copyright (C) 2006 XenSource Inc.
    1.20 +#============================================================================
    1.21 +
    1.22 +"""
    1.23 +XML-RPC SSH transport.
    1.24 +"""
    1.25 +
    1.26 +from xmlrpclib import getparser, Fault
    1.27 +from subprocess import Popen, PIPE
    1.28 +from getpass import getuser
    1.29 +from fcntl import ioctl
    1.30 +import errno
    1.31 +import os
    1.32 +import termios
    1.33 +
    1.34 +
    1.35 +def getHTTPURI(uri):
    1.36 +    (protocol, rest) = uri.split(':', 1)
    1.37 +    if not rest.startswith('//'):
    1.38 +        raise ValueError("Invalid ssh URL '%s'" % uri)
    1.39 +    rest = rest[2:]
    1.40 +    user = getuser()
    1.41 +    path = 'RPC2'
    1.42 +    if rest.find('@') != -1:
    1.43 +        (user, rest) = rest.split('@', 1)
    1.44 +    if rest.find('/') != -1:
    1.45 +        (host, rest) = rest.split('/', 1)
    1.46 +        if len(rest) > 0:
    1.47 +            path = rest
    1.48 +    else:
    1.49 +        host = rest
    1.50 +    transport = SSHTransport(host, user)
    1.51 +    uri = 'http://%s/%s' % (host, path)
    1.52 +    return transport, uri
    1.53 +
    1.54 +
    1.55 +class SSHTransport(object):
    1.56 +    def __init__(self, host, user, askpass=None):
    1.57 +        self.host = host
    1.58 +        self.user = user
    1.59 +        self.askpass = askpass
    1.60 +        self.ssh = None
    1.61 +
    1.62 +    def getssh(self):
    1.63 +        if self.ssh == None:
    1.64 +            if self.askpass:
    1.65 +                f = open('/dev/tty', 'w')
    1.66 +                try:
    1.67 +                    os.environ['SSH_ASKPASS'] = self.askpass
    1.68 +                    ioctl(f.fileno(), termios.TIOCNOTTY)
    1.69 +                finally:
    1.70 +                    f.close()
    1.71 +
    1.72 +            cmd = ['ssh', '%s@%s' % (self.user, self.host), 'xm serve']
    1.73 +            try:
    1.74 +                self.ssh = Popen(cmd, bufsize=0, stdin=PIPE, stdout=PIPE)
    1.75 +            except OSError, (err, msg):
    1.76 +                if err == errno.ENOENT:
    1.77 +                    raise Fault(0, "ssh executable not found!")
    1.78 +                raise
    1.79 +        return self.ssh
    1.80 +
    1.81 +    def request(self, host, handler, request_body, verbose=0):
    1.82 +        p, u = getparser()
    1.83 +        ssh = self.getssh()
    1.84 +        ssh.stdin.write("""POST /%s HTTP/1.1
    1.85 +User-Agent: Xen
    1.86 +Host: %s
    1.87 +Content-Type: text/xml
    1.88 +Content-Length: %d
    1.89 +
    1.90 +%s""" % (handler, host, len(request_body), request_body))
    1.91 +        ssh.stdin.flush()
    1.92 +
    1.93 +        content_length = 0
    1.94 +        line = ssh.stdout.readline()
    1.95 +        if line.split()[1] != '200':
    1.96 +            raise Fault(0, 'Server returned %s' % (' '.join(line[1:])))
    1.97 +        
    1.98 +        while line not in ['', '\r\n', '\n']:
    1.99 +            if line.lower().startswith('content-length:'):
   1.100 +                content_length = int(line[15:].strip())
   1.101 +            line = ssh.stdout.readline()
   1.102 +        content = ssh.stdout.read(content_length)
   1.103 +        p.feed(content)
   1.104 +        p.close()
   1.105 +        return u.close()
     2.1 --- a/tools/python/xen/util/xmlrpclib2.py	Tue Jun 20 12:12:44 2006 +0100
     2.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Tue Jun 20 13:32:21 2006 +0100
     2.3 @@ -13,7 +13,7 @@
     2.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     2.5  #============================================================================
     2.6  # Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
     2.7 -# Copyright (C) 2006 XenSource Ltd.
     2.8 +# Copyright (C) 2006 XenSource Inc.
     2.9  #============================================================================
    2.10  
    2.11  """
    2.12 @@ -24,67 +24,20 @@ import string
    2.13  import types
    2.14  
    2.15  from httplib import HTTPConnection, HTTP
    2.16 -from xmlrpclib import Transport, getparser, Fault
    2.17 +from xmlrpclib import Transport
    2.18  from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
    2.19 -from subprocess import Popen, PIPE
    2.20 -from getpass import getuser
    2.21 -from fcntl import ioctl
    2.22 -import xmlrpclib, socket, os, stat, termios, errno
    2.23  import SocketServer
    2.24 +import xmlrpclib, socket, os, stat
    2.25  
    2.26  from xen.xend.XendLogging import log
    2.27  
    2.28 -class SSHTransport(object):
    2.29 -    def __init__(self, host, user, askpass=None):
    2.30 -        self.host = host
    2.31 -        self.user = user
    2.32 -        self.askpass = askpass
    2.33 -        self.ssh = None
    2.34 -
    2.35 -    def getssh(self):
    2.36 -        if self.ssh == None:
    2.37 -            if self.askpass:
    2.38 -                f = open('/dev/tty', 'w')
    2.39 -                try:
    2.40 -                    os.environ['SSH_ASKPASS'] = self.askpass
    2.41 -                    ioctl(f.fileno(), termios.TIOCNOTTY)
    2.42 -                finally:
    2.43 -                    f.close()
    2.44 -
    2.45 -            cmd = ['ssh', '%s@%s' % (self.user, self.host), 'xm serve']
    2.46 -            try:
    2.47 -                self.ssh = Popen(cmd, bufsize=0, stdin=PIPE, stdout=PIPE)
    2.48 -            except OSError, (err, msg):
    2.49 -                if err == errno.ENOENT:
    2.50 -                    raise Fault(0, "ssh executable not found!")
    2.51 -                raise
    2.52 -        return self.ssh
    2.53 -
    2.54 -    def request(self, host, handler, request_body, verbose=0):
    2.55 -        p, u = getparser()
    2.56 -        ssh = self.getssh()
    2.57 -        ssh.stdin.write("""POST /%s HTTP/1.1
    2.58 -User-Agent: Xen
    2.59 -Host: %s
    2.60 -Content-Type: text/xml
    2.61 -Content-Length: %d
    2.62 -
    2.63 -%s""" % (handler, host, len(request_body), request_body))
    2.64 -        ssh.stdin.flush()
    2.65 -
    2.66 -        content_length = 0
    2.67 -        line = ssh.stdout.readline()
    2.68 -        if line.split()[1] != '200':
    2.69 -            raise Fault(0, 'Server returned %s' % (' '.join(line[1:])))
    2.70 -        
    2.71 -        while line not in ['', '\r\n', '\n']:
    2.72 -            if line.lower().startswith('content-length:'):
    2.73 -                content_length = int(line[15:].strip())
    2.74 -            line = ssh.stdout.readline()
    2.75 -        content = ssh.stdout.read(content_length)
    2.76 -        p.feed(content)
    2.77 -        p.close()
    2.78 -        return u.close()
    2.79 +try:
    2.80 +    import SSHTransport
    2.81 +    ssh_enabled = True
    2.82 +except ImportError:
    2.83 +    # SSHTransport is disabled on Python <2.4, because it uses the subprocess
    2.84 +    # package.
    2.85 +    ssh_enabled = False
    2.86  
    2.87  
    2.88  # A new ServerProxy that also supports httpu urls.  An http URL comes in the
    2.89 @@ -155,21 +108,12 @@ class ServerProxy(xmlrpclib.ServerProxy)
    2.90                  uri = 'http:' + rest
    2.91                  transport = UnixTransport()
    2.92              elif protocol == 'ssh':
    2.93 -                if not rest.startswith('//'):
    2.94 -                    raise ValueError("Invalid ssh URL '%s'" % uri)
    2.95 -                rest = rest[2:]
    2.96 -                user = getuser()
    2.97 -                path = 'RPC2'
    2.98 -                if rest.find('@') != -1:
    2.99 -                    (user, rest) = rest.split('@', 1)
   2.100 -                if rest.find('/') != -1:
   2.101 -                    (host, rest) = rest.split('/', 1)
   2.102 -                    if len(rest) > 0:
   2.103 -                        path = rest
   2.104 +                global ssh_enabled
   2.105 +                if ssh_enabled:
   2.106 +                    (transport, uri) = SSHTransport.getHTTPURI(uri)
   2.107                  else:
   2.108 -                    host = rest
   2.109 -                transport = SSHTransport(host, user)
   2.110 -                uri = 'http://%s/%s' % (host, path)
   2.111 +                    raise ValueError(
   2.112 +                        "SSH transport not supported on Python <2.4.")
   2.113          xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
   2.114                                         verbose, allow_none)
   2.115  
     3.1 --- a/tools/python/xen/xend/XendClient.py	Tue Jun 20 12:12:44 2006 +0100
     3.2 +++ b/tools/python/xen/xend/XendClient.py	Tue Jun 20 13:32:21 2006 +0100
     3.3 @@ -19,6 +19,7 @@
     3.4  
     3.5  from xen.util.xmlrpclib2 import ServerProxy
     3.6  import os
     3.7 +import sys
     3.8  
     3.9  XML_RPC_SOCKET = "/var/run/xend/xmlrpc.sock"
    3.10  
    3.11 @@ -30,4 +31,9 @@ uri = 'httpu:///var/run/xend/xmlrpc.sock
    3.12  if os.environ.has_key('XM_SERVER'):
    3.13      uri = os.environ['XM_SERVER']
    3.14  
    3.15 -server = ServerProxy(uri)
    3.16 +try:
    3.17 +    server = ServerProxy(uri)
    3.18 +except ValueError, exn:
    3.19 +    print >>sys.stderr, exn
    3.20 +    sys.exit(1)
    3.21 +