Me again.
[…]
Right now, I’ve traced it back to some problem with the new ‘become’ logic putting additional prompts into the stdout, so that stdout isn’t valid JSON any more. You can see this by applying the following hack to the latest devel checkout:
[…]
Now I only have to understand if that become-successkey has to be there or how to strip it…
Turns out, for “regular” tasks, the “stdout” gets set/filtered in lib/ansible/plugins/action/init.py, _execute_module() by this code:
data = json.loads(self._filter_leading_non_json_lines(res.get(‘stdout’, ‘’)))
where the _filter_leading_non_json_lines function states:
Used to avoid random output from SSH at the top of JSON output, like messages from
tcagetattr, or where dropbear spews MOTD on every single command (which is nuts).
need to filter anything which starts not with ‘{’, ‘[’, ', ‘=’ or is an empty line.
filter only leading lines since multiline JSON is valid.
Apparently, this unintentionally (?) also stripped out the BECOME_SUCCESS message - except for async tasks.
Calling the same wrapper fixes my problem. The code has some special cases for skipping stuff if we’re going to use sudo while still connecting as root, which I am (rescue system, root’s the only user there is), so the actual problem might lie elsewhere, though. This feels like a really bad hack, and I’m by far not sure whether my hack breaks more than it fixed, so I’m not going to push this upstream.
— a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -320,7 +320,7 @@ class TaskExecutor:
the async_wrapper module returns dumped JSON via its stdout
response, so we parse it here and replace the result
try:
- result = json.loads(result.get(‘stdout’))
- result = json.loads(self._handler._filter_leading_non_json_lines(result.get(‘stdout’)))
except (TypeError, ValueError) as e:
return dict(failed=True, msg=“The async task did not return valid JSON: %s” % str(e))
hope this helps someone and/or helps diagnosing the problem.
Uli / youam