diff options
author | Daniil Sigalov <asterite@seclab.cs.msu.ru> | 2020-12-20 15:44:01 +0300 |
---|---|---|
committer | Daniil Sigalov <asterite@seclab.cs.msu.ru> | 2020-12-20 15:58:58 +0300 |
commit | 1b5278f977cef828546e00a49c2d1687ca0532aa (patch) | |
tree | 83ab78fbd3522a3b6f20d0b08718c94b26082b9f | |
parent | 8034bc3bd6849e28bdb9823a2feb3b3f8fc07c40 (diff) |
Only attach services we'll read logs from in up
When 'up' is run with explicit list of services, compose will
start them together with their dependencies. It will attach to all
started services, but won't read output from dependencies (their
logs are not printed by 'up') - so the receive buffer of
dependencies will fill and at some point will start blocking those
services. Fix that by only attaching to services given in the
list.
To do that, move logic of choosing which services to attach from
cli/main.py to utils.py and use it from project.py to decide if
service should be attached.
Fixes #6018
Signed-off-by: Daniil Sigalov <asterite@seclab.cs.msu.ru>
-rw-r--r-- | compose/cli/main.py | 14 | ||||
-rw-r--r-- | compose/project.py | 11 | ||||
-rw-r--r-- | compose/utils.py | 15 |
3 files changed, 31 insertions, 9 deletions
diff --git a/compose/cli/main.py b/compose/cli/main.py index 9b2a5d0b..c0fe3bb4 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -38,6 +38,7 @@ from ..service import ConvergenceStrategy from ..service import ImageType from ..service import NeedsBuildError from ..service import OperationFailedError +from ..utils import filter_attached_for_up from .command import get_config_from_options from .command import get_project_dir from .command import project_from_options @@ -1071,6 +1072,7 @@ class TopLevelCommand: renew_anonymous_volumes=options.get('--renew-anon-volumes'), silent=options.get('--quiet-pull'), cli=native_builder, + attach_dependencies=attach_dependencies, ) try: @@ -1401,13 +1403,11 @@ def log_printer_from_project( def filter_attached_containers(containers, service_names, attach_dependencies=False): - if attach_dependencies or not service_names: - return containers - - return [ - container - for container in containers if container.service in service_names - ] + return filter_attached_for_up( + containers, + service_names, + attach_dependencies, + lambda container: container.service) @contextlib.contextmanager diff --git a/compose/project.py b/compose/project.py index 9b21e1cd..3bc73828 100644 --- a/compose/project.py +++ b/compose/project.py @@ -39,6 +39,7 @@ from .service import Service from .service import ServiceIpcMode from .service import ServiceNetworkMode from .service import ServicePidMode +from .utils import filter_attached_for_up from .utils import microseconds_from_time_nano from .utils import truncate_string from .volume import ProjectVolumes @@ -645,6 +646,7 @@ class Project: silent=False, cli=False, one_off=False, + attach_dependencies=False, override_options=None, ): @@ -671,12 +673,17 @@ class Project: one_off=service_names if one_off else [], ) - def do(service): + services_to_attach = filter_attached_for_up( + services, + service_names, + attach_dependencies, + lambda service: service.name) + def do(service): return service.execute_convergence_plan( plans[service.name], timeout=timeout, - detached=detached, + detached=detached or (service not in services_to_attach), scale_override=scale_override.get(service.name), rescale=rescale, start=start, diff --git a/compose/utils.py b/compose/utils.py index 060ba50c..86af8f88 100644 --- a/compose/utils.py +++ b/compose/utils.py @@ -174,3 +174,18 @@ def truncate_string(s, max_chars=35): if len(s) > max_chars: return s[:max_chars - 2] + '...' return s + + +def filter_attached_for_up(items, service_names, attach_dependencies=False, + item_to_service_name=lambda x: x): + """This function contains the logic of choosing which services to + attach when doing docker-compose up. It may be used both with containers + and services, and any other entities that map to service names - + this mapping is provided by item_to_service_name.""" + if attach_dependencies or not service_names: + return items + + return [ + item + for item in items if item_to_service_name(item) in service_names + ] |