From 9c5347bd23b3bacc6a583a035a51c7092ee2dbb4 Mon Sep 17 00:00:00 2001
From: Guillermo Arribas <garribas@gmail.com>
Date: Tue, 17 Oct 2017 11:54:06 -0300
Subject: [PATCH] Placing dots in hostname no longer populates domainname if
 api >= 1.23 (fixes #4128)

Signed-off-by: Guillermo Arribas <garribas@gmail.com>
---
 compose/service.py         |  8 +++++---
 tests/unit/cli_test.py     |  3 +++
 tests/unit/service_test.py | 22 ++++++++++++++++------
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/compose/service.py b/compose/service.py
index 1a18c6654..d5be740df 100644
--- a/compose/service.py
+++ b/compose/service.py
@@ -14,6 +14,7 @@ from docker.errors import APIError
 from docker.errors import ImageNotFound
 from docker.errors import NotFound
 from docker.types import LogConfig
+from docker.utils import version_lt
 from docker.utils.ports import build_port_bindings
 from docker.utils.ports import split_port
 from docker.utils.utils import convert_tmpfs_mounts
@@ -747,9 +748,10 @@ class Service(object):
 
         # If a qualified hostname was given, split it into an
         # unqualified hostname and a domainname unless domainname
-        # was also given explicitly. This matches the behavior of
-        # the official Docker CLI in that scenario.
-        if ('hostname' in container_options and
+        # was also given explicitly. This matches behavior
+        # until Docker Engine 1.11.0 - Docker API 1.23.
+        if (version_lt(self.client.api_version, '1.23') and
+                'hostname' in container_options and
                 'domainname' not in container_options and
                 '.' in container_options['hostname']):
             parts = container_options['hostname'].partition('.')
diff --git a/tests/unit/cli_test.py b/tests/unit/cli_test.py
index f9ce240a3..1a324f50a 100644
--- a/tests/unit/cli_test.py
+++ b/tests/unit/cli_test.py
@@ -10,6 +10,7 @@ from io import StringIO
 import docker
 import py
 import pytest
+from docker.constants import DEFAULT_DOCKER_API_VERSION
 
 from .. import mock
 from .. import unittest
@@ -98,6 +99,7 @@ class CLITestCase(unittest.TestCase):
     @mock.patch('compose.cli.main.PseudoTerminal', autospec=True)
     def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal, mock_run_operation):
         mock_client = mock.create_autospec(docker.APIClient)
+        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
         project = Project.from_config(
             name='composetest',
             client=mock_client,
@@ -130,6 +132,7 @@ class CLITestCase(unittest.TestCase):
 
     def test_run_service_with_restart_always(self):
         mock_client = mock.create_autospec(docker.APIClient)
+        mock_client.api_version = DEFAULT_DOCKER_API_VERSION
 
         project = Project.from_config(
             name='composetest',
diff --git a/tests/unit/service_test.py b/tests/unit/service_test.py
index 7d61807ba..c979295ad 100644
--- a/tests/unit/service_test.py
+++ b/tests/unit/service_test.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
 
 import docker
 import pytest
+from docker.constants import DEFAULT_DOCKER_API_VERSION
 from docker.errors import APIError
 
 from .. import mock
@@ -40,6 +41,7 @@ class ServiceTest(unittest.TestCase):
 
     def setUp(self):
         self.mock_client = mock.create_autospec(docker.APIClient)
+        self.mock_client.api_version = DEFAULT_DOCKER_API_VERSION
 
     def test_containers(self):
         service = Service('db', self.mock_client, 'myproject', image='foo')
@@ -145,12 +147,6 @@ class ServiceTest(unittest.TestCase):
         self.assertEqual(service._get_volumes_from(), [container_id + ':rw'])
         from_service.create_container.assert_called_once_with()
 
-    def test_split_domainname_none(self):
-        service = Service('foo', image='foo', hostname='name', client=self.mock_client)
-        opts = service._get_container_create_options({'image': 'foo'}, 1)
-        self.assertEqual(opts['hostname'], 'name', 'hostname')
-        self.assertFalse('domainname' in opts, 'domainname')
-
     def test_memory_swap_limit(self):
         self.mock_client.create_host_config.return_value = {}
 
@@ -232,7 +228,18 @@ class ServiceTest(unittest.TestCase):
             {'Type': 'syslog', 'Config': {'syslog-address': 'tcp://192.168.0.42:123'}}
         )
 
+    def test_split_domainname_none(self):
+        service = Service(
+            'foo',
+            image='foo',
+            hostname='name.domain.tld',
+            client=self.mock_client)
+        opts = service._get_container_create_options({'image': 'foo'}, 1)
+        self.assertEqual(opts['hostname'], 'name.domain.tld', 'hostname')
+        self.assertFalse('domainname' in opts, 'domainname')
+
     def test_split_domainname_fqdn(self):
+        self.mock_client.api_version = '1.22'
         service = Service(
             'foo',
             hostname='name.domain.tld',
@@ -243,6 +250,7 @@ class ServiceTest(unittest.TestCase):
         self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
 
     def test_split_domainname_both(self):
+        self.mock_client.api_version = '1.22'
         service = Service(
             'foo',
             hostname='name',
@@ -254,6 +262,7 @@ class ServiceTest(unittest.TestCase):
         self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
 
     def test_split_domainname_weird(self):
+        self.mock_client.api_version = '1.22'
         service = Service(
             'foo',
             hostname='name.sub',
@@ -857,6 +866,7 @@ class ServiceVolumesTest(unittest.TestCase):
 
     def setUp(self):
         self.mock_client = mock.create_autospec(docker.APIClient)
+        self.mock_client.api_version = DEFAULT_DOCKER_API_VERSION
 
     def test_build_volume_binding(self):
         binding = build_volume_binding(VolumeSpec.parse('/outside:/inside', True))