##// END OF EJS Templates
split QtConsole.init_ssh into generic tunnel_to_kernel...
split QtConsole.init_ssh into generic tunnel_to_kernel added to new IPython.lib.kernel with other kernel connection utilities.

File last commit:

r4971:46eb4e12
r4971:46eb4e12
Show More
kernel.py
152 lines | 4.6 KiB | text/x-python | PythonLexer
"""Utilities for connecting to kernels
Authors:
* Min Ragan-Kelley
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2011 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import json
import sys
from getpass import getpass
from subprocess import Popen, PIPE
# external imports
from IPython.external.ssh import tunnel
# IPython imports
from IPython.utils.path import filefind
from IPython.utils.py3compat import str_to_bytes
#-----------------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------------
def get_connection_file(app=None):
"""Return the path to the connection file of an app
Parameters
----------
app : KernelApp instance [optional]
If unspecified, the currently running app will be used
"""
if app is None:
from IPython.zmq.kernelapp import KernelApp
if not KernelApp.initialized():
raise RuntimeError("app not specified, and not in a running Kernel")
app = KernelApp.instance()
return filefind(app.connection_file, ['.', app.profile_dir.security_dir])
def get_connection_info(unpack=False):
"""Return the connection information for the current Kernel.
Parameters
----------
unpack : bool [default: False]
if True, return the unpacked dict, otherwise just the string contents
of the file.
Returns
-------
The connection dictionary of the current kernel, as string or dict,
depending on `unpack`.
"""
cf = get_connection_file()
with open(cf) as f:
info = f.read()
if unpack:
info = json.loads(info)
# ensure key is bytes:
info['key'] = str_to_bytes(info.get('key', ''))
return info
def connect_qtconsole(argv=None):
"""Connect a qtconsole to the current kernel.
This is useful for connecting a second qtconsole to a kernel, or to a
local notebook.
Parameters
----------
argv : list [optional]
Any extra args to be passed to the console.
Returns
-------
subprocess.Popen instance running the qtconsole frontend
"""
argv = [] if argv is None else argv
# get connection file from current kernel
cf = get_connection_file()
cmd = ';'.join([
"from IPython.frontend.qt.console import qtconsoleapp",
"qtconsoleapp.main()"
])
return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv, stdout=PIPE, stderr=PIPE)
def tunnel_to_kernel(connection_info, sshserver, sshkey=None):
"""tunnel connections to a kernel via ssh
This will open four SSH tunnels from localhost on this machine to the
ports associated with the kernel. They can be either direct
localhost-localhost tunnels, or if an intermediate server is necessary,
the kernel must be listening on a public IP.
Parameters
----------
connection_info : dict or str (path)
Either a connection dict, or the path to a JSON connection file
sshserver : str
The ssh sever to use to tunnel to the kernel. Can be a full
`user@server:port` string. ssh config aliases are respected.
sshkey : str [optional]
Path to file containing ssh key to use for authentication.
Only necessary if your ssh config does not already associate
a keyfile with the host.
Returns
-------
(shell, iopub, stdin, hb) : ints
The four ports on localhost that have been forwarded to the kernel.
"""
if isinstance(connection_info, basestring):
# it's a path, unpack it
with open(connection_info) as f:
connection_info = json.loads(f.read())
cf = connection_info
lports = tunnel.select_random_ports(4)
rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf['hb_port']
remote_ip = cf['ip']
if tunnel.try_passwordless_ssh(sshserver, sshkey):
password=False
else:
password = getpass("SSH Password for %s: "%sshserver)
for lp,rp in zip(lports, rports):
tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password)
return tuple(lports)