mirror of https://github.com/docker/compose.git
Merge pull request #624 from drewkett/multiple_port_mappings
Support multiple port bindings for same internal port
This commit is contained in:
commit
d3e94f2caf
|
@ -251,7 +251,7 @@ class Service(object):
|
||||||
def start_container(self, container=None, intermediate_container=None, **override_options):
|
def start_container(self, container=None, intermediate_container=None, **override_options):
|
||||||
container = container or self.create_container(**override_options)
|
container = container or self.create_container(**override_options)
|
||||||
options = dict(self.options, **override_options)
|
options = dict(self.options, **override_options)
|
||||||
ports = dict(split_port(port) for port in options.get('ports') or [])
|
port_bindings = build_port_bindings(options.get('ports') or [])
|
||||||
|
|
||||||
volume_bindings = dict(
|
volume_bindings = dict(
|
||||||
build_volume_binding(parse_volume_spec(volume))
|
build_volume_binding(parse_volume_spec(volume))
|
||||||
|
@ -264,7 +264,7 @@ class Service(object):
|
||||||
|
|
||||||
container.start(
|
container.start(
|
||||||
links=self._get_links(link_to_self=options.get('one_off', False)),
|
links=self._get_links(link_to_self=options.get('one_off', False)),
|
||||||
port_bindings=ports,
|
port_bindings=port_bindings,
|
||||||
binds=volume_bindings,
|
binds=volume_bindings,
|
||||||
volumes_from=self._get_volumes_from(intermediate_container),
|
volumes_from=self._get_volumes_from(intermediate_container),
|
||||||
privileged=privileged,
|
privileged=privileged,
|
||||||
|
@ -492,6 +492,17 @@ def build_volume_binding(volume_spec):
|
||||||
return os.path.abspath(os.path.expandvars(external)), internal
|
return os.path.abspath(os.path.expandvars(external)), internal
|
||||||
|
|
||||||
|
|
||||||
|
def build_port_bindings(ports):
|
||||||
|
port_bindings = {}
|
||||||
|
for port in ports:
|
||||||
|
internal_port, external = split_port(port)
|
||||||
|
if internal_port in port_bindings:
|
||||||
|
port_bindings[internal_port].append(external)
|
||||||
|
else:
|
||||||
|
port_bindings[internal_port] = [external]
|
||||||
|
return port_bindings
|
||||||
|
|
||||||
|
|
||||||
def split_port(port):
|
def split_port(port):
|
||||||
parts = str(port).split(':')
|
parts = str(port).split(':')
|
||||||
if not 1 <= len(parts) <= 3:
|
if not 1 <= len(parts) <= 3:
|
||||||
|
|
|
@ -13,6 +13,7 @@ from fig.container import Container
|
||||||
from fig.service import (
|
from fig.service import (
|
||||||
ConfigError,
|
ConfigError,
|
||||||
split_port,
|
split_port,
|
||||||
|
build_port_bindings,
|
||||||
parse_volume_spec,
|
parse_volume_spec,
|
||||||
build_volume_binding,
|
build_volume_binding,
|
||||||
APIError,
|
APIError,
|
||||||
|
@ -114,6 +115,19 @@ class ServiceTest(unittest.TestCase):
|
||||||
with self.assertRaises(ConfigError):
|
with self.assertRaises(ConfigError):
|
||||||
split_port("0.0.0.0:1000:2000:tcp")
|
split_port("0.0.0.0:1000:2000:tcp")
|
||||||
|
|
||||||
|
def test_build_port_bindings_with_one_port(self):
|
||||||
|
port_bindings = build_port_bindings(["127.0.0.1:1000:1000"])
|
||||||
|
self.assertEqual(port_bindings["1000"],[("127.0.0.1","1000")])
|
||||||
|
|
||||||
|
def test_build_port_bindings_with_matching_internal_ports(self):
|
||||||
|
port_bindings = build_port_bindings(["127.0.0.1:1000:1000","127.0.0.1:2000:1000"])
|
||||||
|
self.assertEqual(port_bindings["1000"],[("127.0.0.1","1000"),("127.0.0.1","2000")])
|
||||||
|
|
||||||
|
def test_build_port_bindings_with_nonmatching_internal_ports(self):
|
||||||
|
port_bindings = build_port_bindings(["127.0.0.1:1000:1000","127.0.0.1:2000:2000"])
|
||||||
|
self.assertEqual(port_bindings["1000"],[("127.0.0.1","1000")])
|
||||||
|
self.assertEqual(port_bindings["2000"],[("127.0.0.1","2000")])
|
||||||
|
|
||||||
def test_split_domainname_none(self):
|
def test_split_domainname_none(self):
|
||||||
service = Service('foo', hostname='name', client=self.mock_client)
|
service = Service('foo', hostname='name', client=self.mock_client)
|
||||||
self.mock_client.containers.return_value = []
|
self.mock_client.containers.return_value = []
|
||||||
|
|
Loading…
Reference in New Issue