Merge "Add host ssh keys to known hosts" into feature/zuulv3
diff --git a/zuul/ansible/action/add_host.py b/zuul/ansible/action/add_host.py
index e41e4e1..83cfa39 100644
--- a/zuul/ansible/action/add_host.py
+++ b/zuul/ansible/action/add_host.py
@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this software.  If not, see <http://www.gnu.org/licenses/>.
 
-from zuul.ansible.plugins.action import add_host
+from ansible.plugins.action import add_host
 
 
 class ActionModule(add_host.ActionModule):
diff --git a/zuul/ansible/action/assemble.py b/zuul/ansible/action/assemble.py
index d0bff37..2280191 100644
--- a/zuul/ansible/action/assemble.py
+++ b/zuul/ansible/action/assemble.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import assemble
+from ansible.plugins.action import assemble
 
 
 class ActionModule(assemble.ActionModule):
diff --git a/zuul/ansible/action/copy.py b/zuul/ansible/action/copy.py
index 5dc9fa8..c90ebc7 100644
--- a/zuul/ansible/action/copy.py
+++ b/zuul/ansible/action/copy.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import copy
+from ansible.plugins.action import copy
 
 
 class ActionModule(copy.ActionModule):
diff --git a/zuul/ansible/action/fetch.py b/zuul/ansible/action/fetch.py
index fe06c3b..2fc3ce5 100644
--- a/zuul/ansible/action/fetch.py
+++ b/zuul/ansible/action/fetch.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import fetch
+from ansible.plugins.action import fetch
 
 
 class ActionModule(fetch.ActionModule):
diff --git a/zuul/ansible/action/include_vars.py b/zuul/ansible/action/include_vars.py
index aa0e7d8..2706a1f 100644
--- a/zuul/ansible/action/include_vars.py
+++ b/zuul/ansible/action/include_vars.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import include_vars
+from ansible.plugins.action import include_vars
 
 
 class ActionModule(include_vars.ActionModule):
diff --git a/zuul/ansible/action/network.py b/zuul/ansible/action/network.py
index 31a8739..18de5a5 100644
--- a/zuul/ansible/action/network.py
+++ b/zuul/ansible/action/network.py
@@ -14,7 +14,7 @@
 # along with this software.  If not, see <http://www.gnu.org/licenses/>.
 
 
-from zuul.ansible.plugins.action import network
+from ansible.plugins.action import network
 
 
 class ActionModule(network.ActionModule):
diff --git a/zuul/ansible/action/normal.py b/zuul/ansible/action/normal.py
index d4b2396..a50125c 100644
--- a/zuul/ansible/action/normal.py
+++ b/zuul/ansible/action/normal.py
@@ -13,8 +13,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this software.  If not, see <http://www.gnu.org/licenses/>.
 
-
-from zuul.ansible.plugins.action import normal
+# TODO(mordred) Figure out how to not need to do this to get the base class
+import ansible.plugins.action
+import imp
+normal = imp.load_module(
+    'ansible.plugins.action.normal',
+    *imp.find_module('normal', ansible.plugins.action.__path__))
 
 
 class ActionModule(normal.ActionModule):
diff --git a/zuul/ansible/action/patch.py b/zuul/ansible/action/patch.py
index d630844..a83a9e1 100644
--- a/zuul/ansible/action/patch.py
+++ b/zuul/ansible/action/patch.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import patch
+from ansible.plugins.action import patch
 
 
 class ActionModule(patch.ActionModule):
diff --git a/zuul/ansible/action/script.py b/zuul/ansible/action/script.py
index bd3d5d5..ee5b186 100644
--- a/zuul/ansible/action/script.py
+++ b/zuul/ansible/action/script.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import copy
+from ansible.plugins.action import copy
 
 
 class ActionModule(copy.ActionModule):
diff --git a/zuul/ansible/action/synchronize.py b/zuul/ansible/action/synchronize.py
index cbb7ea2..8799eb9 100644
--- a/zuul/ansible/action/synchronize.py
+++ b/zuul/ansible/action/synchronize.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import synchronize
+from ansible.plugins.action import synchronize
 
 
 class ActionModule(synchronize.ActionModule):
diff --git a/zuul/ansible/action/template.py b/zuul/ansible/action/template.py
index 96471ae..cd3b10e 100644
--- a/zuul/ansible/action/template.py
+++ b/zuul/ansible/action/template.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import template
+from ansible.plugins.action import template
 
 
 class ActionModule(template.ActionModule):
diff --git a/zuul/ansible/action/unarchive.py b/zuul/ansible/action/unarchive.py
index c3f6e91..d6b2190 100644
--- a/zuul/ansible/action/unarchive.py
+++ b/zuul/ansible/action/unarchive.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import unarchive
+from ansible.plugins.action import unarchive
 
 
 class ActionModule(unarchive.ActionModule):
diff --git a/zuul/ansible/action/win_copy.py b/zuul/ansible/action/win_copy.py
index eef3a1c..c051630 100644
--- a/zuul/ansible/action/win_copy.py
+++ b/zuul/ansible/action/win_copy.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import win_copy
+from ansible.plugins.action import win_copy
 
 
 class ActionModule(win_copy.ActionModule):
diff --git a/zuul/ansible/action/win_template.py b/zuul/ansible/action/win_template.py
index 2a47216..de88eb8 100644
--- a/zuul/ansible/action/win_template.py
+++ b/zuul/ansible/action/win_template.py
@@ -15,7 +15,7 @@
 
 
 from zuul.ansible import paths
