Merge "Quote message when reporting to Gerrit" into feature/zuulv3
diff --git a/tests/base.py b/tests/base.py
index 9bacf21..0105ffa 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -496,11 +496,6 @@
             if cat != 'submit':
                 change.addApproval(cat, action[cat], username=self.user)
 
-        # TODOv3(jeblair): can this be removed?
-        if 'label' in action:
-            parts = action['label'].split('=')
-            change.addApproval(parts[0], parts[2], username=self.user)
-
         change.messages.append(message)
 
         if 'submit' in action:
diff --git a/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml b/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
index 34bd9cd..2bb61ee 100644
--- a/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/single-tenant/git/common-config/zuul.yaml
@@ -69,7 +69,6 @@
 
 - job:
     name: project1-project2-integration
-    queue-name: integration
 
 - job:
     name: project-testfile
diff --git a/tests/fixtures/layouts/ignore-dependencies.yaml b/tests/fixtures/layouts/ignore-dependencies.yaml
index 02aea36..86fe674 100644
--- a/tests/fixtures/layouts/ignore-dependencies.yaml
+++ b/tests/fixtures/layouts/ignore-dependencies.yaml
@@ -32,7 +32,6 @@
 
 - job:
     name: project1-project2-integration
-    queue-name: integration
 
 - project:
     name: org/project1
diff --git a/tox.ini b/tox.ini
index 174a496..6a50c6d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -51,6 +51,6 @@
 [flake8]
 # These are ignored intentionally in openstack-infra projects;
 # please don't submit patches that solely correct them or enable them.
-ignore = E305,E125,E129,E402,H,F405,W503
+ignore = E305,E125,E129,E402,H,W503
 show-source = True
 exclude = .venv,.tox,dist,doc,build,*.egg
diff --git a/zuul/ansible/library/zuul_afs.py b/zuul/ansible/library/zuul_afs.py
index 3ba426b..710c15d 100644
--- a/zuul/ansible/library/zuul_afs.py
+++ b/zuul/ansible/library/zuul_afs.py
@@ -116,6 +116,7 @@
     module.exit_json(changed=True, build_roots=output)
 
 from ansible.module_utils.basic import *  # noqa
+from ansible.module_utils.basic import AnsibleModule
 
 if __name__ == '__main__':
     main()
diff --git a/zuul/ansible/library/zuul_console.py b/zuul/ansible/library/zuul_console.py
index 1932cf9..b1dc2d9 100644
--- a/zuul/ansible/library/zuul_console.py
+++ b/zuul/ansible/library/zuul_console.py
@@ -17,8 +17,10 @@
 
 import os
 import sys
+import select
 import socket
 import threading
+import time
 
 LOG_STREAM_FILE = '/tmp/console.log'
 LOG_STREAM_PORT = 19885
@@ -181,6 +183,7 @@
     s.run()
 
 from ansible.module_utils.basic import *  # noqa
+from ansible.module_utils.basic import AnsibleModule
 
 if __name__ == '__main__':
     main()
diff --git a/zuul/cmd/__init__.py b/zuul/cmd/__init__.py
old mode 100644
new mode 100755
index f2a2612..d31c5b8
--- a/zuul/cmd/__init__.py
+++ b/zuul/cmd/__init__.py
@@ -98,6 +98,6 @@
         else:
             logging.basicConfig(level=logging.DEBUG)
 
-    def configure_connections(self):
+    def configure_connections(self, source_only=False):
         self.connections = zuul.lib.connections.ConnectionRegistry()
-        self.connections.configure(self.config)
+        self.connections.configure(self.config, source_only)
diff --git a/zuul/cmd/executor.py b/zuul/cmd/executor.py
old mode 100644
new mode 100755
index 96ba4b3..1893f5a
--- a/zuul/cmd/executor.py
+++ b/zuul/cmd/executor.py
@@ -106,7 +106,7 @@
         server.send_command(server.args.command)
         sys.exit(0)
 
-    server.configure_connections()
+    server.configure_connections(source_only=True)
 
     if server.config.has_option('executor', 'pidfile'):
         pid_fn = os.path.expanduser(server.config.get('executor', 'pidfile'))
