Merge "Don't try to split localhost log lines" into feature/zuulv3
diff --git a/zuul/ansible/library/command.py b/zuul/ansible/library/command.py
index 99392cc..8bec502 100644
--- a/zuul/ansible/library/command.py
+++ b/zuul/ansible/library/command.py
@@ -148,7 +148,7 @@
         self.logfile_name = LOG_STREAM_FILE.format(log_uuid=log_uuid)
 
     def __enter__(self):
-        self.logfile = open(self.logfile_name, 'a', 0)
+        self.logfile = open(self.logfile_name, 'ab', buffering=0)
         return self
 
     def __exit__(self, etype, value, tb):
@@ -161,7 +161,7 @@
         # consistent.
         ts = datetime.datetime.now()
         outln = '%s | %s' % (ts, ln)
-        self.logfile.write(outln)
+        self.logfile.write(outln.encode('utf-8'))
 
 
 def follow(fd, log_uuid):
@@ -396,6 +396,7 @@
         self.log("Error Executing CMD:%s Exception:%s" % (clean_args, to_native(e)))
         self.fail_json(rc=e.errno, msg=to_native(e), cmd=clean_args)
     except Exception:
+        e = get_exception()
         self.log("Error Executing CMD:%s Exception:%s" % (clean_args, to_native(traceback.format_exc())))
         self.fail_json(rc=257, msg=to_native(e), exception=traceback.format_exc(), cmd=clean_args)
 
diff --git a/zuul/executor/server.py b/zuul/executor/server.py
index bc4ebd3..902abd9 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
@@ -34,6 +35,7 @@
 import zuul.ansible
 from zuul.lib import commandsocket
 
+BUFFER_LINES_FOR_SYNTAX = 200
 COMMANDS = ['stop', 'pause', 'unpause', 'graceful', 'verbose',
             'unverbose', 'keep', 'nokeep']
 DEFAULT_FINGER_PORT = 79
@@ -515,10 +517,10 @@
         self.verbose = False
 
     def keep(self):
-        self.keep_jobdirs = True
+        self.keep_jobdir = True
 
     def nokeep(self):
-        self.keep_jobdirs = False
+        self.keep_jobdir = False
 
     def join(self):
         self.update_thread.join()
@@ -1314,13 +1316,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")
@@ -1343,6 +1348,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)