kopia lustrzana https://github.com/jupyterhub/repo2docker
Merge pull request #918 from minrk/allow-one-port
allow user to specify a single port with default commandpull/976/head
commit
be7fc8a11a
|
@ -354,7 +354,7 @@ def make_r2d(argv=None):
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if args.ports and not r2d.run_cmd:
|
if args.ports and len(args.ports) > 1 and not r2d.run_cmd:
|
||||||
print(
|
print(
|
||||||
"To publish user defined port mapping, user must specify "
|
"To publish user defined port mapping, user must specify "
|
||||||
"the command to run in the container"
|
"the command to run in the container"
|
||||||
|
|
|
@ -595,8 +595,24 @@ class Repo2Docker(Application):
|
||||||
self.hostname = host_name
|
self.hostname = host_name
|
||||||
|
|
||||||
if not self.run_cmd:
|
if not self.run_cmd:
|
||||||
port = str(self._get_free_port())
|
if len(self.ports) == 1:
|
||||||
self.port = port
|
# single port mapping specified
|
||||||
|
# retrieve container and host port from dict
|
||||||
|
# {'8888/tcp': ('hostname', 'port')}
|
||||||
|
# or
|
||||||
|
# {'8888/tcp': 'port'}
|
||||||
|
container_port_proto, host_port = next(iter(self.ports.items()))
|
||||||
|
if isinstance(host_port, tuple):
|
||||||
|
# (hostname, port) tuple or string port
|
||||||
|
host_name, host_port = host_port
|
||||||
|
self.hostname = host_name
|
||||||
|
host_port = int(host_port)
|
||||||
|
container_port = int(container_port_proto.split("/", 1)[0])
|
||||||
|
else:
|
||||||
|
# no port specified, pick a random one
|
||||||
|
container_port = host_port = str(self._get_free_port())
|
||||||
|
self.ports = {f"{container_port}/tcp": host_port}
|
||||||
|
self.port = host_port
|
||||||
# To use the option --NotebookApp.custom_display_url
|
# To use the option --NotebookApp.custom_display_url
|
||||||
# make sure the base-notebook image is updated:
|
# make sure the base-notebook image is updated:
|
||||||
# docker pull jupyter/base-notebook
|
# docker pull jupyter/base-notebook
|
||||||
|
@ -606,20 +622,13 @@ class Repo2Docker(Application):
|
||||||
"--ip",
|
"--ip",
|
||||||
"0.0.0.0",
|
"0.0.0.0",
|
||||||
"--port",
|
"--port",
|
||||||
port,
|
container_port,
|
||||||
"--NotebookApp.custom_display_url=http://{}:{}".format(host_name, port),
|
f"--NotebookApp.custom_display_url=http://{host_name}:{host_port}"
|
||||||
"--NotebookApp.default_url=/lab",
|
"--NotebookApp.default_url=/lab",
|
||||||
]
|
]
|
||||||
ports = {"%s/tcp" % port: port}
|
|
||||||
else:
|
else:
|
||||||
# run_cmd given by user, if port is also given then pass it on
|
# run_cmd given by user, if port is also given then pass it on
|
||||||
run_cmd = self.run_cmd
|
run_cmd = self.run_cmd
|
||||||
if self.ports:
|
|
||||||
ports = self.ports
|
|
||||||
else:
|
|
||||||
ports = {}
|
|
||||||
# store ports on self so they can be retrieved in tests
|
|
||||||
self.ports = ports
|
|
||||||
|
|
||||||
container_volumes = {}
|
container_volumes = {}
|
||||||
if self.volumes:
|
if self.volumes:
|
||||||
|
@ -634,7 +643,7 @@ class Repo2Docker(Application):
|
||||||
|
|
||||||
run_kwargs = dict(
|
run_kwargs = dict(
|
||||||
publish_all_ports=self.all_ports,
|
publish_all_ports=self.all_ports,
|
||||||
ports=ports,
|
ports=self.ports,
|
||||||
command=run_cmd,
|
command=run_cmd,
|
||||||
volumes=container_volumes,
|
volumes=container_volumes,
|
||||||
environment=self.environment,
|
environment=self.environment,
|
||||||
|
|
|
@ -139,10 +139,10 @@ def validate_and_generate_port_mapping(port_mappings):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Port specification "{}" has ' "an invalid port.".format(mapping)
|
'Port specification "{}" has ' "an invalid port.".format(mapping)
|
||||||
)
|
)
|
||||||
if p > 65535:
|
if not 0 < p <= 65535:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Port specification "{}" specifies '
|
'Port specification "{}" specifies '
|
||||||
"a port above 65535.".format(mapping)
|
"a port outside 1-65535.".format(mapping)
|
||||||
)
|
)
|
||||||
return port
|
return port
|
||||||
|
|
||||||
|
@ -168,7 +168,12 @@ def validate_and_generate_port_mapping(port_mappings):
|
||||||
return ports
|
return ports
|
||||||
|
|
||||||
for mapping in port_mappings:
|
for mapping in port_mappings:
|
||||||
|
if ":" in mapping:
|
||||||
parts = mapping.split(":")
|
parts = mapping.split(":")
|
||||||
|
else:
|
||||||
|
# single port '8888' specified,
|
||||||
|
# treat as '8888:8888'
|
||||||
|
parts = [mapping, mapping]
|
||||||
|
|
||||||
*host, container_port = parts
|
*host, container_port = parts
|
||||||
# just a port
|
# just a port
|
||||||
|
|
|
@ -3,7 +3,6 @@ Test argument parsing and r2d construction
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
import logging
|
|
||||||
from repo2docker.__main__ import make_r2d
|
from repo2docker.__main__ import make_r2d
|
||||||
from repo2docker import __version__
|
from repo2docker import __version__
|
||||||
|
|
||||||
|
@ -71,10 +70,6 @@ def test_run_required():
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
make_r2d(["--no-run", "-p", "8000:8000", "."])
|
make_r2d(["--no-run", "-p", "8000:8000", "."])
|
||||||
|
|
||||||
# Can't publish any ports while running if we don't specify a command explicitly
|
|
||||||
with pytest.raises(SystemExit):
|
|
||||||
make_r2d(["-p", "8000:8000", "."])
|
|
||||||
|
|
||||||
|
|
||||||
def test_clean():
|
def test_clean():
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,6 +13,7 @@ import docker
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from repo2docker.app import Repo2Docker
|
from repo2docker.app import Repo2Docker
|
||||||
|
from repo2docker.__main__ import make_r2d
|
||||||
|
|
||||||
|
|
||||||
def read_port_mapping_response(
|
def read_port_mapping_response(
|
||||||
|
@ -95,7 +96,7 @@ def read_port_mapping_response(
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
pytest.fail("Never succeded in talking to %s" % url)
|
pytest.fail(f"Never succeeded in talking to {url}")
|
||||||
assert "Directory listing" in r.text
|
assert "Directory listing" in r.text
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,3 +114,16 @@ def test_port_mapping(request, tmpdir, host, protocol):
|
||||||
"""Test a port mapping"""
|
"""Test a port mapping"""
|
||||||
port = str(random.randint(50000, 51000))
|
port = str(random.randint(50000, 51000))
|
||||||
read_port_mapping_response(request, tmpdir, host=host, port=port, protocol=protocol)
|
read_port_mapping_response(request, tmpdir, host=host, port=port, protocol=protocol)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"port_str, port_dict",
|
||||||
|
[
|
||||||
|
("8000", {"8000/tcp": "8000"}),
|
||||||
|
("8000:9000", {"9000/tcp": "8000"}),
|
||||||
|
("127.0.0.1:8000:9000", {"9000/tcp": ("127.0.0.1", "8000")}),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_port_args(port_str, port_dict):
|
||||||
|
app = make_r2d(["-p", port_str, "."])
|
||||||
|
assert app.ports == port_dict
|
||||||
|
|
Ładowanie…
Reference in New Issue