Fix depends on restart behavior, fixes #3397

Signed-off-by: Drew Romanyk <drewiswaycool@gmail.com>
This commit is contained in:
Drew Romanyk 2017-11-14 16:24:58 -06:00 committed by Joffrey F
parent 353ebe9337
commit ba0b3d421c
3 changed files with 36 additions and 11 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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)