[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] This patch adds client side support for XML-RPC over ssh. It differs from
# HG changeset patch # User root@xxxxxxxxxxxxxxxxxxxxx # Node ID c2cbcccc44f4252e85ab361f5abbcbe3f3cb3007 # Parent 95ac3f0f79bc1ab821cd93da525df52e2e33329a This patch adds client side support for XML-RPC over ssh. It differs from the previous submission in that it now uses lazy evaluation to connect to the remote server and provides more user friendly error messages if ssh is not available. Signed-off-by: Anthony Liguori --- tools/python/xen/util/xmlrpclib2.py | 78 ++++++++++++++++++++++++++++++++++-- 1 files changed, 74 insertions(+), 4 deletions(-) diff -r 95ac3f0f79bc -r c2cbcccc44f4 tools/python/xen/util/xmlrpclib2.py --- a/tools/python/xen/util/xmlrpclib2.py Tue Jun 20 10:25:20 2006 +0100 +++ b/tools/python/xen/util/xmlrpclib2.py Tue Jun 20 10:25:21 2006 +0100 @@ -24,13 +24,67 @@ import types import types from httplib import HTTPConnection, HTTP -from xmlrpclib import Transport +from xmlrpclib import Transport, getparser, Fault from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler -import xmlrpclib, socket, os, stat +from subprocess import Popen, PIPE +from getpass import getuser +from fcntl import ioctl +import xmlrpclib, socket, os, stat, termios, errno import SocketServer -import xen.xend.XendClient from xen.xend.XendLogging import log + +class SSHTransport(object): + def __init__(self, host, user, askpass=None): + self.host = host + self.user = user + self.askpass = askpass + self.ssh = None + + def getssh(self): + if self.ssh == None: + if self.askpass: + f = open('/dev/tty', 'w') + try: + os.environ['SSH_ASKPASS'] = self.askpass + ioctl(f.fileno(), termios.TIOCNOTTY) + finally: + f.close() + + cmd = ['ssh', '%s@%s' % (self.user, self.host), 'xm serve'] + try: + self.ssh = Popen(cmd, bufsize=0, stdin=PIPE, stdout=PIPE) + except OSError, (err, msg): + if err == errno.ENOENT: + raise Fault(0, "ssh executable not found!") + raise + return self.ssh + + def request(self, host, handler, request_body, verbose=0): + p, u = getparser() + ssh = self.getssh() + ssh.stdin.write("""POST /%s HTTP/1.1 +User-Agent: Xen +Host: %s +Content-Type: text/xml +Content-Length: %d + +%s""" % (handler, host, len(request_body), request_body)) + ssh.stdin.flush() + + content_length = 0 + line = ssh.stdout.readline() + if line.split()[1] != '200': + raise Fault(0, 'Server returned %s' % (' '.join(line[1:]))) + + while line not in ['', '\r\n', '\n']: + if line.lower().startswith('content-length:'): + content_length = int(line[15:].strip()) + line = ssh.stdout.readline() + content = ssh.stdout.read(content_length) + p.feed(content) + p.close() + return u.close() # A new ServerProxy that also supports httpu urls. An http URL comes in the @@ -100,9 +154,24 @@ class ServerProxy(xmlrpclib.ServerProxy) if protocol == 'httpu': uri = 'http:' + rest transport = UnixTransport() + elif protocol == 'ssh': + if not rest.startswith('//'): + raise ValueError("Invalid ssh URL '%s'" % uri) + rest = rest[2:] + user = getuser() + path = 'RPC2' + if rest.find('@') != -1: + (user, rest) = rest.split('@', 1) + if rest.find('/') != -1: + (host, rest) = rest.split('/', 1) + if len(rest) > 0: + path = rest + else: + host = rest + transport = SSHTransport(host, user) + uri = 'http://%s/%s' % (host, path) xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding, verbose, allow_none) - def __request(self, methodname, params): response = xmlrpclib.ServerProxy.__request(self, methodname, params) @@ -150,6 +219,7 @@ class TCPXMLRPCServer(SocketServer.Threa except xmlrpclib.Fault, fault: response = xmlrpclib.dumps(fault) except Exception, exn: + import xen.xend.XendClient log.exception(exn) response = xmlrpclib.dumps( xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn))) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |