Merge "Fix keyerror with synchronize" into feature/zuulv3
diff --git a/tests/base.py b/tests/base.py
index 3ccc872..b8f9d0c 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -759,7 +759,7 @@
self.launcher_server.build_history.append(
BuildHistory(name=build.name, result=result, changes=build.changes,
node=build.node, uuid=build.unique,
- parameters=build.parameters,
+ parameters=build.parameters, jobdir=build.jobdir,
pipeline=build.parameters['ZUUL_PIPELINE'])
)
self.launcher_server.running_builds.remove(build)
diff --git a/tests/fixtures/config/openstack/git/project-config/playbooks/dsvm.yaml b/tests/fixtures/config/openstack/git/project-config/playbooks/dsvm.yaml
new file mode 100644
index 0000000..f679dce
--- /dev/null
+++ b/tests/fixtures/config/openstack/git/project-config/playbooks/dsvm.yaml
@@ -0,0 +1,2 @@
+- hosts: all
+ tasks: []
diff --git a/tests/fixtures/config/openstack/git/project-config/zuul.yaml b/tests/fixtures/config/openstack/git/project-config/zuul.yaml
index 9c2231a..420d979 100644
--- a/tests/fixtures/config/openstack/git/project-config/zuul.yaml
+++ b/tests/fixtures/config/openstack/git/project-config/zuul.yaml
@@ -71,12 +71,22 @@
- python27
- python35
+- job:
+ name: dsvm
+ parent: base
+ repos:
+ - openstack/keystone
+ - openstack/nova
+
# Project definitions
- project:
name: openstack/nova
templates:
- python-jobs
+ check:
+ jobs:
+ - dsvm
gate:
queue: integrated
@@ -84,5 +94,8 @@
name: openstack/keystone
templates:
- python-jobs
+ check:
+ jobs:
+ - dsvm
gate:
queue: integrated
diff --git a/tests/unit/test_openstack.py b/tests/unit/test_openstack.py
index d0c7ab2..670e578 100644
--- a/tests/unit/test_openstack.py
+++ b/tests/unit/test_openstack.py
@@ -14,6 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import os
+
from tests.base import AnsibleZuulTestCase
@@ -54,3 +56,45 @@
"A should report start and success")
self.assertEqual(self.getJobFromHistory('python27').node,
'ubuntu-trusty')
+
+ def test_dsvm_keystone_repo(self):
+ self.launch_server.keep_jobdir = True
+ A = self.fake_gerrit.addFakeChange('openstack/nova', 'master', 'A')
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertHistory([
+ dict(name='dsvm', result='SUCCESS', changes='1,1')])
+ build = self.getJobFromHistory('dsvm')
+
+ # Check that a change to nova triggered a keystone clone
+ launcher_git_dir = os.path.join(self.launcher_src_root,
+ 'openstack', 'keystone', '.git')
+ self.assertTrue(os.path.exists(launcher_git_dir),
+ msg='openstack/keystone should be cloned.')
+
+ jobdir_git_dir = os.path.join(build.jobdir.src_root,
+ 'openstack', 'keystone', '.git')
+ self.assertTrue(os.path.exists(jobdir_git_dir),
+ msg='openstack/keystone should be cloned.')
+
+ def test_dsvm_nova_repo(self):
+ self.launch_server.keep_jobdir = True
+ A = self.fake_gerrit.addFakeChange('openstack/keystone', 'master', 'A')
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertHistory([
+ dict(name='dsvm', result='SUCCESS', changes='1,1')])
+ build = self.getJobFromHistory('dsvm')
+
+ # Check that a change to keystone triggered a nova clone
+ launcher_git_dir = os.path.join(self.launcher_src_root,
+ 'openstack', 'nova', '.git')
+ self.assertTrue(os.path.exists(launcher_git_dir),
+ msg='openstack/nova should be cloned.')
+
+ jobdir_git_dir = os.path.join(build.jobdir.src_root,
+ 'openstack', 'nova', '.git')
+ self.assertTrue(os.path.exists(jobdir_git_dir),
+ msg='openstack/nova should be cloned.')
diff --git a/zuul/ansible/action/synchronize.py b/zuul/ansible/action/synchronize.py
index fa3d051..75fd45f 100644
--- a/zuul/ansible/action/synchronize.py
+++ b/zuul/ansible/action/synchronize.py
@@ -24,15 +24,15 @@
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
- pull = self._task.args.get('pull', False)
+ mode = self._task.args.get('mode', 'push')
if 'rsync_opts' not in self._task.args:
self._task.args['rsync_opts'] = []
if '--safe-links' not in self._task.args['rsync_opts']:
self._task.args['rsync_opts'].append('--safe-links')
- if not pull and not paths._is_safe_path(source):
+ if mode == 'push' and not paths._is_safe_path(source):
return paths._fail_dict(source, prefix='Syncing files from')
- if pull and not paths._is_safe_path(dest):
+ if mode == 'pull' and not paths._is_safe_path(dest):
return paths._fail_dict(dest, prefix='Syncing files to')
return super(ActionModule, self).run(tmp, task_vars)
diff --git a/zuul/configloader.py b/zuul/configloader.py
index e4fa620..3e94c37 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -115,6 +115,7 @@
'run': str,
'_source_context': model.SourceContext,
'roles': to_list(role),
+ 'repos': to_list(str),
}
return vs.Schema(job)
@@ -185,6 +186,11 @@
ns.addNode(node)
job.nodeset = ns
+ if 'repos' in conf:
+ # Accumulate repos in a set so that job inheritance
+ # is additive.
+ job.repos = job.repos.union(set(conf.get('repos', [])))
+
tags = conf.get('tags')
if tags:
# Tags are merged via a union rather than a
diff --git a/zuul/launcher/client.py b/zuul/launcher/client.py
index f36e2a7..a22f82e 100644
--- a/zuul/launcher/client.py
+++ b/zuul/launcher/client.py
@@ -348,6 +348,13 @@
params['nodes'] = nodes
params['zuul'] = zuul_params
projects = set()
+ if job.repos:
+ for repo in job.repos:
+ project = item.pipeline.source.getProject(repo)
+ params['projects'].append(
+ dict(name=repo,
+ url=item.pipeline.source.getGitUrl(project)))
+ projects.add(project)
for item in all_items:
if item.change.project not in projects:
params['projects'].append(
diff --git a/zuul/launcher/server.py b/zuul/launcher/server.py
index 575d352..df24ff6 100644
--- a/zuul/launcher/server.py
+++ b/zuul/launcher/server.py
@@ -87,7 +87,7 @@
# trusted.cfg
# untrusted.cfg
# work
- # git
+ # src
# logs
self.keep = keep
self.root = tempfile.mkdtemp(dir=root)
diff --git a/zuul/model.py b/zuul/model.py
index 10d0446..ac3a286 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -699,6 +699,7 @@
attempts=3,
final=False,
roles=frozenset(),
+ repos=frozenset(),
)
# These are generally internal attributes which are not