##// END OF EJS Templates
Merge pull request #5760 from ivanov/connection-mixin...
Min RK -
r16508:3403b188 merge
parent child Browse files
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, Int, CBool, Any
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 shell_port = Integer(0)
422 hb_port = Integer(0, config=True,
423 iopub_port = Integer(0)
423 help="set the heartbeat port [default: random]")
424 stdin_port = Integer(0)
424 shell_port = Integer(0, config=True,
425 control_port = Integer(0)
425 help="set the shell (ROUTER) port [default: random]")
426 hb_port = Integer(0)
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.loads(f.read())
501 cfg = json.load(f)
496
502 self.transport = cfg.get('transport', self.transport)
497 self.transport = cfg.get('transport', 'tcp')
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 setattr(self, name, cfg[name])
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.session.key = str_to_bytes(cfg['key'])
510 self.config.Session.key = str_to_bytes(cfg['key'])
503 if cfg.get('signature_scheme'):
511 if 'signature_scheme' in cfg:
504 self.session.signature_scheme = cfg['signature_scheme']
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, CaselessStrEnum,
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