diff --git a/zuul/cmd/merger.py b/zuul/cmd/merger.py
old mode 100644
new mode 100755
index 797a990..686f34a
--- a/zuul/cmd/merger.py
+++ b/zuul/cmd/merger.py
@@ -77,7 +77,7 @@
     server.parse_arguments()
 
     server.read_config()
-    server.configure_connections()
+    server.configure_connections(source_only=True)
 
     if server.config.has_option('zuul', 'state_dir'):
         state_dir = os.path.expanduser(server.config.get('zuul', 'state_dir'))
diff --git a/zuul/configloader.py b/zuul/configloader.py
index 50f5d16..90440f7 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -231,7 +231,6 @@
 
         job = {vs.Required('name'): str,
                'parent': str,
-               'queue-name': str,
                'failure-message': str,
                'success-message': str,
                'failure-url': str,
diff --git a/zuul/driver/gerrit/gerritconnection.py b/zuul/driver/gerrit/gerritconnection.py
index 9444d0c..25cce42 100644
--- a/zuul/driver/gerrit/gerritconnection.py
+++ b/zuul/driver/gerrit/gerritconnection.py
@@ -172,11 +172,15 @@
         self._stopped = False
 
     def _read(self, fd):
-        l = fd.readline()
-        data = json.loads(l)
-        self.log.debug("Received data from Gerrit event stream: \n%s" %
-                       pprint.pformat(data))
-        self.gerrit_connection.addEvent(data)
+        while True:
+            l = fd.readline()
+            data = json.loads(l)
+            self.log.debug("Received data from Gerrit event stream: \n%s" %
+                           pprint.pformat(data))
+            self.gerrit_connection.addEvent(data)
+            # Continue until all the lines received are consumed
+            if fd._pos == fd._realpos:
+                break
 
     def _listen(self, stdout, stderr):
         poll = select.poll()
diff --git a/zuul/executor/server.py b/zuul/executor/server.py
index 958d4d9..99d2a9c 100644
--- a/zuul/executor/server.py
+++ b/zuul/executor/server.py
@@ -219,6 +219,16 @@
             self.condition.release()
 
 
+def _copy_ansible_files(python_module, target_dir):
+        library_path = os.path.dirname(os.path.abspath(python_module.__file__))
+        for fn in os.listdir(library_path):
+            full_path = os.path.join(library_path, fn)
+            if os.path.isdir(full_path):
+                shutil.copytree(full_path, os.path.join(target_dir, fn))
+            else:
+                shutil.copy(os.path.join(library_path, fn), target_dir)
+
+
 class ExecutorServer(object):
     log = logging.getLogger("zuul.ExecutorServer")
 
@@ -286,40 +296,10 @@
         if not os.path.exists(self.lookup_dir):
             os.makedirs(self.lookup_dir)
 
-        library_path = os.path.dirname(os.path.abspath(
-            zuul.ansible.library.__file__))
-        for fn in os.listdir(library_path):
-            full_path = os.path.join(library_path, fn)
-            if os.path.isdir(full_path):
-                shutil.copytree(full_path, os.path.join(self.library_dir, fn))
-            else:
-                shutil.copy(os.path.join(library_path, fn), self.library_dir)
-        action_path = os.path.dirname(os.path.abspath(
-                                      zuul.ansible.action.__file__))
-        for fn in os.listdir(action_path):
-            full_path = os.path.join(action_path, fn)
-            if os.path.isdir(full_path):
-                shutil.copytree(full_path, os.path.join(self.action_dir, fn))
-            else:
-                shutil.copy(full_path, self.action_dir)
-
-        callback_path = os.path.dirname(os.path.abspath(
-            zuul.ansible.callback.__file__))
-        for fn in os.listdir(callback_path):
-            full_path = os.path.join(callback_path, fn)
-            if os.path.isdir(full_path):
-                shutil.copytree(full_path, os.path.join(self.callback_dir, fn))
-            else:
-                shutil.copy(os.path.join(callback_path, fn), self.callback_dir)
-
-        lookup_path = os.path.dirname(os.path.abspath(
-            zuul.ansible.lookup.__file__))
-        for fn in os.listdir(lookup_path):
-            full_path = os.path.join(lookup_path, fn)
-            if os.path.isdir(full_path):
-                shutil.copytree(full_path, os.path.join(self.lookup_dir, fn))
-            else:
-                shutil.copy(os.path.join(lookup_path, fn), self.lookup_dir)
+        _copy_ansible_files(zuul.ansible.library, self.library_dir)
+        _copy_ansible_files(zuul.ansible.action, self.action_dir)
+        _copy_ansible_files(zuul.ansible.callback, self.callback_dir)
+        _copy_ansible_files(zuul.ansible.lookup, self.lookup_dir)
 
         self.job_workers = {}
 
@@ -958,7 +938,7 @@
             for item in self.getHostList(args):
                 inventory.write(item['name'])
                 for k, v in item['host_vars'].items():
-                    inventory.write(' %s=%s' % (k, v))
+                    inventory.write(' %s="%s"' % (k, v))
                 inventory.write('\n')
                 for key in item['host_keys']:
                     keys.append(key)
diff --git a/zuul/lib/connections.py b/zuul/lib/connections.py
index f5cce7b..720299a 100644
--- a/zuul/lib/connections.py
+++ b/zuul/lib/connections.py
@@ -23,6 +23,7 @@
 import zuul.driver.timer
 import zuul.driver.sql
 from zuul.connection import BaseConnection
+from zuul.driver import SourceInterface
 
 
 class DefaultConnection(BaseConnection):
@@ -78,7 +79,7 @@
         for driver in self.drivers.values():
             driver.stop()
 
-    def configure(self, config):
+    def configure(self, config, source_only=False):
         # Register connections from the config
         connections = {}
 
@@ -100,6 +101,13 @@
                                 % (con_config['driver'], con_name))
 
             driver = self.drivers[con_driver]
