diff options
Diffstat (limited to 'dotviewer')
-rw-r--r-- | dotviewer/graphclient.py | 26 | ||||
-rwxr-xr-x | dotviewer/graphserver.py | 7 | ||||
-rwxr-xr-x | dotviewer/sshgraphserver.py | 71 |
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:]) |