Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow scaling services that have port binding of the form host_ip::container_port #1659

Merged
merged 1 commit into from
Oct 23, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions compose/service.py
Original file line number Diff line number Diff line change
@@ -770,10 +770,28 @@ def custom_container_name(self):
return self.options.get('container_name')

def specifies_host_port(self):
for port in self.options.get('ports', []):
if ':' in str(port):
def has_host_port(binding):
_, external_bindings = split_port(binding)

# there are no external bindings
if external_bindings is None:
return False

# we only need to check the first binding from the range
external_binding = external_bindings[0]

# non-tuple binding means there is a host port specified
if not isinstance(external_binding, tuple):
return True
return False

# extract actual host port from tuple of (host_ip, host_port)
_, host_port = external_binding
if host_port is not None:
return True

return False

return any(has_host_port(binding) for binding in self.options.get('ports', []))

def pull(self, ignore_pull_failures=False):
if 'image' not in self.options:
62 changes: 62 additions & 0 deletions tests/unit/service_test.py
Original file line number Diff line number Diff line change
@@ -444,6 +444,68 @@ def test_config_dict_with_net_from_container(self):
}
self.assertEqual(config_dict, expected)

def test_specifies_host_port_with_no_ports(self):
service = Service(
'foo',
image='foo')
self.assertEqual(service.specifies_host_port(), False)

def test_specifies_host_port_with_container_port(self):
service = Service(
'foo',
image='foo',
ports=["2000"])
self.assertEqual(service.specifies_host_port(), False)

def test_specifies_host_port_with_host_port(self):
service = Service(
'foo',
image='foo',
ports=["1000:2000"])
self.assertEqual(service.specifies_host_port(), True)

def test_specifies_host_port_with_host_ip_no_port(self):
service = Service(
'foo',
image='foo',
ports=["127.0.0.1::2000"])
self.assertEqual(service.specifies_host_port(), False)

def test_specifies_host_port_with_host_ip_and_port(self):
service = Service(
'foo',
image='foo',
ports=["127.0.0.1:1000:2000"])
self.assertEqual(service.specifies_host_port(), True)

def test_specifies_host_port_with_container_port_range(self):
service = Service(
'foo',
image='foo',
ports=["2000-3000"])
self.assertEqual(service.specifies_host_port(), False)

def test_specifies_host_port_with_host_port_range(self):
service = Service(
'foo',
image='foo',
ports=["1000-2000:2000-3000"])
self.assertEqual(service.specifies_host_port(), True)

def test_specifies_host_port_with_host_ip_no_port_range(self):
service = Service(
'foo',
image='foo',
ports=["127.0.0.1::2000-3000"])
self.assertEqual(service.specifies_host_port(), False)

def test_specifies_host_port_with_host_ip_and_port_range(self):
service = Service(
'foo',
image='foo',
ports=["127.0.0.1:1000-2000:2000-3000"])
self.assertEqual(service.specifies_host_port(), True)


class NetTestCase(unittest.TestCase):