From 2ed171cae94ef5ac9d2eeeb683b217e380e93b81 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Thu, 10 Jan 2019 15:47:44 -0800 Subject: [PATCH] Bring zero container check up in the call stack Signed-off-by: Joffrey F --- compose/parallel.py | 13 +++++++------ compose/project.py | 1 + tests/acceptance/cli_test.py | 5 +---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/compose/parallel.py b/compose/parallel.py index d6af51694..e242a318a 100644 --- a/compose/parallel.py +++ b/compose/parallel.py @@ -43,16 +43,14 @@ class GlobalLimit(object): cls.global_limiter = Semaphore(value) -def parallel_execute_watch(events, writer, errors, results, msg, get_name, func_name): +def parallel_execute_watch(events, writer, errors, results, msg, get_name, fail_check): """ Watch events from a parallel execution, update status and fill errors and results. Returns exception to re-raise. """ error_to_reraise = None for obj, result, exception in events: if exception is None: - if func_name == 'start_service' and ( - callable(getattr(obj, 'containers', None)) and not obj.containers()): - # If service has no containers started + if fail_check is not None and fail_check(obj): writer.write(msg, get_name(obj), 'failed', red) else: writer.write(msg, get_name(obj), 'done', green) @@ -77,12 +75,14 @@ def parallel_execute_watch(events, writer, errors, results, msg, get_name, func_ return error_to_reraise -def parallel_execute(objects, func, get_name, msg, get_deps=None, limit=None): +def parallel_execute(objects, func, get_name, msg, get_deps=None, limit=None, fail_check=None): """Runs func on objects in parallel while ensuring that func is ran on object only after it is ran on all its dependencies. get_deps called on object must return a collection with its dependencies. get_name called on object must return its name. + fail_check is an additional failure check for cases that should display as a failure + in the CLI logs, but don't raise an exception (such as attempting to start 0 containers) """ objects = list(objects) stream = get_output_stream(sys.stderr) @@ -102,7 +102,8 @@ def parallel_execute(objects, func, get_name, msg, get_deps=None, limit=None): errors = {} results = [] error_to_reraise = parallel_execute_watch( - events, writer, errors, results, msg, get_name, getattr(func, '__name__', None)) + events, writer, errors, results, msg, get_name, fail_check + ) for obj_name, error in errors.items(): stream.write("\nERROR: for {} {}\n".format(obj_name, error)) diff --git a/compose/project.py b/compose/project.py index 5c4ce6e17..a7f2aa057 100644 --- a/compose/project.py +++ b/compose/project.py @@ -280,6 +280,7 @@ class Project(object): operator.attrgetter('name'), 'Starting', get_deps, + fail_check=lambda obj: not obj.containers(), ) return containers diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 9334a29fb..5142f96eb 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -610,11 +610,8 @@ class CLITestCase(DockerClientTestCase): result = self.dispatch(['pull']) assert 'Pulling simple' in result.stderr assert 'Pulling another' in result.stderr - - def test_pull_done(self): - result = self.dispatch(['pull']) - assert 'Pulling simple' in result.stderr assert 'done' in result.stderr + assert 'failed' not in result.stderr def test_pull_with_digest(self): result = self.dispatch(['-f', 'digest.yml', 'pull', '--no-parallel'])