mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-12 20:43:02 +00:00
support kubespawner running on a IPv6 only cluster
This commit is contained in:
@@ -561,7 +561,11 @@ class JupyterHub(Application):
|
|||||||
def _url_part_changed(self, change):
|
def _url_part_changed(self, change):
|
||||||
"""propagate deprecated ip/port/base_url config to the bind_url"""
|
"""propagate deprecated ip/port/base_url config to the bind_url"""
|
||||||
urlinfo = urlparse(self.bind_url)
|
urlinfo = urlparse(self.bind_url)
|
||||||
urlinfo = urlinfo._replace(netloc='%s:%i' % (self.ip, self.port))
|
if ':' in self.ip:
|
||||||
|
fmt = '[%s]:%i'
|
||||||
|
else:
|
||||||
|
fmt = '%s:%i'
|
||||||
|
urlinfo = urlinfo._replace(netloc=fmt % (self.ip, self.port))
|
||||||
urlinfo = urlinfo._replace(path=self.base_url)
|
urlinfo = urlinfo._replace(path=self.base_url)
|
||||||
bind_url = urlunparse(urlinfo)
|
bind_url = urlunparse(urlinfo)
|
||||||
if bind_url != self.bind_url:
|
if bind_url != self.bind_url:
|
||||||
@@ -727,10 +731,10 @@ class JupyterHub(Application):
|
|||||||
help="""The ip or hostname for proxies and spawners to use
|
help="""The ip or hostname for proxies and spawners to use
|
||||||
for connecting to the Hub.
|
for connecting to the Hub.
|
||||||
|
|
||||||
Use when the bind address (`hub_ip`) is 0.0.0.0 or otherwise different
|
Use when the bind address (`hub_ip`) is 0.0.0.0, :: or otherwise different
|
||||||
from the connect address.
|
from the connect address.
|
||||||
|
|
||||||
Default: when `hub_ip` is 0.0.0.0, use `socket.gethostname()`, otherwise use `hub_ip`.
|
Default: when `hub_ip` is 0.0.0.0 or ::, use `socket.gethostname()`, otherwise use `hub_ip`.
|
||||||
|
|
||||||
Note: Some spawners or proxy implementations might not support hostnames. Check your
|
Note: Some spawners or proxy implementations might not support hostnames. Check your
|
||||||
spawner or proxy documentation to see if they have extra requirements.
|
spawner or proxy documentation to see if they have extra requirements.
|
||||||
|
@@ -53,7 +53,7 @@ class Server(HasTraits):
|
|||||||
Never used in APIs, only logging,
|
Never used in APIs, only logging,
|
||||||
since it can be non-connectable value, such as '', meaning all interfaces.
|
since it can be non-connectable value, such as '', meaning all interfaces.
|
||||||
"""
|
"""
|
||||||
if self.ip in {'', '0.0.0.0'}:
|
if self.ip in {'', '0.0.0.0', '::'}:
|
||||||
return self.url.replace(self._connect_ip, self.ip or '*', 1)
|
return self.url.replace(self._connect_ip, self.ip or '*', 1)
|
||||||
return self.url
|
return self.url
|
||||||
|
|
||||||
@@ -87,13 +87,13 @@ class Server(HasTraits):
|
|||||||
"""The address to use when connecting to this server
|
"""The address to use when connecting to this server
|
||||||
|
|
||||||
When `ip` is set to a real ip address, the same value is used.
|
When `ip` is set to a real ip address, the same value is used.
|
||||||
When `ip` refers to 'all interfaces' (e.g. '0.0.0.0'),
|
When `ip` refers to 'all interfaces' (e.g. '0.0.0.0' or '::'),
|
||||||
clients connect via hostname by default.
|
clients connect via hostname by default.
|
||||||
Setting `connect_ip` explicitly overrides any default behavior.
|
Setting `connect_ip` explicitly overrides any default behavior.
|
||||||
"""
|
"""
|
||||||
if self.connect_ip:
|
if self.connect_ip:
|
||||||
return self.connect_ip
|
return self.connect_ip
|
||||||
elif self.ip in {'', '0.0.0.0'}:
|
elif self.ip in {'', '0.0.0.0', '::'}:
|
||||||
# if listening on all interfaces, default to hostname for connect
|
# if listening on all interfaces, default to hostname for connect
|
||||||
return socket.gethostname()
|
return socket.gethostname()
|
||||||
else:
|
else:
|
||||||
@@ -149,7 +149,12 @@ class Server(HasTraits):
|
|||||||
if self.connect_url:
|
if self.connect_url:
|
||||||
parsed = urlparse(self.connect_url)
|
parsed = urlparse(self.connect_url)
|
||||||
return "{proto}://{host}".format(proto=parsed.scheme, host=parsed.netloc)
|
return "{proto}://{host}".format(proto=parsed.scheme, host=parsed.netloc)
|
||||||
return "{proto}://{ip}:{port}".format(
|
|
||||||
|
if ':' in self._connect_ip:
|
||||||
|
fmt = "{proto}://[{ip}]:{port}"
|
||||||
|
else:
|
||||||
|
fmt = "{proto}://{ip}:{port}"
|
||||||
|
return fmt.format(
|
||||||
proto=self.proto, ip=self._connect_ip, port=self._connect_port
|
proto=self.proto, ip=self._connect_ip, port=self._connect_port
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -342,7 +342,7 @@ class Service(LoggingConfigurable):
|
|||||||
env['JUPYTERHUB_SERVICE_PREFIX'] = self.server.base_url
|
env['JUPYTERHUB_SERVICE_PREFIX'] = self.server.base_url
|
||||||
|
|
||||||
hub = self.hub
|
hub = self.hub
|
||||||
if self.hub.ip in ('0.0.0.0', ''):
|
if self.hub.ip in ('', '0.0.0.0', '::'):
|
||||||
# if the Hub is listening on all interfaces,
|
# if the Hub is listening on all interfaces,
|
||||||
# tell services to connect via localhost
|
# tell services to connect via localhost
|
||||||
# since they are always local subprocesses
|
# since they are always local subprocesses
|
||||||
|
@@ -566,7 +566,12 @@ class User:
|
|||||||
else:
|
else:
|
||||||
# >= 0.7 returns (ip, port)
|
# >= 0.7 returns (ip, port)
|
||||||
proto = 'https' if self.settings['internal_ssl'] else 'http'
|
proto = 'https' if self.settings['internal_ssl'] else 'http'
|
||||||
url = '%s://%s:%i' % ((proto,) + url)
|
|
||||||
|
# check if spawner returned an IPv6 address
|
||||||
|
if ':' in url[0]:
|
||||||
|
url = '%s://[%s]:%i' % ((proto,) + url)
|
||||||
|
else:
|
||||||
|
url = '%s://%s:%i' % ((proto,) + url)
|
||||||
urlinfo = urlparse(url)
|
urlinfo = urlparse(url)
|
||||||
server.proto = urlinfo.scheme
|
server.proto = urlinfo.scheme
|
||||||
server.ip = urlinfo.hostname
|
server.ip = urlinfo.hostname
|
||||||
|
@@ -66,7 +66,7 @@ def can_connect(ip, port):
|
|||||||
|
|
||||||
Return True if we can connect, False otherwise.
|
Return True if we can connect, False otherwise.
|
||||||
"""
|
"""
|
||||||
if ip in {'', '0.0.0.0'}:
|
if ip in {'', '0.0.0.0', '::'}:
|
||||||
ip = '127.0.0.1'
|
ip = '127.0.0.1'
|
||||||
try:
|
try:
|
||||||
socket.create_connection((ip, port)).close()
|
socket.create_connection((ip, port)).close()
|
||||||
@@ -179,7 +179,7 @@ async def exponential_backoff(
|
|||||||
|
|
||||||
async def wait_for_server(ip, port, timeout=10):
|
async def wait_for_server(ip, port, timeout=10):
|
||||||
"""Wait for any server to show up at ip:port."""
|
"""Wait for any server to show up at ip:port."""
|
||||||
if ip in {'', '0.0.0.0'}:
|
if ip in {'', '0.0.0.0', '::'}:
|
||||||
ip = '127.0.0.1'
|
ip = '127.0.0.1'
|
||||||
await exponential_backoff(
|
await exponential_backoff(
|
||||||
lambda: can_connect(ip, port),
|
lambda: can_connect(ip, port),
|
||||||
|
Reference in New Issue
Block a user