aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dotviewer')
-rw-r--r--dotviewer/graphclient.py26
-rwxr-xr-xdotviewer/graphserver.py7
-rwxr-xr-xdotviewer/sshgraphserver.py71
3 files changed, 96 insertions, 8 deletions
diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py
index bb463ed280..702e062520 100644
--- a/dotviewer/graphclient.py
+++ b/dotviewer/graphclient.py
@@ -110,7 +110,10 @@ def send_error(io, e):
def spawn_handler():
gsvar = os.environ.get('GRAPHSERVER')
if not gsvar:
- return spawn_local_handler()
+ try:
+ return spawn_sshgraphserver_handler()
+ except Exception, e:
+ return spawn_local_handler()
else:
try:
host, port = gsvar.split(':')
@@ -119,10 +122,7 @@ def spawn_handler():
except ValueError:
raise ValueError("$GRAPHSERVER must be set to HOST:PORT, got %r" %
(gvvar,))
- import socket
- s = socket.socket()
- s.connect((host, port))
- return msgstruct.SocketIO(s)
+ return spawn_graphserver_handler((host, port))
def spawn_local_handler():
if hasattr(sys, 'pypy_objspaceclass'):
@@ -133,3 +133,19 @@ def spawn_local_handler():
child_in, child_out = os.popen2(cmdline, 'tb')
io = msgstruct.FileIO(child_out, child_in)
return io
+
+def spawn_graphserver_handler(address):
+ import socket
+ s = socket.socket()
+ s.connect(address)
+ return msgstruct.SocketIO(s)
+
+def spawn_sshgraphserver_handler():
+ import tempfile, getpass
+ tmpdir = tempfile.gettempdir()
+ user = getpass.getuser()
+ fn = os.path.join(tmpdir, 'dotviewer-sshgraphsrv-%s' % user)
+ f = open(fn, 'r')
+ port = int(f.readline().rstrip())
+ f.close()
+ return spawn_graphserver_handler(('127.0.0.1', port))
diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py
index 4405439a37..7f680cb560 100755
--- a/dotviewer/graphserver.py
+++ b/dotviewer/graphserver.py
@@ -144,7 +144,7 @@ class Server(object):
}
-def listen_server(local_address):
+def listen_server(local_address, s1=None):
import socket, graphclient, thread
if isinstance(local_address, str):
if ':' in local_address:
@@ -152,8 +152,9 @@ def listen_server(local_address):
else:
interface, port = '', local_address
local_address = interface, int(port)
- s1 = socket.socket()
- s1.bind(local_address)
+ if s1 is None:
+ s1 = socket.socket()
+ s1.bind(local_address)
s1.listen(5)
print 'listening on %r...' % (s1.getsockname(),)
while True:
diff --git a/dotviewer/sshgraphserver.py b/dotviewer/sshgraphserver.py
new file mode 100755
index 0000000000..edd7a8d9a3
--- /dev/null
+++ b/dotviewer/sshgraphserver.py
@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+"""This script displays locally the graphs that are built by dotviewer
+on remote machines.
+
+Usage:
+ sshgraphserver.py hostname [more args for ssh...]
+
+This logs in to 'hostname' by passing the arguments on the command-line
+to ssh. No further configuration is required: it works for all programs
+using the dotviewer library as long as they run on 'hostname' under the
+same username as the one sshgraphserver logs as.
+"""
+
+import graphserver, socket, subprocess, random
+
+
+def ssh_graph_server(sshargs):
+ s1 = socket.socket()
+ s1.bind(('127.0.0.1', socket.INADDR_ANY))
+ localhost, localport = s1.getsockname()
+ remoteport = random.randrange(10000, 20000)
+ # ^^^ and just hope there is no conflict
+
+ args = ['ssh', '-C', '-R%d:127.0.0.1:%d' % (remoteport, localport)]
+ args = args + sshargs + ['python -u -c "exec input()"']
+ print ' '.join(args[:-1])
+ p = subprocess.Popen(args, bufsize=0,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ p.stdin.write(repr('port=%d\n%s' % (remoteport, REMOTE_SOURCE)) + '\n')
+ line = p.stdout.readline()
+ assert line == 'OK\n'
+
+ graphserver.listen_server(None, s1=s1)
+
+
+REMOTE_SOURCE = r"""
+import tempfile, getpass, os, sys
+
+def main(port):
+ tmpdir = tempfile.gettempdir()
+ user = getpass.getuser()
+ fn = os.path.join(tmpdir, 'dotviewer-sshgraphsrv-%s' % user)
+ try:
+ os.unlink(fn)
+ except OSError:
+ pass
+ f = open(fn, 'w')
+ print >> f, port
+ f.close()
+ try:
+ sys.stdout.write('OK\n')
+ # just wait for the loss of the remote link, ignoring any data
+ while sys.stdin.read(1024):
+ pass
+ finally:
+ try:
+ os.unlink(fn)
+ except OSError:
+ pass
+
+main(port)
+"""
+
+
+if __name__ == '__main__':
+ import sys
+ if len(sys.argv) <= 1:
+ print __doc__
+ sys.exit(2)
+ ssh_graph_server(sys.argv[1:])