##// END OF EJS Templates
avoid executing code in utils.localinterfaces at import time...
MinRK -
Show More
@@ -53,7 +53,7 b' from IPython.kernel.connect import ConnectionFileMixin'
53 53 # Network Constants
54 54 #-----------------------------------------------------------------------------
55 55
56 from IPython.utils.localinterfaces import LOCALHOST
56 from IPython.utils.localinterfaces import localhost
57 57
58 58 #-----------------------------------------------------------------------------
59 59 # Globals
@@ -254,7 +254,7 b' class IPythonConsoleApp(ConnectionFileMixin):'
254 254 with open(fname) as f:
255 255 cfg = json.load(f)
256 256 self.transport = cfg.get('transport', 'tcp')
257 self.ip = cfg.get('ip', LOCALHOST)
257 self.ip = cfg.get('ip', localhost())
258 258
259 259 for channel in ('hb', 'shell', 'iopub', 'stdin', 'control'):
260 260 name = channel + '_port'
@@ -282,7 +282,7 b' class IPythonConsoleApp(ConnectionFileMixin):'
282 282 if self.sshkey and not self.sshserver:
283 283 # specifying just the key implies that we are connecting directly
284 284 self.sshserver = ip
285 ip = LOCALHOST
285 ip = localhost()
286 286
287 287 # build connection dict for tunnels:
288 288 info = dict(ip=ip,
@@ -295,7 +295,7 b' class IPythonConsoleApp(ConnectionFileMixin):'
295 295 self.log.info("Forwarding connections to %s via %s"%(ip, self.sshserver))
296 296
297 297 # tunnels return a new set of ports, which will be on localhost:
298 self.ip = LOCALHOST
298 self.ip = localhost()
299 299 try:
300 300 newports = tunnel_to_kernel(info, self.sshserver, self.sshkey)
301 301 except:
@@ -78,7 +78,7 b' from IPython.kernel.zmq.kernelapp import ('
78 78 kernel_aliases,
79 79 )
80 80 from IPython.utils.importstring import import_item
81 from IPython.utils.localinterfaces import LOCALHOST
81 from IPython.utils.localinterfaces import localhost
82 82 from IPython.utils import submodule
83 83 from IPython.utils.traitlets import (
84 84 Dict, Unicode, Integer, List, Bool, Bytes,
@@ -293,9 +293,11 b' class NotebookApp(BaseIPythonApplication):'
293 293
294 294 # Network related information.
295 295
296 ip = Unicode(LOCALHOST, config=True,
296 ip = Unicode(config=True,
297 297 help="The IP address the notebook server will listen on."
298 298 )
299 def _ip_default(self):
300 return localhost()
299 301
300 302 def _ip_changed(self, name, old, new):
301 303 if new == u'*': self.ip = u''
@@ -694,7 +696,7 b' class NotebookApp(BaseIPythonApplication):'
694 696 info("Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).")
695 697
696 698 if self.open_browser or self.file_to_run:
697 ip = self.ip or LOCALHOST
699 ip = self.ip or localhost()
698 700 try:
699 701 browser = webbrowser.get(self.browser or None)
700 702 except webbrowser.Error as e:
@@ -36,7 +36,7 b' from IPython.external.ssh import tunnel'
36 36 # IPython imports
37 37 from IPython.config import Configurable
38 38 from IPython.core.profiledir import ProfileDir
39 from IPython.utils.localinterfaces import LOCALHOST
39 from IPython.utils.localinterfaces import localhost
40 40 from IPython.utils.path import filefind, get_ipython_dir
41 41 from IPython.utils.py3compat import str_to_bytes, bytes_to_str
42 42 from IPython.utils.traitlets import (
@@ -49,7 +49,7 b' from IPython.utils.traitlets import ('
49 49 #-----------------------------------------------------------------------------
50 50
51 51 def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0,
52 control_port=0, ip=LOCALHOST, key=b'', transport='tcp',
52 control_port=0, ip='', key=b'', transport='tcp',
53 53 signature_scheme='hmac-sha256',
54 54 ):
55 55 """Generates a JSON config file, including the selection of random ports.
@@ -90,6 +90,8 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
90 90 and 'sha256' is the default hash function.
91 91
92 92 """
93 if not ip:
94 ip = localhost()
93 95 # default to temporary connector file
94 96 if not fname:
95 97 fname = tempfile.mktemp('.json')
@@ -391,7 +393,7 b' class ConnectionFileMixin(Configurable):'
391 393
392 394 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True)
393 395
394 ip = Unicode(LOCALHOST, config=True,
396 ip = Unicode(config=True,
395 397 help="""Set the kernel\'s IP address [default localhost].
396 398 If the IP address is something other than localhost, then
397 399 Consoles on other machines will be able to connect
@@ -405,7 +407,7 b' class ConnectionFileMixin(Configurable):'
405 407 else:
406 408 return 'kernel-ipc'
407 409 else:
408 return LOCALHOST
410 return localhost()
409 411
410 412 def _ip_changed(self, name, old, new):
411 413 if new == '*':
@@ -1,5 +1,4 b''
1 """Base class to manage a running kernel
2 """
1 """Base class to manage a running kernel"""
3 2
4 3 #-----------------------------------------------------------------------------
5 4 # Copyright (C) 2013 The IPython Development Team
@@ -24,7 +23,7 b' import zmq'
24 23 # Local imports
25 24 from IPython.config.configurable import LoggingConfigurable
26 25 from IPython.utils.importstring import import_item
27 from IPython.utils.localinterfaces import LOCAL_IPS
26 from IPython.utils.localinterfaces import is_local_ip, local_ips
28 27 from IPython.utils.traitlets import (
29 28 Any, Instance, Unicode, List, Bool, Type, DottedObjectName
30 29 )
@@ -185,11 +184,11 b' class KernelManager(LoggingConfigurable, ConnectionFileMixin):'
185 184 keyword arguments that are passed down to build the kernel_cmd
186 185 and launching the kernel (e.g. Popen kwargs).
187 186 """
188 if self.transport == 'tcp' and self.ip not in LOCAL_IPS:
187 if self.transport == 'tcp' and not is_local_ip(self.ip):
189 188 raise RuntimeError("Can only launch a kernel on a local interface. "
190 189 "Make sure that the '*_address' attributes are "
191 190 "configured properly. "
192 "Currently valid addresses are: %s"%LOCAL_IPS
191 "Currently valid addresses are: %s" % local_ips()
193 192 )
194 193
195 194 # write connection file / get default ports
@@ -7,7 +7,7 b' from unittest import TestCase'
7 7 from IPython.testing import decorators as dec
8 8
9 9 from IPython.config.loader import Config
10 from IPython.utils.localinterfaces import LOCALHOST
10 from IPython.utils.localinterfaces import localhost
11 11 from IPython.kernel import KernelManager
12 12 from IPython.kernel.multikernelmanager import MultiKernelManager
13 13
@@ -64,7 +64,7 b' class TestKernelManager(TestCase):'
64 64
65 65 def test_tcp_cinfo(self):
66 66 km = self._get_tcp_km()
67 self._run_cinfo(km, 'tcp', LOCALHOST)
67 self._run_cinfo(km, 'tcp', localhost())
68 68
69 69 @dec.skip_win32
70 70 def test_ipc_lifecycle(self):
@@ -19,7 +19,7 b' from threading import Thread'
19 19
20 20 import zmq
21 21
22 from IPython.utils.localinterfaces import LOCALHOST
22 from IPython.utils.localinterfaces import localhost
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Code
@@ -29,7 +29,9 b' from IPython.utils.localinterfaces import LOCALHOST'
29 29 class Heartbeat(Thread):
30 30 "A simple ping-pong style heartbeat that runs in a thread."
31 31
32 def __init__(self, context, addr=('tcp', LOCALHOST, 0)):
32 def __init__(self, context, addr=None):
33 if addr is None:
34 addr = ('tcp', localhost(), 0)
33 35 Thread.__init__(self)
34 36 self.context = context
35 37 self.transport, self.ip, self.port = addr
@@ -39,7 +39,7 b' from IPython.core.shellapp import ('
39 39 InteractiveShellApp, shell_flags, shell_aliases
40 40 )
41 41 from IPython.utils import io
42 from IPython.utils.localinterfaces import LOCALHOST
42 from IPython.utils.localinterfaces import localhost
43 43 from IPython.utils.path import filefind
44 44 from IPython.utils.py3compat import str_to_bytes
45 45 from IPython.utils.traitlets import (
@@ -156,7 +156,8 b' class IPKernelApp(BaseIPythonApplication, InteractiveShellApp):'
156 156 else:
157 157 return 'kernel-ipc'
158 158 else:
159 return LOCALHOST
159 return localhost()
160
160 161 hb_port = Integer(0, config=True, help="set the heartbeat port [default: random]")
161 162 shell_port = Integer(0, config=True, help="set the shell (ROUTER) port [default: random]")
162 163 iopub_port = Integer(0, config=True, help="set the iopub (PUB) port [default: random]")
@@ -11,7 +11,7 b' Authors:'
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
@@ -44,7 +44,7 b' from IPython.parallel.apps.baseapp import ('
44 44 catch_config_error,
45 45 )
46 46 from IPython.utils.importstring import import_item
47 from IPython.utils.localinterfaces import LOCALHOST, PUBLIC_IPS
47 from IPython.utils.localinterfaces import localhost, public_ips
48 48 from IPython.utils.traitlets import Instance, Unicode, Bool, List, Dict, TraitError
49 49
50 50 from IPython.kernel.zmq.session import (
@@ -224,13 +224,13 b' class IPControllerApp(BaseParallelApplication):'
224 224 location = cdict['location']
225 225
226 226 if not location:
227 if PUBLIC_IPS:
228 location = PUBLIC_IPS[-1]
227 if public_ips():
228 location = public_ips()[-1]
229 229 else:
230 230 self.log.warn("Could not identify this machine's IP, assuming %s."
231 231 " You may need to specify '--location=<external_ip_address>' to help"
232 " IPython decide when to connect via loopback." % LOCALHOST)
233 location = LOCALHOST
232 " IPython decide when to connect via loopback." % localhost() )
233 location = localhost()
234 234 cdict['location'] = location
235 235 fname = os.path.join(self.profile_dir.security_dir, fname)
236 236 self.log.info("writing connection info to %s", fname)
@@ -26,7 +26,7 b' import zmq'
26 26 from zmq.eventloop import ioloop, zmqstream
27 27
28 28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.utils.localinterfaces import LOCALHOST
29 from IPython.utils.localinterfaces import localhost
30 30 from IPython.utils.traitlets import Int, Unicode, Instance, List
31 31
32 32 #-----------------------------------------------------------------------------
@@ -44,8 +44,10 b' class LogWatcher(LoggingConfigurable):'
44 44 # configurables
45 45 topics = List([''], config=True,
46 46 help="The ZMQ topics to subscribe to. Default is to subscribe to all messages")
47 url = Unicode('tcp://%s:20202' % LOCALHOST, config=True,
47 url = Unicode(config=True,
48 48 help="ZMQ url on which to listen for log messages")
49 def _url_default(self):
50 return 'tcp://%s:20202' % localhost()
49 51
50 52 # internals
51 53 stream = Instance('zmq.eventloop.zmqstream.ZMQStream')
@@ -37,7 +37,7 b' from IPython.core.profiledir import ProfileDir, ProfileDirError'
37 37 from IPython.utils.capture import RichOutput
38 38 from IPython.utils.coloransi import TermColors
39 39 from IPython.utils.jsonutil import rekey
40 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
40 from IPython.utils.localinterfaces import localhost, is_local_ip
41 41 from IPython.utils.path import get_ipython_dir
42 42 from IPython.utils.py3compat import cast_bytes
43 43 from IPython.utils.traitlets import (HasTraits, Integer, Instance, Unicode,
@@ -433,13 +433,13 b' class Client(HasTraits):'
433 433
434 434 url = cfg['registration']
435 435
436 if location is not None and addr == LOCALHOST:
436 if location is not None and addr == localhost():
437 437 # location specified, and connection is expected to be local
438 if location not in LOCAL_IPS and not sshserver:
438 if not is_local_ip(location) and not sshserver:
439 439 # load ssh from JSON *only* if the controller is not on
440 440 # this machine
441 441 sshserver=cfg['ssh']
442 if location not in LOCAL_IPS and not sshserver:
442 if not is_local_ip(location) and not sshserver:
443 443 # warn if no ssh specified, but SSH is probably needed
444 444 # This is only a warning, because the most likely cause
445 445 # is a local Controller on a laptop whose IP is dynamic
@@ -30,7 +30,7 b' from zmq.eventloop.zmqstream import ZMQStream'
30 30
31 31 # internal:
32 32 from IPython.utils.importstring import import_item
33 from IPython.utils.localinterfaces import LOCALHOST
33 from IPython.utils.localinterfaces import localhost
34 34 from IPython.utils.py3compat import cast_bytes
35 35 from IPython.utils.traitlets import (
36 36 HasTraits, Instance, Integer, Unicode, Dict, Set, Tuple, CBytes, DottedObjectName
@@ -177,21 +177,26 b' class HubFactory(RegistrationFactory):'
177 177 def _notifier_port_default(self):
178 178 return util.select_random_ports(1)[0]
179 179
180 engine_ip = Unicode(LOCALHOST, config=True,
180 engine_ip = Unicode(config=True,
181 181 help="IP on which to listen for engine connections. [default: loopback]")
182 def _engine_ip_default(self):
183 return localhost()
182 184 engine_transport = Unicode('tcp', config=True,
183 185 help="0MQ transport for engine connections. [default: tcp]")
184 186
185 client_ip = Unicode(LOCALHOST, config=True,
187 client_ip = Unicode(config=True,
186 188 help="IP on which to listen for client connections. [default: loopback]")
187 189 client_transport = Unicode('tcp', config=True,
188 190 help="0MQ transport for client connections. [default : tcp]")
189 191
190 monitor_ip = Unicode(LOCALHOST, config=True,
192 monitor_ip = Unicode(config=True,
191 193 help="IP on which to listen for monitor messages. [default: loopback]")
192 194 monitor_transport = Unicode('tcp', config=True,
193 195 help="0MQ transport for monitor messages. [default : tcp]")
194 196
197 _client_ip_default = _monitor_ip_default = _engine_ip_default
198
199
195 200 monitor_url = Unicode('')
196 201
197 202 db_class = DottedObjectName('NoDB',
@@ -24,7 +24,7 b' from zmq.eventloop import ioloop, zmqstream'
24 24
25 25 from IPython.external.ssh import tunnel
26 26 # internal
27 from IPython.utils.localinterfaces import LOCALHOST
27 from IPython.utils.localinterfaces import localhost
28 28 from IPython.utils.traitlets import (
29 29 Instance, Dict, Integer, Type, Float, Integer, Unicode, CBytes, Bool
30 30 )
@@ -184,13 +184,13 b' class EngineFactory(RegistrationFactory):'
184 184 if self.max_heartbeat_misses > 0:
185 185 # Add a monitor socket which will record the last time a ping was seen
186 186 mon = self.context.socket(zmq.SUB)
187 mport = mon.bind_to_random_port('tcp://%s' % LOCALHOST)
187 mport = mon.bind_to_random_port('tcp://%s' % localhost())
188 188 mon.setsockopt(zmq.SUBSCRIBE, b"")
189 189 self._hb_listener = zmqstream.ZMQStream(mon, self.loop)
190 190 self._hb_listener.on_recv(self._report_ping)
191 191
192 192
193 hb_monitor = "tcp://%s:%i" % (LOCALHOST, mport)
193 hb_monitor = "tcp://%s:%i" % (localhost(), mport)
194 194
195 195 heart = Heart(hb_ping, hb_pong, hb_monitor , heart_id=identity)
196 196 heart.start()
@@ -24,7 +24,7 b' import zmq'
24 24 from zmq.eventloop.ioloop import IOLoop
25 25
26 26 from IPython.config.configurable import Configurable
27 from IPython.utils.localinterfaces import LOCALHOST
27 from IPython.utils.localinterfaces import localhost
28 28 from IPython.utils.traitlets import Integer, Instance, Unicode
29 29
30 30 from IPython.parallel.util import select_random_ports
@@ -40,16 +40,18 b' class RegistrationFactory(SessionFactory):'
40 40
41 41 url = Unicode('', config=True,
42 42 help="""The 0MQ url used for registration. This sets transport, ip, and port
43 in one variable. For example: url='tcp://%s:12345' or
43 in one variable. For example: url='tcp://127.0.0.1:12345' or
44 44 url='epgm://*:90210'"""
45 % LOCALHOST) # url takes precedence over ip,regport,transport
45 ) # url takes precedence over ip,regport,transport
46 46 transport = Unicode('tcp', config=True,
47 47 help="""The 0MQ transport for communications. This will likely be
48 48 the default of 'tcp', but other values include 'ipc', 'epgm', 'inproc'.""")
49 ip = Unicode(LOCALHOST, config=True,
49 ip = Unicode(config=True,
50 50 help="""The IP address for registration. This is generally either
51 51 '127.0.0.1' for loopback only or '*' for all interfaces.
52 [default: '%s']""" % LOCALHOST)
52 """)
53 def _ip_default(self):
54 return localhost()
53 55 regport = Integer(config=True,
54 56 help="""The port on which the Hub listens for registration.""")
55 57 def _regport_default(self):
@@ -43,7 +43,7 b' from IPython.external.decorator import decorator'
43 43
44 44 # IPython imports
45 45 from IPython.config.application import Application
46 from IPython.utils.localinterfaces import LOCALHOST, PUBLIC_IPS
46 from IPython.utils.localinterfaces import localhost, is_public_ip, public_ips
47 47 from IPython.kernel.zmq.log import EnginePUBHandler
48 48 from IPython.kernel.zmq.serialize import (
49 49 unserialize_object, serialize_object, pack_apply_message, unpack_apply_message
@@ -187,9 +187,9 b' def disambiguate_ip_address(ip, location=None):'
187 187 """turn multi-ip interfaces '0.0.0.0' and '*' into connectable
188 188 ones, based on the location (default interpretation of location is localhost)."""
189 189 if ip in ('0.0.0.0', '*'):
190 if location is None or location in PUBLIC_IPS or not PUBLIC_IPS:
190 if location is None or is_public_ip(location) or not public_ips():
191 191 # If location is unspecified or cannot be determined, assume local
192 ip = LOCALHOST
192 ip = localhost()
193 193 elif location:
194 194 return location
195 195 return ip
@@ -74,7 +74,7 b' from IPython.consoleapp import ('
74 74 # Network Constants
75 75 #-----------------------------------------------------------------------------
76 76
77 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
77 from IPython.utils.localinterfaces import is_local_ip
78 78
79 79 #-----------------------------------------------------------------------------
80 80 # Globals
@@ -250,7 +250,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):'
250 250 QtGui.QApplication.setWindowIcon(self.app.icon)
251 251
252 252 ip = self.ip
253 local_kernel = (not self.existing) or ip in LOCAL_IPS
253 local_kernel = (not self.existing) or is_local_ip(ip)
254 254 self.widget = self.widget_factory(config=self.config,
255 255 local_kernel=local_kernel)
256 256 self.init_colors(self.widget)
@@ -29,27 +29,80 b' from .data import uniq_stable'
29 29 #-----------------------------------------------------------------------------
30 30
31 31 LOCAL_IPS = []
32 PUBLIC_IPS = []
33
34 LOCALHOST = '127.0.0.1'
35
36 def _only_once(f):
37 """decorator to only run a function once"""
38 f.called = False
39 def wrapped():
40 if f.called:
41 return
42 ret = f()
43 f.called = True
44 return ret
45 return wrapped
46
47 def _requires_ips(f):
48 """decorator to ensure load_ips has been run before f"""
49 def ips_loaded(*args, **kwargs):
50 _load_ips()
51 return f(*args, **kwargs)
52 return ips_loaded
53
54 @_only_once
55 def _load_ips():
56 """load the IPs that point to this machine
57
58 This function will only ever be called once.
59 """
60 global LOCALHOST
32 61 try:
33 LOCAL_IPS = socket.gethostbyname_ex('localhost')[2]
62 LOCAL_IPS[:] = socket.gethostbyname_ex('localhost')[2]
34 63 except socket.error:
35 64 pass
36 65
37 PUBLIC_IPS = []
38 66 try:
39 67 hostname = socket.gethostname()
40 PUBLIC_IPS = socket.gethostbyname_ex(hostname)[2]
68 PUBLIC_IPS[:] = socket.gethostbyname_ex(hostname)[2]
41 69 # try hostname.local, in case hostname has been short-circuited to loopback
42 70 if not hostname.endswith('.local') and all(ip.startswith('127') for ip in PUBLIC_IPS):
43 PUBLIC_IPS = socket.gethostbyname_ex(socket.gethostname() + '.local')[2]
71 PUBLIC_IPS[:] = socket.gethostbyname_ex(socket.gethostname() + '.local')[2]
44 72 except socket.error:
45 73 pass
46 74 finally:
47 PUBLIC_IPS = uniq_stable(PUBLIC_IPS)
75 PUBLIC_IPS[:] = uniq_stable(PUBLIC_IPS)
48 76 LOCAL_IPS.extend(PUBLIC_IPS)
49 77
50 78 # include all-interface aliases: 0.0.0.0 and ''
51 79 LOCAL_IPS.extend(['0.0.0.0', ''])
52 80
53 LOCAL_IPS = uniq_stable(LOCAL_IPS)
81 LOCAL_IPS[:] = uniq_stable(LOCAL_IPS)
54 82
55 83 LOCALHOST = LOCAL_IPS[0]
84
85 @_requires_ips
86 def local_ips():
87 """return the IP addresses that point to this machine"""
88 return LOCAL_IPS
89
90 @_requires_ips
91 def public_ips():
92 """return the IP addresses for this machine that are visible to other machines"""
93 return PUBLIC_IPS
94
95 @_requires_ips
96 def localhost():
97 """return ip for localhost (almost always 127.0.0.1)"""
98 return LOCALHOST
99
100 @_requires_ips
101 def is_local_ip(ip):
102 """does `ip` point to this machine?"""
103 return ip in LOCAL_IPS
104
105 @_requires_ips
106 def is_public_ip(ip):
107 """is `ip` a publicly visible address?"""
108 return ip in PUBLIC_IPS
General Comments 0
You need to be logged in to leave comments. Login now