Show More
@@ -3,18 +3,9 b'' | |||||
3 | This is not a complete console app, as subprocess will not be able to receive |
|
3 | This is not a complete console app, as subprocess will not be able to receive | |
4 | input, there is no real readline support, among other limitations. This is a |
|
4 | input, there is no real readline support, among other limitations. This is a | |
5 | refactoring of what used to be the IPython/qt/console/qtconsoleapp.py |
|
5 | refactoring of what used to be the IPython/qt/console/qtconsoleapp.py | |
6 |
|
||||
7 | Authors: |
|
|||
8 |
|
||||
9 | * Evan Patterson |
|
|||
10 | * Min RK |
|
|||
11 | * Erik Tollerud |
|
|||
12 | * Fernando Perez |
|
|||
13 | * Bussonnier Matthias |
|
|||
14 | * Thomas Kluyver |
|
|||
15 | * Paul Ivanov |
|
|||
16 |
|
||||
17 | """ |
|
6 | """ | |
|
7 | # Copyright (c) IPython Development Team. | |||
|
8 | # Distributed under the terms of the Modified BSD License. | |||
18 |
|
9 | |||
19 | #----------------------------------------------------------------------------- |
|
10 | #----------------------------------------------------------------------------- | |
20 | # Imports |
|
11 | # Imports | |
@@ -22,7 +13,6 b' Authors:' | |||||
22 |
|
13 | |||
23 | # stdlib imports |
|
14 | # stdlib imports | |
24 | import atexit |
|
15 | import atexit | |
25 | import json |
|
|||
26 | import os |
|
16 | import os | |
27 | import signal |
|
17 | import signal | |
28 | import sys |
|
18 | import sys | |
@@ -37,9 +27,8 b' from IPython.kernel import KernelManager' | |||||
37 | from IPython.kernel import tunnel_to_kernel, find_connection_file, swallow_argv |
|
27 | from IPython.kernel import tunnel_to_kernel, find_connection_file, swallow_argv | |
38 | from IPython.kernel.kernelspec import NoSuchKernel |
|
28 | from IPython.kernel.kernelspec import NoSuchKernel | |
39 | from IPython.utils.path import filefind |
|
29 | from IPython.utils.path import filefind | |
40 | from IPython.utils.py3compat import str_to_bytes |
|
|||
41 | from IPython.utils.traitlets import ( |
|
30 | from IPython.utils.traitlets import ( | |
42 |
Dict, List, Unicode, CUnicode, |
|
31 | Dict, List, Unicode, CUnicode, CBool, Any | |
43 | ) |
|
32 | ) | |
44 | from IPython.kernel.zmq.kernelapp import ( |
|
33 | from IPython.kernel.zmq.kernelapp import ( | |
45 | kernel_flags, |
|
34 | kernel_flags, | |
@@ -155,21 +144,6 b' class IPythonConsoleApp(ConnectionFileMixin):' | |||||
155 | sshkey = Unicode('', config=True, |
|
144 | sshkey = Unicode('', config=True, | |
156 | help="""Path to the ssh key to use for logging in to the ssh server.""") |
|
145 | help="""Path to the ssh key to use for logging in to the ssh server.""") | |
157 |
|
146 | |||
158 | hb_port = Int(0, config=True, |
|
|||
159 | help="set the heartbeat port [default: random]") |
|
|||
160 | shell_port = Int(0, config=True, |
|
|||
161 | help="set the shell (ROUTER) port [default: random]") |
|
|||
162 | iopub_port = Int(0, config=True, |
|
|||
163 | help="set the iopub (PUB) port [default: random]") |
|
|||
164 | stdin_port = Int(0, config=True, |
|
|||
165 | help="set the stdin (DEALER) port [default: random]") |
|
|||
166 | connection_file = Unicode('', config=True, |
|
|||
167 | help="""JSON file in which to store connection info [default: kernel-<pid>.json] |
|
|||
168 |
|
||||
169 | This file will contain the IP, ports, and authentication key needed to connect |
|
|||
170 | clients to this kernel. By default, this file will be created in the security-dir |
|
|||
171 | of the current profile, but can be specified by absolute path. |
|
|||
172 | """) |
|
|||
173 | def _connection_file_default(self): |
|
147 | def _connection_file_default(self): | |
174 | return 'kernel-%i.json' % os.getpid() |
|
148 | return 'kernel-%i.json' % os.getpid() | |
175 |
|
149 | |||
@@ -230,6 +204,11 b' class IPythonConsoleApp(ConnectionFileMixin):' | |||||
230 | else: |
|
204 | else: | |
231 | cf = self.connection_file |
|
205 | cf = self.connection_file | |
232 | self.connection_file = cf |
|
206 | self.connection_file = cf | |
|
207 | try: | |||
|
208 | self.connection_file = filefind(self.connection_file, ['.', self.profile_dir.security_dir]) | |||
|
209 | except IOError: | |||
|
210 | self.log.debug("Connection File not found: %s", self.connection_file) | |||
|
211 | return | |||
233 |
|
212 | |||
234 | # should load_connection_file only be used for existing? |
|
213 | # should load_connection_file only be used for existing? | |
235 | # as it is now, this allows reusing ports if an existing |
|
214 | # as it is now, this allows reusing ports if an existing | |
@@ -240,31 +219,6 b' class IPythonConsoleApp(ConnectionFileMixin):' | |||||
240 | self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True) |
|
219 | self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True) | |
241 | self.exit(1) |
|
220 | self.exit(1) | |
242 |
|
221 | |||
243 | def load_connection_file(self): |
|
|||
244 | """load ip/port/hmac config from JSON connection file""" |
|
|||
245 | # this is identical to IPKernelApp.load_connection_file |
|
|||
246 | # perhaps it can be centralized somewhere? |
|
|||
247 | try: |
|
|||
248 | fname = filefind(self.connection_file, ['.', self.profile_dir.security_dir]) |
|
|||
249 | except IOError: |
|
|||
250 | self.log.debug("Connection File not found: %s", self.connection_file) |
|
|||
251 | return |
|
|||
252 | self.log.debug(u"Loading connection file %s", fname) |
|
|||
253 | with open(fname) as f: |
|
|||
254 | cfg = json.load(f) |
|
|||
255 | self.transport = cfg.get('transport', 'tcp') |
|
|||
256 | self.ip = cfg.get('ip', localhost()) |
|
|||
257 |
|
||||
258 | for channel in ('hb', 'shell', 'iopub', 'stdin', 'control'): |
|
|||
259 | name = channel + '_port' |
|
|||
260 | if getattr(self, name) == 0 and name in cfg: |
|
|||
261 | # not overridden by config or cl_args |
|
|||
262 | setattr(self, name, cfg[name]) |
|
|||
263 | if 'key' in cfg: |
|
|||
264 | self.config.Session.key = str_to_bytes(cfg['key']) |
|
|||
265 | if 'signature_scheme' in cfg: |
|
|||
266 | self.config.Session.signature_scheme = cfg['signature_scheme'] |
|
|||
267 |
|
||||
268 | def init_ssh(self): |
|
222 | def init_ssh(self): | |
269 | """set up ssh tunnels, if needed.""" |
|
223 | """set up ssh tunnels, if needed.""" | |
270 | if not self.existing or (not self.sshserver and not self.sshkey): |
|
224 | if not self.existing or (not self.sshserver and not self.sshkey): |
@@ -1,17 +1,11 b'' | |||||
1 | """Utilities for connecting to kernels |
|
1 | """Utilities for connecting to kernels | |
2 |
|
2 | |||
3 | Authors: |
|
3 | Notable contents: | |
4 |
|
4 | - ConnectionFileMixin class | ||
5 | * Min Ragan-Kelley |
|
5 | encapsulates the logic related to writing and reading connections files. | |
6 |
|
||||
7 | """ |
|
6 | """ | |
8 |
|
7 | # Copyright (c) IPython Development Team. | ||
9 | #----------------------------------------------------------------------------- |
|
8 | # Distributed under the terms of the Modified BSD License. | |
10 | # Copyright (C) 2013 The IPython Development Team |
|
|||
11 | # |
|
|||
12 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
13 | # the file COPYING, distributed as part of this software. |
|
|||
14 | #----------------------------------------------------------------------------- |
|
|||
15 |
|
9 | |||
16 | #----------------------------------------------------------------------------- |
|
10 | #----------------------------------------------------------------------------- | |
17 | # Imports |
|
11 | # Imports | |
@@ -392,7 +386,13 b' class ConnectionFileMixin(Configurable):' | |||||
392 | """Mixin for configurable classes that work with connection files""" |
|
386 | """Mixin for configurable classes that work with connection files""" | |
393 |
|
387 | |||
394 | # The addresses for the communication channels |
|
388 | # The addresses for the communication channels | |
395 |
connection_file = Unicode('' |
|
389 | connection_file = Unicode('', config=True, | |
|
390 | help="""JSON file in which to store connection info [default: kernel-<pid>.json] | |||
|
391 | ||||
|
392 | This file will contain the IP, ports, and authentication key needed to connect | |||
|
393 | clients to this kernel. By default, this file will be created in the security dir | |||
|
394 | of the current profile, but can be specified by absolute path. | |||
|
395 | """) | |||
396 | _connection_file_written = Bool(False) |
|
396 | _connection_file_written = Bool(False) | |
397 |
|
397 | |||
398 | transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True) |
|
398 | transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True) | |
@@ -419,11 +419,16 b' class ConnectionFileMixin(Configurable):' | |||||
419 |
|
419 | |||
420 | # protected traits |
|
420 | # protected traits | |
421 |
|
421 | |||
422 |
|
|
422 | hb_port = Integer(0, config=True, | |
423 | iopub_port = Integer(0) |
|
423 | help="set the heartbeat port [default: random]") | |
424 |
s |
|
424 | shell_port = Integer(0, config=True, | |
425 | control_port = Integer(0) |
|
425 | help="set the shell (ROUTER) port [default: random]") | |
426 |
|
|
426 | iopub_port = Integer(0, config=True, | |
|
427 | help="set the iopub (PUB) port [default: random]") | |||
|
428 | stdin_port = Integer(0, config=True, | |||
|
429 | help="set the stdin (ROUTER) port [default: random]") | |||
|
430 | control_port = Integer(0, config=True, | |||
|
431 | help="set the control (ROUTER) port [default: random]") | |||
427 |
|
432 | |||
428 | @property |
|
433 | @property | |
429 | def ports(self): |
|
434 | def ports(self): | |
@@ -491,18 +496,20 b' class ConnectionFileMixin(Configurable):' | |||||
491 |
|
496 | |||
492 | def load_connection_file(self): |
|
497 | def load_connection_file(self): | |
493 | """Load connection info from JSON dict in self.connection_file.""" |
|
498 | """Load connection info from JSON dict in self.connection_file.""" | |
|
499 | self.log.debug(u"Loading connection file %s", self.connection_file) | |||
494 | with open(self.connection_file) as f: |
|
500 | with open(self.connection_file) as f: | |
495 |
cfg = json.load |
|
501 | cfg = json.load(f) | |
496 |
|
502 | self.transport = cfg.get('transport', self.transport) | ||
497 |
self. |
|
503 | self.ip = cfg.get('ip', self._ip_default()) | |
498 | self.ip = cfg['ip'] |
|
504 | ||
499 | for name in port_names: |
|
505 | for name in port_names: | |
500 |
|
|
506 | if getattr(self, name) == 0 and name in cfg: | |
|
507 | # not overridden by config or cl_args | |||
|
508 | setattr(self, name, cfg[name]) | |||
501 | if 'key' in cfg: |
|
509 | if 'key' in cfg: | |
502 |
self. |
|
510 | self.config.Session.key = str_to_bytes(cfg['key']) | |
503 |
if |
|
511 | if 'signature_scheme' in cfg: | |
504 |
self. |
|
512 | self.config.Session.signature_scheme = cfg['signature_scheme'] | |
505 |
|
||||
506 | #-------------------------------------------------------------------------- |
|
513 | #-------------------------------------------------------------------------- | |
507 | # Creating connected sockets |
|
514 | # Creating connected sockets | |
508 | #-------------------------------------------------------------------------- |
|
515 | #-------------------------------------------------------------------------- |
@@ -1,15 +1,7 b'' | |||||
1 | """An Application for launching a kernel |
|
1 | """An Application for launching a kernel | |
2 |
|
||||
3 | Authors |
|
|||
4 | ------- |
|
|||
5 | * MinRK |
|
|||
6 | """ |
|
2 | """ | |
7 | #----------------------------------------------------------------------------- |
|
3 | # Copyright (c) IPython Development Team. | |
8 | # Copyright (C) 2011 The IPython Development Team |
|
4 | # Distributed under the terms of the Modified BSD License. | |
9 | # |
|
|||
10 | # Distributed under the terms of the BSD License. The full license is in |
|
|||
11 | # the file COPYING.txt, distributed as part of this software. |
|
|||
12 | #----------------------------------------------------------------------------- |
|
|||
13 |
|
5 | |||
14 | #----------------------------------------------------------------------------- |
|
6 | #----------------------------------------------------------------------------- | |
15 | # Imports |
|
7 | # Imports | |
@@ -19,7 +11,6 b' from __future__ import print_function' | |||||
19 |
|
11 | |||
20 | # Standard library imports |
|
12 | # Standard library imports | |
21 | import atexit |
|
13 | import atexit | |
22 | import json |
|
|||
23 | import os |
|
14 | import os | |
24 | import sys |
|
15 | import sys | |
25 | import signal |
|
16 | import signal | |
@@ -39,15 +30,13 b' from IPython.core.shellapp import (' | |||||
39 | InteractiveShellApp, shell_flags, shell_aliases |
|
30 | InteractiveShellApp, shell_flags, shell_aliases | |
40 | ) |
|
31 | ) | |
41 | from IPython.utils import io |
|
32 | from IPython.utils import io | |
42 | from IPython.utils.localinterfaces import localhost |
|
|||
43 | from IPython.utils.path import filefind |
|
33 | from IPython.utils.path import filefind | |
44 | from IPython.utils.py3compat import str_to_bytes |
|
|||
45 | from IPython.utils.traitlets import ( |
|
34 | from IPython.utils.traitlets import ( | |
46 |
Any, Instance, Dict, Unicode, Integer, Bool, |
|
35 | Any, Instance, Dict, Unicode, Integer, Bool, DottedObjectName, | |
47 | DottedObjectName, |
|
|||
48 | ) |
|
36 | ) | |
49 | from IPython.utils.importstring import import_item |
|
37 | from IPython.utils.importstring import import_item | |
50 | from IPython.kernel import write_connection_file |
|
38 | from IPython.kernel import write_connection_file | |
|
39 | from IPython.kernel.connect import ConnectionFileMixin | |||
51 |
|
40 | |||
52 | # local imports |
|
41 | # local imports | |
53 | from .heartbeat import Heartbeat |
|
42 | from .heartbeat import Heartbeat | |
@@ -113,7 +102,8 b' To read more about this, see https://github.com/ipython/ipython/issues/2049' | |||||
113 | # Application class for starting an IPython Kernel |
|
102 | # Application class for starting an IPython Kernel | |
114 | #----------------------------------------------------------------------------- |
|
103 | #----------------------------------------------------------------------------- | |
115 |
|
104 | |||
116 |
class IPKernelApp(BaseIPythonApplication, InteractiveShellApp |
|
105 | class IPKernelApp(BaseIPythonApplication, InteractiveShellApp, | |
|
106 | ConnectionFileMixin): | |||
117 | name='ipkernel' |
|
107 | name='ipkernel' | |
118 | aliases = Dict(kernel_aliases) |
|
108 | aliases = Dict(kernel_aliases) | |
119 | flags = Dict(kernel_flags) |
|
109 | flags = Dict(kernel_flags) | |
@@ -146,30 +136,7 b' class IPKernelApp(BaseIPythonApplication, InteractiveShellApp):' | |||||
146 | self.config_file_specified.remove(self.config_file_name) |
|
136 | self.config_file_specified.remove(self.config_file_name) | |
147 |
|
137 | |||
148 | # connection info: |
|
138 | # connection info: | |
149 | transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True) |
|
|||
150 | ip = Unicode(config=True, |
|
|||
151 | help="Set the IP or interface on which the kernel will listen.") |
|
|||
152 | def _ip_default(self): |
|
|||
153 | if self.transport == 'ipc': |
|
|||
154 | if self.connection_file: |
|
|||
155 | return os.path.splitext(self.abs_connection_file)[0] + '-ipc' |
|
|||
156 | else: |
|
|||
157 | return 'kernel-ipc' |
|
|||
158 | else: |
|
|||
159 | return localhost() |
|
|||
160 |
|
||||
161 | hb_port = Integer(0, config=True, help="set the heartbeat port [default: random]") |
|
|||
162 | shell_port = Integer(0, config=True, help="set the shell (ROUTER) port [default: random]") |
|
|||
163 | iopub_port = Integer(0, config=True, help="set the iopub (PUB) port [default: random]") |
|
|||
164 | stdin_port = Integer(0, config=True, help="set the stdin (ROUTER) port [default: random]") |
|
|||
165 | control_port = Integer(0, config=True, help="set the control (ROUTER) port [default: random]") |
|
|||
166 | connection_file = Unicode('', config=True, |
|
|||
167 | help="""JSON file in which to store connection info [default: kernel-<pid>.json] |
|
|||
168 |
|
139 | |||
169 | This file will contain the IP, ports, and authentication key needed to connect |
|
|||
170 | clients to this kernel. By default, this file will be created in the security dir |
|
|||
171 | of the current profile, but can be specified by absolute path. |
|
|||
172 | """) |
|
|||
173 | @property |
|
140 | @property | |
174 | def abs_connection_file(self): |
|
141 | def abs_connection_file(self): | |
175 | if os.path.basename(self.connection_file) == self.connection_file: |
|
142 | if os.path.basename(self.connection_file) == self.connection_file: | |
@@ -227,31 +194,6 b' class IPKernelApp(BaseIPythonApplication, InteractiveShellApp):' | |||||
227 | s.bind("ipc://%s" % path) |
|
194 | s.bind("ipc://%s" % path) | |
228 | return port |
|
195 | return port | |
229 |
|
196 | |||
230 | def load_connection_file(self): |
|
|||
231 | """load ip/port/hmac config from JSON connection file""" |
|
|||
232 | try: |
|
|||
233 | fname = filefind(self.connection_file, ['.', self.profile_dir.security_dir]) |
|
|||
234 | except IOError: |
|
|||
235 | self.log.debug("Connection file not found: %s", self.connection_file) |
|
|||
236 | # This means I own it, so I will clean it up: |
|
|||
237 | atexit.register(self.cleanup_connection_file) |
|
|||
238 | return |
|
|||
239 | self.log.debug(u"Loading connection file %s", fname) |
|
|||
240 | with open(fname) as f: |
|
|||
241 | s = f.read() |
|
|||
242 | cfg = json.loads(s) |
|
|||
243 | self.transport = cfg.get('transport', self.transport) |
|
|||
244 | if self.ip == self._ip_default() and 'ip' in cfg: |
|
|||
245 | # not overridden by config or cl_args |
|
|||
246 | self.ip = cfg['ip'] |
|
|||
247 | for channel in ('hb', 'shell', 'iopub', 'stdin', 'control'): |
|
|||
248 | name = channel + '_port' |
|
|||
249 | if getattr(self, name) == 0 and name in cfg: |
|
|||
250 | # not overridden by config or cl_args |
|
|||
251 | setattr(self, name, cfg[name]) |
|
|||
252 | if 'key' in cfg: |
|
|||
253 | self.config.Session.key = str_to_bytes(cfg['key']) |
|
|||
254 |
|
||||
255 | def write_connection_file(self): |
|
197 | def write_connection_file(self): | |
256 | """write connection info to JSON file""" |
|
198 | """write connection info to JSON file""" | |
257 | cf = self.abs_connection_file |
|
199 | cf = self.abs_connection_file | |
@@ -270,21 +212,17 b' class IPKernelApp(BaseIPythonApplication, InteractiveShellApp):' | |||||
270 |
|
212 | |||
271 | self.cleanup_ipc_files() |
|
213 | self.cleanup_ipc_files() | |
272 |
|
214 | |||
273 | def cleanup_ipc_files(self): |
|
|||
274 | """cleanup ipc files if we wrote them""" |
|
|||
275 | if self.transport != 'ipc': |
|
|||
276 | return |
|
|||
277 | for port in (self.shell_port, self.iopub_port, self.stdin_port, self.hb_port, self.control_port): |
|
|||
278 | ipcfile = "%s-%i" % (self.ip, port) |
|
|||
279 | try: |
|
|||
280 | os.remove(ipcfile) |
|
|||
281 | except (IOError, OSError): |
|
|||
282 | pass |
|
|||
283 |
|
||||
284 | def init_connection_file(self): |
|
215 | def init_connection_file(self): | |
285 | if not self.connection_file: |
|
216 | if not self.connection_file: | |
286 | self.connection_file = "kernel-%s.json"%os.getpid() |
|
217 | self.connection_file = "kernel-%s.json"%os.getpid() | |
287 | try: |
|
218 | try: | |
|
219 | self.connection_file = filefind(self.connection_file, ['.', self.profile_dir.security_dir]) | |||
|
220 | except IOError: | |||
|
221 | self.log.debug("Connection file not found: %s", self.connection_file) | |||
|
222 | # This means I own it, so I will clean it up: | |||
|
223 | atexit.register(self.cleanup_connection_file) | |||
|
224 | return | |||
|
225 | try: | |||
288 | self.load_connection_file() |
|
226 | self.load_connection_file() | |
289 | except Exception: |
|
227 | except Exception: | |
290 | self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True) |
|
228 | self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True) |
General Comments 0
You need to be logged in to leave comments.
Login now