##// END OF EJS Templates
Merge pull request #2811 from minrk/ipc_defaults...
Min RK -
r9245:8c1236c4 merge
parent child Browse files
Show More
@@ -88,11 +88,12 b' aliases = dict(ipkernel_aliases)'
88 88
89 89 # also scrub aliases from the frontend
90 90 app_aliases = dict(
91 ip = 'KernelManager.ip',
92 transport = 'KernelManager.transport',
91 93 hb = 'IPythonConsoleApp.hb_port',
92 94 shell = 'IPythonConsoleApp.shell_port',
93 95 iopub = 'IPythonConsoleApp.iopub_port',
94 96 stdin = 'IPythonConsoleApp.stdin_port',
95 ip = 'IPythonConsoleApp.ip',
96 97 existing = 'IPythonConsoleApp.existing',
97 98 f = 'IPythonConsoleApp.connection_file',
98 99
@@ -153,27 +154,6 b' class IPythonConsoleApp(Configurable):'
153 154 auto_create = CBool(True)
154 155 # connection info:
155 156
156 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True)
157
158 ip = Unicode(config=True,
159 help="""Set the kernel\'s IP address [default localhost].
160 If the IP address is something other than localhost, then
161 Consoles on other machines will be able to connect
162 to the Kernel, so be careful!"""
163 )
164 def _ip_default(self):
165 if self.transport == 'tcp':
166 return LOCALHOST
167 else:
168 # this can fire early if ip is given,
169 # in which case our return value is meaningless
170 if not hasattr(self, 'profile_dir'):
171 return ''
172 ipcdir = os.path.join(self.profile_dir.security_dir, 'kernel-%s' % os.getpid())
173 os.makedirs(ipcdir)
174 atexit.register(lambda : shutil.rmtree(ipcdir))
175 return os.path.join(ipcdir, 'ipc')
176
177 157 sshserver = Unicode('', config=True,
178 158 help="""The SSH server to use to connect to the kernel.""")
179 159 sshkey = Unicode('', config=True,
@@ -274,9 +254,9 b' class IPythonConsoleApp(Configurable):'
274 254 with open(fname) as f:
275 255 cfg = json.load(f)
276 256
277 self.transport = cfg.get('transport', 'tcp')
278 if 'ip' in cfg:
279 self.ip = cfg['ip']
257 self.config.KernelManager.transport = cfg.get('transport', 'tcp')
258 self.config.KernelManager.ip = cfg.get('ip', LOCALHOST)
259
280 260 for channel in ('hb', 'shell', 'iopub', 'stdin'):
281 261 name = channel + '_port'
282 262 if getattr(self, name) == 0 and name in cfg:
@@ -284,34 +264,38 b' class IPythonConsoleApp(Configurable):'
284 264 setattr(self, name, cfg[name])
285 265 if 'key' in cfg:
286 266 self.config.Session.key = str_to_bytes(cfg['key'])
287
288 267
289 268 def init_ssh(self):
290 269 """set up ssh tunnels, if needed."""
291 if not self.sshserver and not self.sshkey:
270 if not self.existing or (not self.sshserver and not self.sshkey):
292 271 return
293 272
294 if self.transport != 'tcp':
295 self.log.error("Can only use ssh tunnels with TCP sockets, not %s", self.transport)
296 return
273 self.load_connection_file()
274
275 transport = self.config.KernelManager.transport
276 ip = self.config.KernelManager.ip
277
278 if transport != 'tcp':
279 self.log.error("Can only use ssh tunnels with TCP sockets, not %s", transport)
280 sys.exit(-1)
297 281
298 282 if self.sshkey and not self.sshserver:
299 283 # specifying just the key implies that we are connecting directly
300 self.sshserver = self.ip
301 self.ip = LOCALHOST
284 self.sshserver = ip
285 ip = LOCALHOST
302 286
303 287 # build connection dict for tunnels:
304 info = dict(ip=self.ip,
288 info = dict(ip=ip,
305 289 shell_port=self.shell_port,
306 290 iopub_port=self.iopub_port,
307 291 stdin_port=self.stdin_port,
308 292 hb_port=self.hb_port
309 293 )
310 294
311 self.log.info("Forwarding connections to %s via %s"%(self.ip, self.sshserver))
295 self.log.info("Forwarding connections to %s via %s"%(ip, self.sshserver))
312 296
313 297 # tunnels return a new set of ports, which will be on localhost:
314 self.ip = LOCALHOST
298 self.config.KernelManager.ip = LOCALHOST
315 299 try:
316 300 newports = tunnel_to_kernel(info, self.sshserver, self.sshkey)
317 301 except:
@@ -347,8 +331,6 b' class IPythonConsoleApp(Configurable):'
347 331
348 332 # Create a KernelManager and start a kernel.
349 333 self.kernel_manager = self.kernel_manager_class(
350 transport=self.transport,
351 ip=self.ip,
352 334 shell_port=self.shell_port,
353 335 iopub_port=self.iopub_port,
354 336 stdin_port=self.stdin_port,
@@ -359,6 +341,7 b' class IPythonConsoleApp(Configurable):'
359 341 # start the kernel
360 342 if not self.existing:
361 343 self.kernel_manager.start_kernel(extra_arguments=self.kernel_argv)
344 atexit.register(self.kernel_manager.cleanup_ipc_files)
362 345 elif self.sshserver:
363 346 # ssh, write new connection file
364 347 self.kernel_manager.write_connection_file()
@@ -242,6 +242,7 b' aliases.update({'
242 242 'ip': 'NotebookApp.ip',
243 243 'port': 'NotebookApp.port',
244 244 'port-retries': 'NotebookApp.port_retries',
245 'transport': 'KernelManager.transport',
245 246 'keyfile': 'NotebookApp.keyfile',
246 247 'certfile': 'NotebookApp.certfile',
247 248 'notebook-dir': 'NotebookManager.notebook_dir',
@@ -193,9 +193,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):'
193 193 def new_frontend_master(self):
194 194 """ Create and return new frontend attached to new kernel, launched on localhost.
195 195 """
196 ip = self.ip if self.ip in LOCAL_IPS else LOCALHOST
197 196 kernel_manager = self.kernel_manager_class(
198 ip=ip,
199 197 connection_file=self._new_connection_file(),
200 198 config=self.config,
201 199 )
@@ -245,7 +243,11 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):'
245 243 self.app.icon = QtGui.QIcon(icon_path)
246 244 QtGui.QApplication.setWindowIcon(self.app.icon)
247 245
248 local_kernel = (not self.existing) or self.ip in LOCAL_IPS
246 try:
247 ip = self.config.KernelManager.ip
248 except AttributeError:
249 ip = LOCALHOST
250 local_kernel = (not self.existing) or ip in LOCAL_IPS
249 251 self.widget = self.widget_factory(config=self.config,
250 252 local_kernel=local_kernel)
251 253 self.init_colors(self.widget)
@@ -41,7 +41,8 b' class Heartbeat(Thread):'
41 41 self.port = s.getsockname()[1]
42 42 s.close()
43 43 elif addr[0] == 'ipc':
44 while os.path.exists(self.ip + '-' + self.port):
44 self.port = 1
45 while os.path.exists("%s-%s" % (self.ip, self.port)):
45 46 self.port = self.port + 1
46 47 else:
47 48 raise ValueError("Unrecognized zmq transport: %s" % addr[0])
@@ -62,6 +62,7 b' kernel_aliases.update({'
62 62 'stdin' : 'KernelApp.stdin_port',
63 63 'f' : 'KernelApp.connection_file',
64 64 'parent': 'KernelApp.parent',
65 'transport': 'KernelApp.transport',
65 66 })
66 67 if sys.platform.startswith('win'):
67 68 kernel_aliases['interrupt'] = 'KernelApp.interrupt'
@@ -98,7 +99,6 b' class KernelApp(BaseIPythonApplication):'
98 99 heartbeat = Instance(Heartbeat)
99 100 session = Instance('IPython.zmq.session.Session')
100 101 ports = Dict()
101 _full_connection_file = Unicode()
102 102
103 103 # inherit config file name from parent:
104 104 parent_appname = Unicode(config=True)
@@ -112,8 +112,16 b' class KernelApp(BaseIPythonApplication):'
112 112
113 113 # connection info:
114 114 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True)
115 ip = Unicode(LOCALHOST, config=True,
115 ip = Unicode(config=True,
116 116 help="Set the IP or interface on which the kernel will listen.")
117 def _ip_default(self):
118 if self.transport == 'ipc':
119 if self.connection_file:
120 return os.path.splitext(self.abs_connection_file)[0] + '-ipc'
121 else:
122 return 'kernel-ipc'
123 else:
124 return LOCALHOST
117 125 hb_port = Integer(0, config=True, help="set the heartbeat port [default: random]")
118 126 shell_port = Integer(0, config=True, help="set the shell (ROUTER) port [default: random]")
119 127 iopub_port = Integer(0, config=True, help="set the iopub (PUB) port [default: random]")
@@ -122,9 +130,16 b' class KernelApp(BaseIPythonApplication):'
122 130 help="""JSON file in which to store connection info [default: kernel-<pid>.json]
123 131
124 132 This file will contain the IP, ports, and authentication key needed to connect
125 clients to this kernel. By default, this file will be created in the security-dir
133 clients to this kernel. By default, this file will be created in the security dir
126 134 of the current profile, but can be specified by absolute path.
127 135 """)
136 @property
137 def abs_connection_file(self):
138 if os.path.basename(self.connection_file) == self.connection_file:
139 return os.path.join(self.profile_dir.security_dir, self.connection_file)
140 else:
141 return self.connection_file
142
128 143
129 144 # streams, etc.
130 145 no_stdout = Bool(False, config=True, help="redirect stdout to the null device")
@@ -141,7 +156,7 b' class KernelApp(BaseIPythonApplication):'
141 156 """)
142 157 interrupt = Integer(0, config=True,
143 158 help="""ONLY USED ON WINDOWS
144 Interrupt this process when the parent is signalled.
159 Interrupt this process when the parent is signaled.
145 160 """)
146 161
147 162 def init_crash_handler(self):
@@ -158,11 +173,21 b' class KernelApp(BaseIPythonApplication):'
158 173
159 174 def _bind_socket(self, s, port):
160 175 iface = '%s://%s' % (self.transport, self.ip)
161 if port <= 0 and self.transport == 'tcp':
162 port = s.bind_to_random_port(iface)
163 else:
164 c = ':' if self.transport == 'tcp' else '-'
165 s.bind(iface + c + str(port))
176 if self.transport == 'tcp':
177 if port <= 0:
178 port = s.bind_to_random_port(iface)
179 else:
180 s.bind("tcp://%s:%i" % (self.ip, port))
181 elif self.transport == 'ipc':
182 if port <= 0:
183 port = 1
184 path = "%s-%i" % (self.ip, port)
185 while os.path.exists(path):
186 port = port + 1
187 path = "%s-%i" % (self.ip, port)
188 else:
189 path = "%s-%i" % (self.ip, port)
190 s.bind("ipc://%s" % path)
166 191 return port
167 192
168 193 def load_connection_file(self):
@@ -179,7 +204,7 b' class KernelApp(BaseIPythonApplication):'
179 204 s = f.read()
180 205 cfg = json.loads(s)
181 206 self.transport = cfg.get('transport', self.transport)
182 if self.ip == LOCALHOST and 'ip' in cfg:
207 if self.ip == self._ip_default() and 'ip' in cfg:
183 208 # not overridden by config or cl_args
184 209 self.ip = cfg['ip']
185 210 for channel in ('hb', 'shell', 'iopub', 'stdin'):
@@ -192,19 +217,15 b' class KernelApp(BaseIPythonApplication):'
192 217
193 218 def write_connection_file(self):
194 219 """write connection info to JSON file"""
195 if os.path.basename(self.connection_file) == self.connection_file:
196 cf = os.path.join(self.profile_dir.security_dir, self.connection_file)
197 else:
198 cf = self.connection_file
220 cf = self.abs_connection_file
221 self.log.debug("Writing connection file: %s", cf)
199 222 write_connection_file(cf, ip=self.ip, key=self.session.key, transport=self.transport,
200 223 shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port,
201 224 iopub_port=self.iopub_port)
202
203 self._full_connection_file = cf
204 225
205 226 def cleanup_connection_file(self):
206 cf = self._full_connection_file
207 self.log.debug("cleaning up connection file: %r", cf)
227 cf = self.abs_connection_file
228 self.log.debug("Cleaning up connection file: %s", cf)
208 229 try:
209 230 os.remove(cf)
210 231 except (IOError, OSError):
@@ -684,7 +684,20 b' class KernelManager(Configurable):'
684 684
685 685 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True)
686 686
687 ip = Unicode(LOCALHOST, config=True)
687 ip = Unicode(LOCALHOST, config=True,
688 help="""Set the kernel\'s IP address [default localhost].
689 If the IP address is something other than localhost, then
690 Consoles on other machines will be able to connect
691 to the Kernel, so be careful!"""
692 )
693 def _ip_default(self):
694 if self.transport == 'ipc':
695 if self.connection_file:
696 return os.path.splitext(self.connection_file)[0] + '-ipc'
697 else:
698 return 'kernel-ipc'
699 else:
700 return LOCALHOST
688 701 def _ip_changed(self, name, old, new):
689 702 if new == '*':
690 703 self.ip = '0.0.0.0'
@@ -706,8 +719,8 b' class KernelManager(Configurable):'
706 719 _stdin_channel = Any
707 720 _hb_channel = Any
708 721 _connection_file_written=Bool(False)
709
710 def __del__(self):
722
723 def __del__(self):
711 724 self.cleanup_connection_file()
712 725
713 726 #--------------------------------------------------------------------------
General Comments 0
You need to be logged in to leave comments. Login now