+
+            # The merger and the reporter only needs source driver.
+            # This makes sure Reporter like the SQLDriver are only created by
+            # the scheduler process
+            if source_only and not issubclass(driver, SourceInterface):
+                continue
+
             connection = driver.getConnection(con_name, con_config)
             connections[con_name] = connection
 
diff --git a/zuul/merger/client.py b/zuul/merger/client.py
index 069cbf5..e164195 100644
--- a/zuul/merger/client.py
+++ b/zuul/merger/client.py
@@ -113,12 +113,6 @@
                     files=files)
         self.submitJob('merger:merge', data, build_set, precedence)
 
-    def updateRepo(self, connection_name, project_name, build_set,
-                   precedence=zuul.model.PRECEDENCE_NORMAL):
-        data = dict(connection=connection_name,
-                    project=project_name)
-        self.submitJob('merger:update', data, build_set, precedence)
-
     def getFiles(self, connection_name, project_name, branch, files,
                  precedence=zuul.model.PRECEDENCE_HIGH):
         data = dict(connection=connection_name,
diff --git a/zuul/merger/server.py b/zuul/merger/server.py
index 04fd03b..c09d7ba 100644
--- a/zuul/merger/server.py
+++ b/zuul/merger/server.py
@@ -67,7 +67,6 @@
 
     def register(self):
         self.worker.registerFunction("merger:merge")
-        self.worker.registerFunction("merger:update")
         self.worker.registerFunction("merger:cat")
 
     def stop(self):
@@ -88,9 +87,6 @@
                     if job.name == 'merger:merge':
                         self.log.debug("Got merge job: %s" % job.unique)
                         self.merge(job)
-                    elif job.name == 'merger:update':
-                        self.log.debug("Got update job: %s" % job.unique)
-                        self.update(job)
                     elif job.name == 'merger:cat':
                         self.log.debug("Got cat job: %s" % job.unique)
                         self.cat(job)
@@ -119,13 +115,6 @@
             result['commit'] = ret
         job.sendWorkComplete(json.dumps(result))
 
-    def update(self, job):
-        args = json.loads(job.arguments)
-        self.merger.updateRepo(args['connection'], args['project'])
-        result = dict(updated=True,
-                      zuul_url=self.zuul_url)
-        job.sendWorkComplete(json.dumps(result))
-
     def cat(self, job):
         args = json.loads(job.arguments)
         self.merger.updateRepo(args['connection'], args['project'])