From f10918475379ec2314b62bbe6d2053f344cc8368 Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Tue, 25 Jun 2019 17:16:46 -0700 Subject: [PATCH] Recognize module tracebacks on stdout and stderr. Module tracebacks may be reported on stdout instead of stderr when using some connection plugins. For example, the ssh connection plugin will report tracebacks on stdout due to use of the -tt option. This change results in tracebacks being recognized on both stdout and stderr, instead of the previous behavior of just stderr. ci_complete --- changelogs/fragments/module-exceptions.yaml | 2 ++ lib/ansible/plugins/action/__init__.py | 4 ++++ .../targets/module_tracebacks/aliases | 2 ++ .../targets/module_tracebacks/inventory | 5 +++++ .../targets/module_tracebacks/runme.sh | 5 +++++ .../targets/module_tracebacks/traceback.yml | 21 +++++++++++++++++++ 6 files changed, 39 insertions(+) create mode 100644 changelogs/fragments/module-exceptions.yaml create mode 100644 test/integration/targets/module_tracebacks/aliases create mode 100644 test/integration/targets/module_tracebacks/inventory create mode 100755 test/integration/targets/module_tracebacks/runme.sh create mode 100644 test/integration/targets/module_tracebacks/traceback.yml diff --git a/changelogs/fragments/module-exceptions.yaml b/changelogs/fragments/module-exceptions.yaml new file mode 100644 index 00000000000..f5fc916aa47 --- /dev/null +++ b/changelogs/fragments/module-exceptions.yaml @@ -0,0 +1,2 @@ +bugfixes: + - Module tracebacks are now recognized on stdout and stderr, intead of just on stderr. diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 752829ddf45..405165a5cc9 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -992,6 +992,10 @@ class ActionBase(with_metaclass(ABCMeta, object)): if res['stderr'].startswith(u'Traceback'): data['exception'] = res['stderr'] + # in some cases a traceback will arrive on stdout instead of stderr, such as when using ssh with -tt + if 'exception' not in data and data['module_stdout'].startswith(u'Traceback'): + data['exception'] = data['module_stdout'] + # The default data['msg'] = "MODULE FAILURE" diff --git a/test/integration/targets/module_tracebacks/aliases b/test/integration/targets/module_tracebacks/aliases new file mode 100644 index 00000000000..93fb6f10c18 --- /dev/null +++ b/test/integration/targets/module_tracebacks/aliases @@ -0,0 +1,2 @@ +shippable/posix/group4 +needs/ssh diff --git a/test/integration/targets/module_tracebacks/inventory b/test/integration/targets/module_tracebacks/inventory new file mode 100644 index 00000000000..91565267790 --- /dev/null +++ b/test/integration/targets/module_tracebacks/inventory @@ -0,0 +1,5 @@ +testhost_local ansible_connection=local +testhost_ssh ansible_connection=ssh ansible_host=localhost + +[all:vars] +ansible_python_interpreter="{{ ansible_playbook_python }}" diff --git a/test/integration/targets/module_tracebacks/runme.sh b/test/integration/targets/module_tracebacks/runme.sh new file mode 100755 index 00000000000..b8ac8068b0b --- /dev/null +++ b/test/integration/targets/module_tracebacks/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ansible-playbook traceback.yml -i inventory "$@" diff --git a/test/integration/targets/module_tracebacks/traceback.yml b/test/integration/targets/module_tracebacks/traceback.yml new file mode 100644 index 00000000000..b1f0b5164a8 --- /dev/null +++ b/test/integration/targets/module_tracebacks/traceback.yml @@ -0,0 +1,21 @@ +- hosts: all + gather_facts: no + tasks: + - name: intentionally fail module execution + ping: + data: crash + ignore_errors: yes + register: ping + +- hosts: localhost + gather_facts: no + tasks: + - name: verify exceptions were properly captured + assert: + that: + - hostvars.testhost_local.ping is failed + - "'boom' in hostvars.testhost_local.ping.exception" + - "'boom' in hostvars.testhost_local.ping.module_stderr" + - hostvars.testhost_ssh.ping is failed + - "'boom' in hostvars.testhost_ssh.ping.exception" + - "'boom' in hostvars.testhost_ssh.ping.module_stdout"