Ver código fonte

Fix depends on restart behavior, fixes #3397

Signed-off-by: Drew Romanyk <[email protected]>
Drew Romanyk 8 anos atrás
pai
commit
ba0b3d421c
3 arquivos alterados com 36 adições e 11 exclusões
  1. 4 1
      compose/cli/main.py
  2. 12 4
      compose/project.py
  3. 20 6
      tests/integration/state_test.py

+ 4 - 1
compose/cli/main.py

@@ -918,6 +918,7 @@ class TopLevelCommand(object):
             --no-deps                  Don't start linked services.
             --force-recreate           Recreate containers even if their configuration
                                        and image haven't changed.
+            --always-recreate-deps     Recreate dependant containers.
                                        Incompatible with --no-recreate.
             --no-recreate              If containers already exist, don't recreate them.
                                        Incompatible with --force-recreate.
@@ -938,6 +939,7 @@ class TopLevelCommand(object):
                                        setting in the Compose file if present.
         """
         start_deps = not options['--no-deps']
+        always_recreate_deps = options['--always-recreate-deps']
         exit_value_from = exitval_from_opts(options, self.project)
         cascade_stop = options['--abort-on-container-exit']
         service_names = options['SERVICE']
@@ -974,7 +976,8 @@ class TopLevelCommand(object):
                 remove_orphans=remove_orphans,
                 ignore_orphans=ignore_orphans,
                 scale_override=parse_scale_args(options['--scale']),
-                start=not no_start
+                start=not no_start,
+                always_recreate_deps=always_recreate_deps
             )
 
             if detached or no_start:

+ 12 - 4
compose/project.py

@@ -442,7 +442,8 @@ class Project(object):
            ignore_orphans=False,
            scale_override=None,
            rescale=True,
-           start=True):
+           start=True,
+           always_recreate_deps=False):
 
         warn_for_swarm_mode(self.client)
 
@@ -459,7 +460,8 @@ class Project(object):
 
         for svc in services:
             svc.ensure_image_exists(do_build=do_build)
-        plans = self._get_convergence_plans(services, strategy)
+        plans = self._get_convergence_plans(
+            services, strategy, always_recreate_deps=always_recreate_deps)
         scaled_services = self.get_scaled_services(services, scale_override)
 
         def do(service):
@@ -503,7 +505,7 @@ class Project(object):
         self.networks.initialize()
         self.volumes.initialize()
 
-    def _get_convergence_plans(self, services, strategy):
+    def _get_convergence_plans(self, services, strategy, always_recreate_deps=False):
         plans = {}
 
         for service in services:
@@ -518,7 +520,13 @@ class Project(object):
                 log.debug('%s has upstream changes (%s)',
                           service.name,
                           ", ".join(updated_dependencies))
-                plan = service.convergence_plan(ConvergenceStrategy.always)
+                containers_stopped = any((not c.is_paused and not c.is_restarting and not c.is_running
+                                         for c in service.containers(stopped=True)))
+                has_links = any(c.get('HostConfig.Links') for c in service.containers())
+                if always_recreate_deps or containers_stopped or not has_links:
+                    plan = service.convergence_plan(ConvergenceStrategy.always)
+                else:
+                    plan = service.convergence_plan(strategy)
             else:
                 plan = service.convergence_plan(strategy)
 

+ 20 - 6
tests/integration/state_test.py

@@ -130,9 +130,16 @@ class ProjectWithDependenciesTest(ProjectTestCase):
         self.cfg['web']['environment'] = {'NEW_VAR': '1'}
         new_containers = self.run_up(self.cfg)
 
-        assert set(c.name_without_project for c in new_containers - old_containers) == set(
-            ['web_1', 'nginx_1']
-        )
+        assert set(c.name_without_project for c in new_containers - old_containers) == set(['web_1'])
+
+    def test_change_middle_always_recreate_deps(self):
+        old_containers = self.run_up(self.cfg, always_recreate_deps=True)
+
+        self.cfg['web']['environment'] = {'NEW_VAR': '1'}
+        new_containers = self.run_up(self.cfg, always_recreate_deps=True)
+
+        assert set(c.name_without_project
+                   for c in new_containers - old_containers) == {'web_1', 'nginx_1'}
 
     def test_change_root(self):
         old_containers = self.run_up(self.cfg)
@@ -140,9 +147,16 @@ class ProjectWithDependenciesTest(ProjectTestCase):
         self.cfg['db']['environment'] = {'NEW_VAR': '1'}
         new_containers = self.run_up(self.cfg)
 
-        assert set(c.name_without_project for c in new_containers - old_containers) == set(
-            ['db_1', 'web_1', 'nginx_1']
-        )
+        assert set(c.name_without_project for c in new_containers - old_containers) == set(['db_1'])
+
+    def test_change_root_always_recreate_deps(self):
+        old_containers = self.run_up(self.cfg, always_recreate_deps=True)
+
+        self.cfg['db']['environment'] = {'NEW_VAR': '1'}
+        new_containers = self.run_up(self.cfg, always_recreate_deps=True)
+
+        assert set(c.name_without_project
+                   for c in new_containers - old_containers) == {'db_1', 'web_1', 'nginx_1'}
 
     def test_change_root_no_recreate(self):
         old_containers = self.run_up(self.cfg)