Use ssh for git-upload-pack

Currently git-upload-pack is executed via an unauthenticated https
call. This doesn't work if the project is not world readable.
Switching git-upload-pack to use ssh like all other commands resolves
this issue.

This is a port of I26bc6c8937a6b8cdd2577f32c67b708211144fbd to zuulv3
branch.

Change-Id: If3541faf1f866a40d750c9c899f399a14bf30553
diff --git a/tests/base.py b/tests/base.py
index 27479b0..c3b8a9b 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -68,6 +68,7 @@
 import zuul.merger.client
 import zuul.merger.merger
 import zuul.merger.server
+import zuul.model
 import zuul.nodepool
 import zuul.zk
 from zuul.exceptions import MergeFailure
@@ -530,6 +531,18 @@
     def _start_watcher_thread(self, *args, **kw):
         pass
 
+    def _uploadPack(self, project):
+        ret = ('00a31270149696713ba7e06f1beb760f20d359c4abed HEAD\x00'
+               'multi_ack thin-pack side-band side-band-64k ofs-delta '
+               'shallow no-progress include-tag multi_ack_detailed no-done\n')
+        path = os.path.join(self.upstream_root, project.name)
+        repo = git.Repo(path)
+        for ref in repo.refs:
+            r = ref.object.hexsha + ' ' + ref.path + '\n'
+            ret += '%04x%s' % (len(r) + 4, r)
+        ret += '0000'
+        return ret
+
     def getGitUrl(self, project):
         return os.path.join(self.upstream_root, project.name)
 
@@ -952,28 +965,6 @@
                 (self.result, self.name, self.uuid, self.changes))
 
 
-class FakeURLOpener(object):
-    def __init__(self, upstream_root, url):
-        self.upstream_root = upstream_root
-        self.url = url
-
-    def read(self):
-        res = urllib.parse.urlparse(self.url)
-        path = res.path
-        project = '/'.join(path.split('/')[2:-2])
-        ret = '001e# service=git-upload-pack\n'
-        ret += ('000000a31270149696713ba7e06f1beb760f20d359c4abed HEAD\x00'
-                'multi_ack thin-pack side-band side-band-64k ofs-delta '
-                'shallow no-progress include-tag multi_ack_detailed no-done\n')
-        path = os.path.join(self.upstream_root, project)
-        repo = git.Repo(path)
-        for ref in repo.refs:
-            r = ref.object.hexsha + ' ' + ref.path + '\n'
-            ret += '%04x%s' % (len(r) + 4, r)
-        ret += '0000'
-        return ret
-
-
 class FakeStatsd(threading.Thread):
     def __init__(self):
         threading.Thread.__init__(self)
@@ -1805,14 +1796,6 @@
         self.configure_connections()
         self.sched.registerConnections(self.connections, self.webapp)
 
-        def URLOpenerFactory(*args, **kw):
-            if isinstance(args[0], urllib.request.Request):
-                return old_urlopen(*args, **kw)
-            return FakeURLOpener(self.upstream_root, *args, **kw)
-
-        old_urlopen = urllib.request.urlopen
-        urllib.request.urlopen = URLOpenerFactory
-
         self.executor_server = RecordingExecutorServer(
             self.config, self.connections,
             jobdir_root=self.test_root,
diff --git a/zuul/driver/gerrit/gerritconnection.py b/zuul/driver/gerrit/gerritconnection.py
index dcbc172..c3c8584 100644
--- a/zuul/driver/gerrit/gerritconnection.py
+++ b/zuul/driver/gerrit/gerritconnection.py
@@ -19,7 +19,6 @@
 import threading
 import time
 from six.moves import queue as Queue
-from six.moves import urllib
 from six.moves import shlex_quote
 import paramiko
 import logging
@@ -699,6 +698,11 @@
             chunk, more_changes = _query_chunk("%s %s" % (query, resume))
         return alldata
 
+    def _uploadPack(self, project_name):
+        cmd = "git-upload-pack %s" % project_name
+        out, err = self._ssh(cmd, "0000")
+        return out
+
     def _open(self):
         client = paramiko.SSHClient()
         client.load_system_host_keys()
@@ -738,19 +742,13 @@
         return (out, err)
 
     def getInfoRefs(self, project):
-        url = "%s/p/%s/info/refs?service=git-upload-pack" % (
-            self.baseurl, project.name)
         try:
-            data = urllib.request.urlopen(url).read()
+            data = self._uploadPack(project)
         except:
-            self.log.error("Cannot get references from %s" % url)
-            raise  # keeps urllib error informations
+            self.log.error("Cannot get references from %s" % project)
+            raise  # keeps error information
         ret = {}
-        read_headers = False
         read_advertisement = False
-        if data[4] != '#':
-            raise Exception("Gerrit repository does not support "
-                            "git-upload-pack")
         i = 0
         while i < len(data):
             if len(data) - i < 4:
@@ -766,10 +764,6 @@
                 raise Exception("Invalid data in info/refs")
             line = data[i:i + plen]
             i += plen
-            if not read_headers:
-                if plen == 0:
-                    read_headers = True
-                continue
             if not read_advertisement:
                 read_advertisement = True
                 continue