|
@@ -120,3 +120,42 @@ def extract_capabilities(text):
|
|
|
capabilities = text.split("\0")
|
|
|
return (capabilities[0], capabilities[1:])
|
|
|
|
|
|
+
|
|
|
+class SSHSubprocess(object):
|
|
|
+ """A socket-like object that talks to an ssh subprocess via pipes."""
|
|
|
+
|
|
|
+ def __init__(self, proc):
|
|
|
+ self.proc = proc
|
|
|
+
|
|
|
+ def send(self, data):
|
|
|
+ return os.write(self.proc.stdin.fileno(), data)
|
|
|
+
|
|
|
+ def recv(self, count):
|
|
|
+ return os.read(self.proc.stdout.fileno(), count)
|
|
|
+
|
|
|
+ def close(self):
|
|
|
+ self.proc.stdin.close()
|
|
|
+ self.proc.stdout.close()
|
|
|
+ self.proc.wait()
|
|
|
+
|
|
|
+
|
|
|
+class SSHVendor(object):
|
|
|
+
|
|
|
+ def connect_ssh(self, host, command, username=None, port=None):
|
|
|
+ #FIXME: This has no way to deal with passwords..
|
|
|
+ args = ['ssh', '-x']
|
|
|
+ if port is not None:
|
|
|
+ args.extend(['-p', str(port)])
|
|
|
+ if username is not None:
|
|
|
+ host = "%s@%s" % (username, host)
|
|
|
+ args.append(host)
|
|
|
+ else:
|
|
|
+ args.append(host)
|
|
|
+ proc = subprocess.Popen(args + command,
|
|
|
+ stdin=subprocess.PIPE,
|
|
|
+ stdout=subprocess.PIPE)
|
|
|
+ return SSHSubprocess(proc)
|
|
|
+
|
|
|
+# Can be overridden by users
|
|
|
+get_ssh_vendor = SSHVendor
|
|
|
+
|