debuggers.hg

view tools/python/xen/util/SSHTransport.py @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2006 Anthony Liguori <aliguori@us.ibm.com>
16 # Copyright (C) 2006 XenSource Inc.
17 #============================================================================
19 """
20 XML-RPC SSH transport.
21 """
23 from xmlrpclib import getparser, Fault
24 from subprocess import Popen, PIPE
25 from getpass import getuser
26 from fcntl import ioctl
27 import errno
28 import os
29 import termios
32 def getHTTPURI(uri):
33 (protocol, rest) = uri.split(':', 1)
34 if not rest.startswith('//'):
35 raise ValueError("Invalid ssh URL '%s'" % uri)
36 rest = rest[2:]
37 user = getuser()
38 path = 'RPC2'
39 if rest.find('@') != -1:
40 (user, rest) = rest.split('@', 1)
41 if rest.find('/') != -1:
42 (host, rest) = rest.split('/', 1)
43 if len(rest) > 0:
44 path = rest
45 else:
46 host = rest
47 transport = SSHTransport(host, user)
48 uri = 'http://%s/%s' % (host, path)
49 return transport, uri
52 class SSHTransport(object):
53 def __init__(self, host, user, askpass=None):
54 self.host = host
55 self.user = user
56 self.askpass = askpass
57 self.ssh = None
59 def getssh(self):
60 if self.ssh == None:
61 if self.askpass:
62 f = open('/dev/tty', 'w')
63 try:
64 os.environ['SSH_ASKPASS'] = self.askpass
65 ioctl(f.fileno(), termios.TIOCNOTTY)
66 finally:
67 f.close()
69 cmd = ['ssh', '%s@%s' % (self.user, self.host), 'xm serve']
70 try:
71 self.ssh = Popen(cmd, bufsize=0, stdin=PIPE, stdout=PIPE)
72 except OSError, (err, msg):
73 if err == errno.ENOENT:
74 raise Fault(0, "ssh executable not found!")
75 raise
76 return self.ssh
78 def request(self, host, handler, request_body, verbose=0):
79 p, u = getparser()
80 ssh = self.getssh()
81 ssh.stdin.write("""POST /%s HTTP/1.1
82 User-Agent: Xen
83 Host: %s
84 Content-Type: text/xml
85 Content-Length: %d
87 %s""" % (handler, host, len(request_body), request_body))
88 ssh.stdin.flush()
90 content_length = 0
91 line = ssh.stdout.readline()
92 if line.split()[1] != '200':
93 raise Fault(0, 'Server returned %s' % (' '.join(line[1:])))
95 while line not in ['', '\r\n', '\n']:
96 if line.lower().startswith('content-length:'):
97 content_length = int(line[15:].strip())
98 line = ssh.stdout.readline()
99 content = ssh.stdout.read(content_length)
100 p.feed(content)
101 p.close()
102 return u.close()