Append ansible yaml parse errors to job log file
If ansible can't parse the yaml, it dies immediately with return code 4.
This happens before callback plugins, so nothing gets captured to
the log. Save the first 200 lines in case there result is a syntax
error. If we detect one, append directly to the job's log file.
Change-Id: I059a61357c471f61485f141f92c35b2bcf2d168d
diff --git a/zuul/executor/server.py b/zuul/executor/server.py
index 94678d7..0a43ca8 100644
--- a/zuul/executor/server.py
+++ b/zuul/executor/server.py
@@ -13,6 +13,7 @@
# under the License.
import collections
+import datetime
import json
import logging
import os
@@ -33,6 +34,7 @@
import zuul.ansible
from zuul.lib import commandsocket
+BUFFER_LINES_FOR_SYNTAX = 200
COMMANDS = ['stop', 'pause', 'unpause', 'graceful', 'verbose',
'unverbose']
@@ -1298,13 +1300,16 @@
env=env_copy,
)
+ syntax_buffer = []
ret = None
if timeout:
watchdog = Watchdog(timeout, self._ansibleTimeout,
("Ansible timeout exceeded",))
watchdog.start()
try:
- for line in iter(self.proc.stdout.readline, b''):
+ for idx, line in enumerate(iter(self.proc.stdout.readline, b'')):
+ if idx < BUFFER_LINES_FOR_SYNTAX:
+ syntax_buffer.append(line)
line = line[:1024].rstrip()
self.log.debug("Ansible output: %s" % (line,))
self.log.debug("Ansible output terminated")
@@ -1327,6 +1332,18 @@
elif ret == -9:
# Received abort request.
return (self.RESULT_ABORTED, None)
+ elif ret == 4:
+ # Ansible could not parse the yaml.
+ self.log.debug("Ansible parse error")
+ # TODO(mordred) If/when we rework use of logger in ansible-playbook
+ # we'll want to change how this works to use that as well. For now,
+ # this is what we need to do.
+ with open(self.jobdir.job_output_file, 'a') as job_output:
+ job_output.write("{now} | ANSIBLE PARSE ERROR\n".format(
+ now=datetime.datetime.now()))
+ for line in syntax_buffer:
+ job_output.write("{now} | {line}".format(
+ now=datetime.datetime.now(), line=line))
return (self.RESULT_NORMAL, ret)