-from zuul.ansible.plugins.action import win_template
+from ansible.plugins.action import win_template
 
 
 class ActionModule(win_template.ActionModule):
diff --git a/zuul/launcher/server.py b/zuul/launcher/server.py
index 8a8e00c..8db41de 100644
--- a/zuul/launcher/server.py
+++ b/zuul/launcher/server.py
@@ -916,5 +916,7 @@
         # TODOv3: get this from the job
         timeout = 60
 
+        # TODO(mordred) Action plugin python import is breaking - troubleshoot
+        # and set this back to secure=True
         return self.runAnsible(
-            cmd=cmd, timeout=timeout, secure=playbook.secure)
+            cmd=cmd, timeout=timeout, secure=True)
diff --git a/zuul/merger/merger.py b/zuul/merger/merger.py
index f970b03..658fd64 100644
--- a/zuul/merger/merger.py
+++ b/zuul/merger/merger.py
@@ -214,24 +214,17 @@
         self.working_root = working_root
         if not os.path.exists(working_root):
             os.makedirs(working_root)
-        self._makeSSHWrappers(working_root, connections)
+        self.connections = connections
         self.email = email
         self.username = username
 
-    def _makeSSHWrappers(self, working_root, connections):
-        for connection_name, connection in connections.connections.items():
-            sshkey = connection.connection_config.get('sshkey')
-            if sshkey:
-                self._makeSSHWrapper(sshkey, working_root, connection_name)
-
-    def _makeSSHWrapper(self, key, merge_root, connection_name='default'):
-        wrapper_name = '.ssh_wrapper_%s' % connection_name
-        name = os.path.join(merge_root, wrapper_name)
-        fd = open(name, 'w')
-        fd.write('#!/bin/bash\n')
-        fd.write('ssh -i %s $@\n' % key)
-        fd.close()
-        os.chmod(name, 0o755)
+    def _get_ssh_cmd(self, connection_name):
+        sshkey = self.connections.connections.get(connection_name).\
+            connection_config.get('sshkey')
+        if sshkey:
+            return 'ssh -i %s' % sshkey
+        else:
+            return None
 
     def addProject(self, project, url):
         repo = None
@@ -299,30 +292,26 @@
 
         return commit
 
-    def _setGitSsh(self, connection_name):
-        wrapper_name = '.ssh_wrapper_%s' % connection_name
-        name = os.path.join(self.working_root, wrapper_name)
-        if os.path.isfile(name):
-            os.environ['GIT_SSH'] = name
-        elif 'GIT_SSH' in os.environ:
-            del os.environ['GIT_SSH']
-
     def _mergeItem(self, item, recent):
         self.log.debug("Processing refspec %s for project %s / %s ref %s" %
                        (item['refspec'], item['project'], item['branch'],
                         item['ref']))
-        self._setGitSsh(item['connection_name'])
         repo = self.getRepo(item['project'], item['url'])
         key = (item['project'], item['branch'])
+
         # See if we have a commit for this change already in this repo
         zuul_ref = item['branch'] + '/' + item['ref']
-        commit = repo.getCommitFromRef(zuul_ref)
-        if commit:
-            self.log.debug("Found commit %s for ref %s" % (commit, zuul_ref))
-            # Store this as the most recent commit for this
-            # project-branch
-            recent[key] = commit
-            return commit
+        with repo.createRepoObject().git.custom_environment(
+            GIT_SSH_COMMAND=self._get_ssh_cmd(item['connection_name'])):
+            commit = repo.getCommitFromRef(zuul_ref)
+            if commit:
+                self.log.debug(
+                    "Found commit %s for ref %s" % (commit, zuul_ref))
+                # Store this as the most recent commit for this
+                # project-branch
+                recent[key] = commit
+                return commit
+
         self.log.debug("Unable to find commit for ref %s" % (zuul_ref,))
         # We need to merge the change
         # Get the most recent commit for this project-branch
@@ -340,24 +329,26 @@
         else:
             self.log.debug("Found base commit %s for %s" % (base, key,))
         # Merge the change
-        commit = self._mergeChange(item, base)
-        if not commit:
-            return None
-        # Store this commit as the most recent for this project-branch
-        recent[key] = commit
-        # Set the Zuul ref for this item to point to the most recent
-        # commits of each project-branch
-        for key, mrc in recent.items():
-            project, branch = key
-            try:
-                repo = self.getRepo(project, None)
-                zuul_ref = branch + '/' + item['ref']
-                repo.createZuulRef(zuul_ref, mrc)
-            except Exception:
-                self.log.exception("Unable to set zuul ref %s for "
-                                   "item %s" % (zuul_ref, item))
+        with repo.createRepoObject().git.custom_environment(
+            GIT_SSH_COMMAND=self._get_ssh_cmd(item['connection_name'])):
+            commit = self._mergeChange(item, base)
+            if not commit:
                 return None
-        return commit
+            # Store this commit as the most recent for this project-branch
+            recent[key] = commit
+            # Set the Zuul ref for this item to point to the most recent
+            # commits of each project-branch
+            for key, mrc in recent.items():
+                project, branch = key
+                try:
+                    repo = self.getRepo(project, None)
+                    zuul_ref = branch + '/' + item['ref']
+                    repo.createZuulRef(zuul_ref, mrc)
+                except Exception:
+                    self.log.exception("Unable to set zuul ref %s for "
+                                       "item %s" % (zuul_ref, item))
+                    return None
+            return commit
 
     def mergeChanges(self, items, files=None):
         recent = {}