Skip to content

Commit 6826d72

Browse files
minrkconsideRatio
authored andcommitted
allow user to specify a single port with default command
Allows specifying `-p9999` or `-p5555:9999` without also needing to override the default command app retrieves port arguments from length-1 port mapping for default command, instead of requiring random port OR overriding the whole command
1 parent 0f5ee70 commit 6826d72

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

repo2docker/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ def make_r2d(argv=None):
354354
)
355355
sys.exit(1)
356356

357-
if args.ports and not r2d.run_cmd:
357+
if args.ports and len(args.ports) > 1 and not r2d.run_cmd:
358358
print(
359359
"To publish user defined port mapping, user must specify "
360360
"the command to run in the container"

repo2docker/app.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,24 @@ def start_container(self):
595595
self.hostname = host_name
596596

597597
if not self.run_cmd:
598-
port = str(self._get_free_port())
599-
self.port = port
598+
if len(self.ports) == 1:
599+
# single port mapping specified
600+
# retrieve container and host port from dict
601+
# {'8888/tcp': ('hostname', 'port')}
602+
# or
603+
# {'8888/tcp': 'port'}
604+
container_port_proto, host_port = next(iter(self.ports.items()))
605+
if isinstance(host_port, tuple):
606+
# (hostname, port) tuple or string port
607+
host_name, host_port = host_port
608+
self.hostname = host_name
609+
host_port = int(host_port)
610+
container_port = int(container_port_proto.split("/", 1)[0])
611+
else:
612+
# no port specified, pick a random one
613+
container_port = host_port = str(self._get_free_port())
614+
self.ports = {"%s/tcp" % container_port: host_port}
615+
self.port = host_port
600616
# To use the option --NotebookApp.custom_display_url
601617
# make sure the base-notebook image is updated:
602618
# docker pull jupyter/base-notebook
@@ -606,20 +622,13 @@ def start_container(self):
606622
"--ip",
607623
"0.0.0.0",
608624
"--port",
609-
port,
610-
"--NotebookApp.custom_display_url=http://{}:{}".format(host_name, port),
625+
container_port,
626+
f"--NotebookApp.custom_display_url=http://{host_name}:{host_port}"
611627
"--NotebookApp.default_url=/lab",
612628
]
613-
ports = {"%s/tcp" % port: port}
614629
else:
615630
# run_cmd given by user, if port is also given then pass it on
616631
run_cmd = self.run_cmd
617-
if self.ports:
618-
ports = self.ports
619-
else:
620-
ports = {}
621-
# store ports on self so they can be retrieved in tests
622-
self.ports = ports
623632

624633
container_volumes = {}
625634
if self.volumes:
@@ -634,7 +643,7 @@ def start_container(self):
634643

635644
run_kwargs = dict(
636645
publish_all_ports=self.all_ports,
637-
ports=ports,
646+
ports=self.ports,
638647
command=run_cmd,
639648
volumes=container_volumes,
640649
environment=self.environment,

repo2docker/utils.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,10 @@ def check_port(port):
139139
raise ValueError(
140140
'Port specification "{}" has ' "an invalid port.".format(mapping)
141141
)
142-
if p > 65535:
142+
if not 0 < p <= 65535:
143143
raise ValueError(
144144
'Port specification "{}" specifies '
145-
"a port above 65535.".format(mapping)
145+
"a port outside 1-65535.".format(mapping)
146146
)
147147
return port
148148

@@ -168,7 +168,12 @@ def check_port_string(p):
168168
return ports
169169

170170
for mapping in port_mappings:
171-
parts = mapping.split(":")
171+
if ":" in mapping:
172+
parts = mapping.split(":")
173+
else:
174+
# single port '8888' specified,
175+
# treat as '8888:8888'
176+
parts = [mapping, mapping]
172177

173178
*host, container_port = parts
174179
# just a port

0 commit comments

Comments
 (0)