Show More
@@ -21,26 +21,22 b' import glob' | |||
|
21 | 21 | import os |
|
22 | 22 | import signal |
|
23 | 23 | import sys |
|
24 | from getpass import getpass | |
|
25 | 24 | |
|
26 | 25 | # System library imports |
|
27 | 26 | from IPython.external.qt import QtGui |
|
28 | 27 | from pygments.styles import get_all_styles |
|
29 | 28 | from zmq.utils import jsonapi as json |
|
30 | 29 | |
|
31 | # external imports | |
|
32 | from IPython.external.ssh import tunnel | |
|
33 | ||
|
34 | 30 | # Local imports |
|
35 | 31 | from IPython.config.application import boolean_flag |
|
36 | 32 | from IPython.core.application import BaseIPythonApplication |
|
37 | 33 | from IPython.core.profiledir import ProfileDir |
|
34 | from IPython.lib.kernel import tunnel_to_kernel | |
|
38 | 35 | from IPython.frontend.qt.console.frontend_widget import FrontendWidget |
|
39 | 36 | from IPython.frontend.qt.console.ipython_widget import IPythonWidget |
|
40 | 37 | from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget |
|
41 | 38 | from IPython.frontend.qt.console import styles |
|
42 | 39 | from IPython.frontend.qt.kernelmanager import QtKernelManager |
|
43 | from IPython.parallel.util import select_random_ports | |
|
44 | 40 | from IPython.utils.path import filefind |
|
45 | 41 | from IPython.utils.py3compat import str_to_bytes |
|
46 | 42 | from IPython.utils.traitlets import ( |
@@ -424,24 +420,30 b' class IPythonQtConsoleApp(BaseIPythonApplication):' | |||
|
424 | 420 | return |
|
425 | 421 | |
|
426 | 422 | if self.sshkey and not self.sshserver: |
|
423 | # specifying just the key implies that we are connecting directly | |
|
427 | 424 | self.sshserver = self.ip |
|
428 | 425 | self.ip=LOCALHOST |
|
429 | 426 | |
|
430 | lports = select_random_ports(4) | |
|
431 | rports = self.shell_port, self.iopub_port, self.stdin_port, self.hb_port | |
|
432 | self.shell_port, self.iopub_port, self.stdin_port, self.hb_port = lports | |
|
427 | # build connection dict for tunnels: | |
|
428 | info = dict(ip=self.ip, | |
|
429 | shell_port=self.shell_port, | |
|
430 | iopub_port=self.iopub_port, | |
|
431 | stdin_port=self.stdin_port, | |
|
432 | hb_port=self.hb_port | |
|
433 | ) | |
|
434 | ||
|
435 | self.log.info("Forwarding connections to %s via %s"%(self.ip, self.sshserver)) | |
|
433 | 436 | |
|
434 | remote_ip = self.ip | |
|
437 | # tunnels return a new set of ports, which will be on localhost: | |
|
435 | 438 | self.ip = LOCALHOST |
|
436 | self.log.info("Forwarding connections to %s via %s"%(remote_ip, self.sshserver)) | |
|
437 | ||
|
438 | if tunnel.try_passwordless_ssh(self.sshserver, self.sshkey): | |
|
439 | password=False | |
|
440 | else: | |
|
441 | password = getpass("SSH Password for %s: "%self.sshserver) | |
|
439 | try: | |
|
440 | newports = tunnel_to_kernel(info, self.sshserver, self.sshkey) | |
|
441 | except: | |
|
442 | # even catch KeyboardInterrupt | |
|
443 | self.log.error("Could not setup tunnels", exc_info=True) | |
|
444 | self.exit(1) | |
|
442 | 445 | |
|
443 | for lp,rp in zip(lports, rports): | |
|
444 | tunnel.ssh_tunnel(lp, rp, self.sshserver, remote_ip, self.sshkey, password) | |
|
446 | self.shell_port, self.iopub_port, self.stdin_port, self.hb_port = newports | |
|
445 | 447 | |
|
446 | 448 | cf = self.connection_file |
|
447 | 449 | base,ext = os.path.splitext(cf) |
@@ -19,8 +19,13 b' Authors:' | |||
|
19 | 19 | |
|
20 | 20 | import json |
|
21 | 21 | import sys |
|
22 | from getpass import getpass | |
|
22 | 23 | from subprocess import Popen, PIPE |
|
23 | 24 | |
|
25 | # external imports | |
|
26 | from IPython.external.ssh import tunnel | |
|
27 | ||
|
28 | # IPython imports | |
|
24 | 29 | from IPython.utils.path import filefind |
|
25 | 30 | from IPython.utils.py3compat import str_to_bytes |
|
26 | 31 | |
@@ -96,4 +101,52 b' def connect_qtconsole(argv=None):' | |||
|
96 | 101 | |
|
97 | 102 | return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv, stdout=PIPE, stderr=PIPE) |
|
98 | 103 | |
|
104 | def tunnel_to_kernel(connection_info, sshserver, sshkey=None): | |
|
105 | """tunnel connections to a kernel via ssh | |
|
106 | ||
|
107 | This will open four SSH tunnels from localhost on this machine to the | |
|
108 | ports associated with the kernel. They can be either direct | |
|
109 | localhost-localhost tunnels, or if an intermediate server is necessary, | |
|
110 | the kernel must be listening on a public IP. | |
|
111 | ||
|
112 | Parameters | |
|
113 | ---------- | |
|
114 | connection_info : dict or str (path) | |
|
115 | Either a connection dict, or the path to a JSON connection file | |
|
116 | sshserver : str | |
|
117 | The ssh sever to use to tunnel to the kernel. Can be a full | |
|
118 | `user@server:port` string. ssh config aliases are respected. | |
|
119 | sshkey : str [optional] | |
|
120 | Path to file containing ssh key to use for authentication. | |
|
121 | Only necessary if your ssh config does not already associate | |
|
122 | a keyfile with the host. | |
|
123 | ||
|
124 | Returns | |
|
125 | ------- | |
|
126 | ||
|
127 | (shell, iopub, stdin, hb) : ints | |
|
128 | The four ports on localhost that have been forwarded to the kernel. | |
|
129 | """ | |
|
130 | if isinstance(connection_info, basestring): | |
|
131 | # it's a path, unpack it | |
|
132 | with open(connection_info) as f: | |
|
133 | connection_info = json.loads(f.read()) | |
|
134 | ||
|
135 | cf = connection_info | |
|
136 | ||
|
137 | lports = tunnel.select_random_ports(4) | |
|
138 | rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf['hb_port'] | |
|
139 | ||
|
140 | remote_ip = cf['ip'] | |
|
141 | ||
|
142 | if tunnel.try_passwordless_ssh(sshserver, sshkey): | |
|
143 | password=False | |
|
144 | else: | |
|
145 | password = getpass("SSH Password for %s: "%sshserver) | |
|
146 | ||
|
147 | for lp,rp in zip(lports, rports): | |
|
148 | tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password) | |
|
149 | ||
|
150 | return tuple(lports) | |
|
151 | ||
|
99 | 152 |
General Comments 0
You need to be logged in to leave comments.
Login now