From 62d8c8fde6a76d9c567ded381e9b34dad69afcd6 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 2 Aug 2018 13:30:57 -0400 Subject: [PATCH] more useful messages when module failure (#43576) * more useful messages when module failure specially if the 'interpreter' is not found * 1 less var * shebang can be none * remove typoes --- changelogs/fragments/missing_interpreter.yml | 2 ++ lib/ansible/plugins/action/__init__.py | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/missing_interpreter.yml diff --git a/changelogs/fragments/missing_interpreter.yml b/changelogs/fragments/missing_interpreter.yml new file mode 100644 index 00000000000..38e711b5e1b --- /dev/null +++ b/changelogs/fragments/missing_interpreter.yml @@ -0,0 +1,2 @@ +bugfixes: + - nicer message when we are missing interpreter diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 72dd769686a..41ac119d95f 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -60,6 +60,8 @@ class ActionBase(with_metaclass(ABCMeta, object)): # Backwards compat: self._display isn't really needed, just import the global display and use that. self._display = display + self._used_interpreter = None + @abstractmethod def run(self, tmp=None, task_vars=None): """ Action Plugins should implement this method to perform their @@ -753,6 +755,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): if not shebang and module_style != 'binary': raise AnsibleError("module (%s) is missing interpreter line" % module_name) + self._used_interpreter = shebang remote_module_path = None if not self._is_pipelining_enabled(module_style, wrap_async): @@ -896,12 +899,20 @@ class ActionBase(with_metaclass(ABCMeta, object)): except ValueError: # not valid json, lets try to capture error data = dict(failed=True, _ansible_parsed=False) - data['msg'] = "MODULE FAILURE" data['module_stdout'] = res.get('stdout', u'') if 'stderr' in res: data['module_stderr'] = res['stderr'] if res['stderr'].startswith(u'Traceback'): data['exception'] = res['stderr'] + + # try to figure out if we are missing interpreter + if self._used_interpreter is not None and '%s: No such file or directory' % self._used_interpreter.lstrip('!#') in data['module_stderr']: + data['msg'] = "The module failed to execute correctly, you probably need to set the interpreter." + else: + data['msg'] = "MODULE FAILURE" + + data['msg'] += '\nSee stdout/stderr for the exact error' + if 'rc' in res: data['rc'] = res['rc'] return data