From 47d170b06a0f04ca77c4083a151d48a714508a52 Mon Sep 17 00:00:00 2001 From: Ulysses Souza Date: Wed, 4 Sep 2019 17:52:31 +0200 Subject: [PATCH] Fix race condition on watch_events Avoid to attach to restarting containers and ignore race conditions when trying to attach to already dead containers Signed-off-by: Ulysses Souza --- compose/cli/log_printer.py | 8 +++++++- tests/unit/cli/log_printer_test.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/compose/cli/log_printer.py b/compose/cli/log_printer.py index 8aa93a8440..6940a74c87 100644 --- a/compose/cli/log_printer.py +++ b/compose/cli/log_printer.py @@ -230,7 +230,13 @@ def watch_events(thread_map, event_stream, presenters, thread_args): # Container crashed so we should reattach to it if event['id'] in crashed_containers: - event['container'].attach_log_stream() + container = event['container'] + if not container.is_restarting: + try: + container.attach_log_stream() + except APIError: + # Just ignore errors when reattaching to already crashed containers + pass crashed_containers.remove(event['id']) thread_map[event['id']] = build_thread( diff --git a/tests/unit/cli/log_printer_test.py b/tests/unit/cli/log_printer_test.py index 6db24e4648..5e387241d6 100644 --- a/tests/unit/cli/log_printer_test.py +++ b/tests/unit/cli/log_printer_test.py @@ -152,6 +152,17 @@ def test_start_event(self, thread_map, mock_presenters): *thread_args) assert container_id in thread_map + def test_container_attach_event(self, thread_map, mock_presenters): + container_id = 'abcd' + mock_container = mock.Mock(is_restarting=False) + mock_container.attach_log_stream.side_effect = APIError("race condition") + event_die = {'action': 'die', 'id': container_id} + event_start = {'action': 'start', 'id': container_id, 'container': mock_container} + event_stream = [event_die, event_start] + thread_args = 'foo', 'bar' + watch_events(thread_map, event_stream, mock_presenters, thread_args) + assert mock_container.attach_log_stream.called + def test_other_event(self, thread_map, mock_presenters): container_id = 'abcd' event_stream = [{'action': 'create', 'id': container_id}]