All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@us.ibm.com>
To: xen-devel <xen-devel@lists.xensource.com>
Cc: Ewan Mellor <ewan@xensource.com>
Subject: [PATCH 2/4] Client support for XML-RPC over SSH
Date: Wed, 14 Jun 2006 14:33:52 -0500	[thread overview]
Message-ID: <449064A0.8050601@us.ibm.com> (raw)
In-Reply-To: <44906357.90107@us.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 139 bytes --]

This incorporates Ewan's error reporting suggestion and uses lazy 
evaluation to initialize the ssh connection.

Regards,

Anthony Liguori

[-- Attachment #2: sshtransport-1.diff --]
[-- Type: text/plain, Size: 4369 bytes --]

# HG changeset patch
# User root@rhesis.austin.ibm.com
# Node ID ee7eb0713498591c50f43cabfcf48608b0b7aa32
# Parent  84596b81600e09c83e85eb8c7517747d57d1da98
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

diff -r 84596b81600e -r ee7eb0713498 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py	Wed Jun 14 17:09:48 2006
+++ b/tools/python/xen/util/xmlrpclib2.py	Wed Jun 14 19:14:27 2006
@@ -24,13 +24,67 @@
 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 @@
             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 @@
         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)))

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

  parent reply	other threads:[~2006-06-14 19:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-14 19:28 [PATCH 0/4] Add support for XML-RPC over SSH (take two) Anthony Liguori
2006-06-14 19:31 ` [PATCH 1/4] Fix Xend's HTTP/1.1 Keep-Alive support Anthony Liguori
2006-06-14 19:32 ` [PATCH 2/4] Add support for an xm serve command Anthony Liguori
2006-06-14 19:33 ` Anthony Liguori [this message]
2006-06-14 19:34 ` [PATCH 4/4] Add support for XM_SERVER variable to choose XML-RPC URI Anthony Liguori
2006-06-20  9:26 ` [PATCH 0/4] Add support for XML-RPC over SSH (take two) Ewan Mellor
2006-06-20 12:49   ` Ewan Mellor
2006-06-20 21:07     ` Anthony Liguori
2006-06-21  6:30       ` Ewan Mellor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=449064A0.8050601@us.ibm.com \
    --to=aliguori@us.ibm.com \
    --cc=ewan@xensource.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.