diff --git a/docker/utils/ports.py b/docker/utils/ports.py index 326ef94f..5bb7079a 100644 --- a/docker/utils/ports.py +++ b/docker/utils/ports.py @@ -24,7 +24,7 @@ def build_port_bindings(ports): return port_bindings -def to_port_range(port): +def to_port_range(port, randomly_available_port=False): if not port: return None @@ -37,6 +37,9 @@ def to_port_range(port): port, protocol = parts protocol = "/" + protocol + if randomly_available_port: + return ["%s%s" % (port, protocol)] + parts = str(port).split('-') if len(parts) == 1: @@ -69,9 +72,11 @@ def split_port(port): external_port, internal_port = parts internal_range = to_port_range(internal_port) - external_range = to_port_range(external_port) + if internal_range is None: + _raise_invalid_port(port) - if internal_range is None or external_range is None: + external_range = to_port_range(external_port, len(internal_range) == 1) + if external_range is None: _raise_invalid_port(port) if len(internal_range) != len(external_range): @@ -81,7 +86,7 @@ def split_port(port): external_ip, external_port, internal_port = parts internal_range = to_port_range(internal_port) - external_range = to_port_range(external_port) + external_range = to_port_range(external_port, len(internal_range) == 1) if not external_range: external_range = [None] * len(internal_range) diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py index 854d0ef2..ad6d9e09 100644 --- a/tests/unit/utils_test.py +++ b/tests/unit/utils_test.py @@ -530,6 +530,11 @@ class PortsTest(unittest.TestCase): self.assertEqual(internal_port, ["2000", "2001"]) self.assertEqual(external_port, ["1000", "1001"]) + def test_split_port_random_port_range_with_host_port(self): + internal_port, external_port = split_port("1000-1001:2000") + self.assertEqual(internal_port, ["2000"]) + self.assertEqual(external_port, ["1000-1001"]) + def test_split_port_no_host_port(self): internal_port, external_port = split_port("2000") self.assertEqual(internal_port, ["2000"])