Bring zero container check up in the call stack

Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
Joffrey F 2019-01-10 15:47:44 -08:00
parent 325637d9d5
commit 2ed171cae9
3 changed files with 9 additions and 10 deletions

View File

@ -43,16 +43,14 @@ class GlobalLimit(object):
cls.global_limiter = Semaphore(value) 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. """ Watch events from a parallel execution, update status and fill errors and results.
Returns exception to re-raise. Returns exception to re-raise.
""" """
error_to_reraise = None error_to_reraise = None
for obj, result, exception in events: for obj, result, exception in events:
if exception is None: if exception is None:
if func_name == 'start_service' and ( if fail_check is not None and fail_check(obj):
callable(getattr(obj, 'containers', None)) and not obj.containers()):
# If service has no containers started
writer.write(msg, get_name(obj), 'failed', red) writer.write(msg, get_name(obj), 'failed', red)
else: else:
writer.write(msg, get_name(obj), 'done', green) 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 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 """Runs func on objects in parallel while ensuring that func is
ran on object only after it is ran on all its dependencies. 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_deps called on object must return a collection with its dependencies.
get_name called on object must return its name. 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) objects = list(objects)
stream = get_output_stream(sys.stderr) stream = get_output_stream(sys.stderr)
@ -102,7 +102,8 @@ def parallel_execute(objects, func, get_name, msg, get_deps=None, limit=None):
errors = {} errors = {}
results = [] results = []
error_to_reraise = parallel_execute_watch( 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(): for obj_name, error in errors.items():
stream.write("\nERROR: for {} {}\n".format(obj_name, error)) stream.write("\nERROR: for {} {}\n".format(obj_name, error))

View File

@ -280,6 +280,7 @@ class Project(object):
operator.attrgetter('name'), operator.attrgetter('name'),
'Starting', 'Starting',
get_deps, get_deps,
fail_check=lambda obj: not obj.containers(),
) )
return containers return containers

View File

@ -610,11 +610,8 @@ class CLITestCase(DockerClientTestCase):
result = self.dispatch(['pull']) result = self.dispatch(['pull'])
assert 'Pulling simple' in result.stderr assert 'Pulling simple' in result.stderr
assert 'Pulling another' 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 'done' in result.stderr
assert 'failed' not in result.stderr
def test_pull_with_digest(self): def test_pull_with_digest(self):
result = self.dispatch(['-f', 'digest.yml', 'pull', '--no-parallel']) result = self.dispatch(['-f', 'digest.yml', 'pull', '--no-parallel'])