mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-18 12:52:37 +00:00
Handle yet another random unstructured error output. (#949)
This commit is contained in:
parent
d91f854d45
commit
3cc27ecd65
2
changelogs/fragments/949-compose-error.yml
Normal file
2
changelogs/fragments/949-compose-error.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
bugfixes:
|
||||||
|
- "docker_compose_v2 - handle yet another random unstructured error output from pre-2.29.0 Compose versions (https://github.com/ansible-collections/community.docker/issues/948, https://github.com/ansible-collections/community.docker/pull/949)."
|
||||||
@ -456,13 +456,13 @@ def parse_json_events(stderr, warn_function=None):
|
|||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
def parse_events(stderr, dry_run=False, warn_function=None):
|
def parse_events(stderr, dry_run=False, warn_function=None, nonzero_rc=False):
|
||||||
events = []
|
events = []
|
||||||
error_event = None
|
error_event = None
|
||||||
stderr_lines = stderr.splitlines()
|
stderr_lines = stderr.splitlines()
|
||||||
if stderr_lines and stderr_lines[-1] == b'':
|
if stderr_lines and stderr_lines[-1] == b'':
|
||||||
del stderr_lines[-1]
|
del stderr_lines[-1]
|
||||||
for line in stderr_lines:
|
for index, line in enumerate(stderr_lines):
|
||||||
line = to_native(line.strip())
|
line = to_native(line.strip())
|
||||||
if not line:
|
if not line:
|
||||||
continue
|
continue
|
||||||
@ -513,7 +513,7 @@ def parse_events(stderr, dry_run=False, warn_function=None):
|
|||||||
)
|
)
|
||||||
events.append(error_event)
|
events.append(error_event)
|
||||||
continue
|
continue
|
||||||
if len(stderr_lines) == 1:
|
if len(stderr_lines) == 1 or (nonzero_rc and index == len(stderr_lines) - 1):
|
||||||
# **Very likely** an error message that is independent of an error event
|
# **Very likely** an error message that is independent of an error event
|
||||||
error_event = Event(
|
error_event = Event(
|
||||||
ResourceType.UNKNOWN,
|
ResourceType.UNKNOWN,
|
||||||
@ -780,10 +780,10 @@ class BaseComposeManager(DockerBaseClass):
|
|||||||
self._handle_failed_cli_call(args, rc, images, stderr)
|
self._handle_failed_cli_call(args, rc, images, stderr)
|
||||||
return images
|
return images
|
||||||
|
|
||||||
def parse_events(self, stderr, dry_run=False):
|
def parse_events(self, stderr, dry_run=False, nonzero_rc=False):
|
||||||
if self.use_json_events:
|
if self.use_json_events:
|
||||||
return parse_json_events(stderr, warn_function=self.client.warn)
|
return parse_json_events(stderr, warn_function=self.client.warn)
|
||||||
return parse_events(stderr, dry_run=dry_run, warn_function=self.client.warn)
|
return parse_events(stderr, dry_run=dry_run, warn_function=self.client.warn, nonzero_rc=nonzero_rc)
|
||||||
|
|
||||||
def emit_warnings(self, events):
|
def emit_warnings(self, events):
|
||||||
emit_warnings(events, warn_function=self.client.warn)
|
emit_warnings(events, warn_function=self.client.warn)
|
||||||
|
|||||||
@ -506,7 +506,7 @@ class ServicesManager(BaseComposeManager):
|
|||||||
result = dict()
|
result = dict()
|
||||||
args = self.get_up_cmd(self.check_mode)
|
args = self.get_up_cmd(self.check_mode)
|
||||||
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
||||||
events = self.parse_events(stderr, dry_run=self.check_mode)
|
events = self.parse_events(stderr, dry_run=self.check_mode, nonzero_rc=rc != 0)
|
||||||
self.emit_warnings(events)
|
self.emit_warnings(events)
|
||||||
self.update_result(result, events, stdout, stderr, ignore_service_pull_events=True)
|
self.update_result(result, events, stdout, stderr, ignore_service_pull_events=True)
|
||||||
self.update_failed(result, events, args, stdout, stderr, rc)
|
self.update_failed(result, events, args, stdout, stderr, rc)
|
||||||
@ -537,7 +537,7 @@ class ServicesManager(BaseComposeManager):
|
|||||||
# Make sure all containers are created
|
# Make sure all containers are created
|
||||||
args_1 = self.get_up_cmd(self.check_mode, no_start=True)
|
args_1 = self.get_up_cmd(self.check_mode, no_start=True)
|
||||||
rc_1, stdout_1, stderr_1 = self.client.call_cli(*args_1, cwd=self.project_src)
|
rc_1, stdout_1, stderr_1 = self.client.call_cli(*args_1, cwd=self.project_src)
|
||||||
events_1 = self.parse_events(stderr_1, dry_run=self.check_mode)
|
events_1 = self.parse_events(stderr_1, dry_run=self.check_mode, nonzero_rc=rc_1 != 0)
|
||||||
self.emit_warnings(events_1)
|
self.emit_warnings(events_1)
|
||||||
self.update_result(result, events_1, stdout_1, stderr_1, ignore_service_pull_events=True)
|
self.update_result(result, events_1, stdout_1, stderr_1, ignore_service_pull_events=True)
|
||||||
is_failed_1 = is_failed(events_1, rc_1)
|
is_failed_1 = is_failed(events_1, rc_1)
|
||||||
@ -545,7 +545,7 @@ class ServicesManager(BaseComposeManager):
|
|||||||
# Make sure all containers are stopped
|
# Make sure all containers are stopped
|
||||||
args_2 = self.get_stop_cmd(self.check_mode)
|
args_2 = self.get_stop_cmd(self.check_mode)
|
||||||
rc_2, stdout_2, stderr_2 = self.client.call_cli(*args_2, cwd=self.project_src)
|
rc_2, stdout_2, stderr_2 = self.client.call_cli(*args_2, cwd=self.project_src)
|
||||||
events_2 = self.parse_events(stderr_2, dry_run=self.check_mode)
|
events_2 = self.parse_events(stderr_2, dry_run=self.check_mode, nonzero_rc=rc_2 != 0)
|
||||||
self.emit_warnings(events_2)
|
self.emit_warnings(events_2)
|
||||||
self.update_result(result, events_2, stdout_2, stderr_2)
|
self.update_result(result, events_2, stdout_2, stderr_2)
|
||||||
else:
|
else:
|
||||||
@ -580,7 +580,7 @@ class ServicesManager(BaseComposeManager):
|
|||||||
result = dict()
|
result = dict()
|
||||||
args = self.get_restart_cmd(self.check_mode)
|
args = self.get_restart_cmd(self.check_mode)
|
||||||
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
||||||
events = self.parse_events(stderr, dry_run=self.check_mode)
|
events = self.parse_events(stderr, dry_run=self.check_mode, nonzero_rc=rc != 0)
|
||||||
self.emit_warnings(events)
|
self.emit_warnings(events)
|
||||||
self.update_result(result, events, stdout, stderr)
|
self.update_result(result, events, stdout, stderr)
|
||||||
self.update_failed(result, events, args, stdout, stderr, rc)
|
self.update_failed(result, events, args, stdout, stderr, rc)
|
||||||
@ -607,7 +607,7 @@ class ServicesManager(BaseComposeManager):
|
|||||||
result = dict()
|
result = dict()
|
||||||
args = self.get_down_cmd(self.check_mode)
|
args = self.get_down_cmd(self.check_mode)
|
||||||
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
||||||
events = self.parse_events(stderr, dry_run=self.check_mode)
|
events = self.parse_events(stderr, dry_run=self.check_mode, nonzero_rc=rc != 0)
|
||||||
self.emit_warnings(events)
|
self.emit_warnings(events)
|
||||||
self.update_result(result, events, stdout, stderr)
|
self.update_result(result, events, stdout, stderr)
|
||||||
self.update_failed(result, events, args, stdout, stderr, rc)
|
self.update_failed(result, events, args, stdout, stderr, rc)
|
||||||
|
|||||||
@ -165,7 +165,7 @@ class PullManager(BaseComposeManager):
|
|||||||
result = dict()
|
result = dict()
|
||||||
args = self.get_pull_cmd(self.check_mode)
|
args = self.get_pull_cmd(self.check_mode)
|
||||||
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
rc, stdout, stderr = self.client.call_cli(*args, cwd=self.project_src)
|
||||||
events = self.parse_events(stderr, dry_run=self.check_mode)
|
events = self.parse_events(stderr, dry_run=self.check_mode, nonzero_rc=rc != 0)
|
||||||
self.emit_warnings(events)
|
self.emit_warnings(events)
|
||||||
self.update_result(result, events, stdout, stderr, ignore_service_pull_events=self.policy != 'missing' and not self.check_mode)
|
self.update_result(result, events, stdout, stderr, ignore_service_pull_events=self.policy != 'missing' and not self.check_mode)
|
||||||
self.update_failed(result, events, args, stdout, stderr, rc)
|
self.update_failed(result, events, args, stdout, stderr, rc)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@ EXTRA_TEST_CASES = [
|
|||||||
'2.24.2-manual-build-dry-run',
|
'2.24.2-manual-build-dry-run',
|
||||||
'2.24.2',
|
'2.24.2',
|
||||||
True,
|
True,
|
||||||
|
False,
|
||||||
' DRY-RUN MODE - build service foobar \n'
|
' DRY-RUN MODE - build service foobar \n'
|
||||||
' DRY-RUN MODE - ==> ==> writing image dryRun-8843d7f92416211de9ebb963ff4ce28125932878 \n'
|
' DRY-RUN MODE - ==> ==> writing image dryRun-8843d7f92416211de9ebb963ff4ce28125932878 \n'
|
||||||
' DRY-RUN MODE - ==> ==> naming to my-python \n'
|
' DRY-RUN MODE - ==> ==> naming to my-python \n'
|
||||||
@ -80,6 +81,7 @@ EXTRA_TEST_CASES = [
|
|||||||
'2.20.0-manual-pull',
|
'2.20.0-manual-pull',
|
||||||
'2.20.0',
|
'2.20.0',
|
||||||
False,
|
False,
|
||||||
|
False,
|
||||||
'4f4fb700ef54 Waiting\n'
|
'4f4fb700ef54 Waiting\n'
|
||||||
'238022553356 Downloading 541B/541B\n'
|
'238022553356 Downloading 541B/541B\n'
|
||||||
'972e292d3a60 Downloading 106kB/10.43MB\n'
|
'972e292d3a60 Downloading 106kB/10.43MB\n'
|
||||||
@ -180,6 +182,7 @@ EXTRA_TEST_CASES = [
|
|||||||
'2.20.3-logrus-warn',
|
'2.20.3-logrus-warn',
|
||||||
'2.20.3',
|
'2.20.3',
|
||||||
False,
|
False,
|
||||||
|
False,
|
||||||
'time="2024-02-02T08:14:10+01:00" level=warning msg="a network with name influxNetwork exists but was not'
|
'time="2024-02-02T08:14:10+01:00" level=warning msg="a network with name influxNetwork exists but was not'
|
||||||
' created for project \\"influxdb\\".\\nSet `external: true` to use an existing network"\n',
|
' created for project \\"influxdb\\".\\nSet `external: true` to use an existing network"\n',
|
||||||
[],
|
[],
|
||||||
@ -192,6 +195,7 @@ EXTRA_TEST_CASES = [
|
|||||||
'2.20.3-image-warning-error',
|
'2.20.3-image-warning-error',
|
||||||
'2.20.3',
|
'2.20.3',
|
||||||
False,
|
False,
|
||||||
|
True,
|
||||||
" dummy3 Warning \n"
|
" dummy3 Warning \n"
|
||||||
" dummy2 Warning \n"
|
" dummy2 Warning \n"
|
||||||
" dummy Error \n"
|
" dummy Error \n"
|
||||||
@ -222,6 +226,7 @@ EXTRA_TEST_CASES = [
|
|||||||
'2.28.1-image-pull-skipped',
|
'2.28.1-image-pull-skipped',
|
||||||
'2.28.1',
|
'2.28.1',
|
||||||
False,
|
False,
|
||||||
|
False,
|
||||||
" bash_1 Skipped \n"
|
" bash_1 Skipped \n"
|
||||||
" bash_2 Pulling \n"
|
" bash_2 Pulling \n"
|
||||||
" bash_2 Pulled \n",
|
" bash_2 Pulled \n",
|
||||||
@ -247,23 +252,54 @@ EXTRA_TEST_CASES = [
|
|||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
# https://github.com/ansible-collections/community.docker/issues/948
|
||||||
|
'2.28.1-unknown', # TODO: find out actual version!
|
||||||
|
'2.28.1', # TODO: find out actual version!
|
||||||
|
False,
|
||||||
|
True,
|
||||||
|
" prometheus Pulling \n"
|
||||||
|
" prometheus Pulled \n"
|
||||||
|
"network internet-monitoring-front-tier was found but has incorrect label com.docker.compose.network set to \"internet-monitoring-front-tier\"\n",
|
||||||
|
[
|
||||||
|
Event(
|
||||||
|
'service',
|
||||||
|
'prometheus',
|
||||||
|
'Pulling',
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
Event(
|
||||||
|
'service',
|
||||||
|
'prometheus',
|
||||||
|
'Pulled',
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
Event(
|
||||||
|
'unknown',
|
||||||
|
'',
|
||||||
|
'Error',
|
||||||
|
'network internet-monitoring-front-tier was found but has incorrect label com.docker.compose.network set to "internet-monitoring-front-tier"',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
_ALL_TEST_CASES = EVENT_TEST_CASES + EXTRA_TEST_CASES
|
_ALL_TEST_CASES = EVENT_TEST_CASES + EXTRA_TEST_CASES
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'test_id, compose_version, dry_run, stderr, events, warnings',
|
'test_id, compose_version, dry_run, nonzero_rc, stderr, events, warnings',
|
||||||
_ALL_TEST_CASES,
|
_ALL_TEST_CASES,
|
||||||
ids=[tc[0] for tc in _ALL_TEST_CASES],
|
ids=[tc[0] for tc in _ALL_TEST_CASES],
|
||||||
)
|
)
|
||||||
def test_parse_events(test_id, compose_version, dry_run, stderr, events, warnings):
|
def test_parse_events(test_id, compose_version, dry_run, nonzero_rc, stderr, events, warnings):
|
||||||
collected_warnings = []
|
collected_warnings = []
|
||||||
|
|
||||||
def collect_warning(msg):
|
def collect_warning(msg):
|
||||||
collected_warnings.append(msg)
|
collected_warnings.append(msg)
|
||||||
|
|
||||||
collected_events = parse_events(stderr, dry_run=dry_run, warn_function=collect_warning)
|
collected_events = parse_events(stderr, dry_run=dry_run, warn_function=collect_warning, nonzero_rc=nonzero_rc)
|
||||||
|
|
||||||
print(collected_events)
|
print(collected_events)
|
||||||
print(collected_warnings)
|
print(collected_warnings)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user