Merge "Put script string in directly instead of in files"
diff --git a/zuul/launcher/ansiblelaunchserver.py b/zuul/launcher/ansiblelaunchserver.py
index 753344e..9a0cdaf 100644
--- a/zuul/launcher/ansiblelaunchserver.py
+++ b/zuul/launcher/ansiblelaunchserver.py
@@ -12,6 +12,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+import getopt
 import json
 import logging
 import os
@@ -25,7 +26,6 @@
 import time
 import traceback
 import Queue
-import uuid
 
 import gear
 import yaml
@@ -52,6 +52,45 @@
     return bool(x)
 
 
+def deal_with_shebang(data):
+    # Ansible shell blocks do not honor shebang lines. That's fine - but
+    # we do have a bunch of scripts that have either nothing, -x, -xe,
+    # -ex or -eux. Transform those into leading set commands
+    if not data.startswith('#!'):
+        return (None, data)
+    data_lines = data.split('\n')
+    data_lines.reverse()
+    shebang = data_lines.pop()
+    split_line = shebang.split()
+    # Strip the # and the !
+    executable = split_line[0][2:]
+    if executable == '/bin/sh':
+        # Ansible default
+        executable = None
+    if len(split_line) > 1:
+        flag_x = False
+        flag_e = False
+        flag_u = False
+        optlist, args = getopt.getopt(split_line[1:], 'uex')
+        for opt, _ in optlist:
+            if opt == '-x':
+                flag_x = True
+            elif opt == '-e':
+                flag_e = True
+            elif opt == '-u':
+                flag_u = True
+
+        if flag_x:
+            data_lines.append('set -x')
+        if flag_e:
+            data_lines.append('set -e')
+        if flag_u:
+            data_lines.append('set -u')
+    data_lines.reverse()
+    data = '\n'.join(data_lines)
+    return (executable, data)
+
+
 class LaunchGearWorker(gear.Worker):
     def __init__(self, *args, **kw):
         self.__launch_server = kw.pop('launch_server')
@@ -116,9 +155,7 @@
         self.playbook = os.path.join(self.ansible_root, 'playbook')
         self.post_playbook = os.path.join(self.ansible_root, 'post_playbook')
         self.config = os.path.join(self.ansible_root, 'ansible.cfg')
-        self.script_root = os.path.join(self.ansible_root, 'scripts')
         self.ansible_log = os.path.join(self.ansible_root, 'ansible_log.txt')
-        os.makedirs(self.script_root)
         self.staging_root = os.path.join(self.root, 'staging')
         os.makedirs(self.staging_root)
 
@@ -1272,22 +1309,10 @@
 
     def _makeBuilderTask(self, jobdir, builder, parameters):
         tasks = []
-        script_fn = '%s.sh' % str(uuid.uuid4().hex)
-        script_path = os.path.join(jobdir.script_root, script_fn)
-        with open(script_path, 'w') as script:
-            data = builder['shell']
-            if not data.startswith('#!'):
-                data = '#!/bin/bash -x\n %s' % (data,)
-            script.write(data)
 
-        remote_path = os.path.join('/tmp', script_fn)
-        copy = dict(src=script_path,
-                    dest=remote_path,
-                    mode=0o555)
-        task = dict(copy=copy)
-        tasks.append(task)
+        (executable, shell) = deal_with_shebang(builder['shell'])
 
-        task = dict(command=remote_path)
+        task = dict(shell=shell)
         task['name'] = ('command with {{ timeout | int - elapsed_time }} '
                         'second timeout')
         task['when'] = '{{ elapsed_time < timeout | int }}'
@@ -1295,11 +1320,9 @@
         task['poll'] = 5
         task['environment'] = parameters
         task['args'] = dict(chdir=parameters['WORKSPACE'])
-        tasks.append(task)
+        if executable:
+            task['args']['executable'] = executable
 
-        filetask = dict(path=remote_path,
-                        state='absent')
-        task = dict(file=filetask)
         tasks.append(task)
 
         return tasks