Procházet zdrojové kódy

Specify all HostConfig at create time

This is required for Swarm integration: the cluster needs to know
about config like `links` and `volumes_from` at create time so that it
can co-schedule containers.

Signed-off-by: Aanand Prasad <[email protected]>
Aanand Prasad před 10 roky
rodič
revize
eef4bc3917

+ 1 - 1
compose/cli/docker_client.py

@@ -32,4 +32,4 @@ def docker_client():
         )
 
     timeout = int(os.environ.get('DOCKER_CLIENT_TIMEOUT', 60))
-    return Client(base_url=base_url, tls=tls_config, version='1.14', timeout=timeout)
+    return Client(base_url=base_url, tls=tls_config, version='1.15', timeout=timeout)

+ 5 - 5
compose/cli/main.py

@@ -328,20 +328,20 @@ class TopLevelCommand(Command):
         if options['--user']:
             container_options['user'] = options.get('--user')
 
+        if not options['--service-ports']:
+            container_options['ports'] = []
+
         container = service.create_container(
             one_off=True,
             insecure_registry=insecure_registry,
             **container_options
         )
 
-        service_ports = None
-        if options['--service-ports']:
-            service_ports = service.options['ports']
         if options['-d']:
-            service.start_container(container, ports=service_ports, one_off=True)
+            service.start_container(container)
             print(container.name)
         else:
-            service.start_container(container, ports=service_ports, one_off=True)
+            service.start_container(container)
             dockerpty.start(project.client, container.id, interactive=not options['-T'])
             exit_code = container.wait()
             if options['--rm']:

+ 57 - 37
compose/service.py

@@ -8,6 +8,7 @@ from operator import attrgetter
 import sys
 
 from docker.errors import APIError
+from docker.utils import create_host_config
 
 from .config import DOCKER_CONFIG_KEYS
 from .container import Container, get_container_name
@@ -168,6 +169,7 @@ class Service(object):
                          one_off=False,
                          insecure_registry=False,
                          do_build=True,
+                         intermediate_container=None,
                          **override_options):
         """
         Create a container for this service. If the image doesn't exist, attempt to pull
@@ -175,7 +177,9 @@ class Service(object):
         """
         container_options = self._get_container_create_options(
             override_options,
-            one_off=one_off)
+            one_off=one_off,
+            intermediate_container=intermediate_container,
+        )
 
         if (do_build and
                 self.can_be_built() and
@@ -240,56 +244,33 @@ class Service(object):
             entrypoint=['/bin/echo'],
             command=[],
             detach=True,
+            host_config=create_host_config(volumes_from=[container.id]),
         )
-        intermediate_container.start(volumes_from=container.id)
+        intermediate_container.start()
         intermediate_container.wait()
         container.remove()
 
         options = dict(override_options)
-        new_container = self.create_container(do_build=False, **options)
-        self.start_container(new_container, intermediate_container=intermediate_container)
+        new_container = self.create_container(
+            do_build=False,
+            intermediate_container=intermediate_container,
+            **options
+        )
+        self.start_container(new_container)
 
         intermediate_container.remove()
 
         return (intermediate_container, new_container)
 
-    def start_container_if_stopped(self, container, **options):
+    def start_container_if_stopped(self, container):
         if container.is_running:
             return container
         else:
             log.info("Starting %s..." % container.name)
-            return self.start_container(container, **options)
-
-    def start_container(self, container, intermediate_container=None, **override_options):
-        options = dict(self.options, **override_options)
-        port_bindings = build_port_bindings(options.get('ports') or [])
-
-        volume_bindings = dict(
-            build_volume_binding(parse_volume_spec(volume))
-            for volume in options.get('volumes') or []
-            if ':' in volume)
-
-        privileged = options.get('privileged', False)
-        dns = options.get('dns', None)
-        dns_search = options.get('dns_search', None)
-        cap_add = options.get('cap_add', None)
-        cap_drop = options.get('cap_drop', None)
-
-        restart = parse_restart_spec(options.get('restart', None))
+            return self.start_container(container)
 
-        container.start(
-            links=self._get_links(link_to_self=options.get('one_off', False)),
-            port_bindings=port_bindings,
-            binds=volume_bindings,
-            volumes_from=self._get_volumes_from(intermediate_container),
-            privileged=privileged,
-            network_mode=self._get_net(),
-            dns=dns,
-            dns_search=dns_search,
-            restart_policy=restart,
-            cap_add=cap_add,
-            cap_drop=cap_drop,
-        )
+    def start_container(self, container):
+        container.start()
         return container
 
     def start_or_create_containers(
@@ -389,7 +370,7 @@ class Service(object):
 
         return net
 
-    def _get_container_create_options(self, override_options, one_off=False):
+    def _get_container_create_options(self, override_options, one_off=False, intermediate_container=None):
         container_options = dict(
             (k, self.options[k])
             for k in DOCKER_CONFIG_KEYS if k in self.options)
@@ -436,8 +417,47 @@ class Service(object):
         for key in DOCKER_START_KEYS:
             container_options.pop(key, None)
 
+        container_options['host_config'] = self._get_container_host_config(override_options, one_off=one_off, intermediate_container=intermediate_container)
+
         return container_options
 
+    def _get_container_host_config(self, override_options, one_off=False, intermediate_container=None):
+        options = dict(self.options, **override_options)
+        port_bindings = build_port_bindings(options.get('ports') or [])
+
+        volume_bindings = dict(
+            build_volume_binding(parse_volume_spec(volume))
+            for volume in options.get('volumes') or []
+            if ':' in volume)
+
+        privileged = options.get('privileged', False)
+        cap_add = options.get('cap_add', None)
+        cap_drop = options.get('cap_drop', None)
+
+        dns = options.get('dns', None)
+        if not isinstance(dns, list):
+            dns = [dns]
+
+        dns_search = options.get('dns_search', None)
+        if not isinstance(dns_search, list):
+            dns_search = [dns_search]
+
+        restart = parse_restart_spec(options.get('restart', None))
+
+        return create_host_config(
+            links=self._get_links(link_to_self=one_off),
+            port_bindings=port_bindings,
+            binds=volume_bindings,
+            volumes_from=self._get_volumes_from(intermediate_container),
+            privileged=privileged,
+            network_mode=self._get_net(),
+            dns=dns,
+            dns_search=dns_search,
+            restart_policy=restart,
+            cap_add=cap_add,
+            cap_drop=cap_drop,
+        )
+
     def _get_image_name(self, image):
         repo, tag = parse_repository_tag(image)
         if tag == "":

+ 1 - 1
tests/integration/service_test.py

@@ -13,7 +13,7 @@ from .testcases import DockerClientTestCase
 
 def create_and_start_container(service, **override_options):
     container = service.create_container(**override_options)
-    return service.start_container(container, **override_options)
+    return service.start_container(container)
 
 
 class ServiceTest(DockerClientTestCase):