summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2019-02-06 04:38:02 +0000
committerGerrit Code Review <review@openstack.org>2019-02-06 04:38:02 +0000
commit214146209de4cb524df95b8f35660524f55037ea (patch)
tree6f557d7a138200082a512892cd7756d7f15626c5
parent6f775ddc27d2a67d7e928051ec016053e1f3ed76 (diff)
parent74a974bf4e3e7faa78fda2af3604a2db5e6a1829 (diff)
Merge "Allow run to be list of playbooks"
-rw-r--r--doc/source/user/config.rst6
-rw-r--r--releasenotes/notes/job-run-list-7036fbac9c146098.yaml4
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/bar.yaml5
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/first-fail-post.yaml11
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/first-fail.yaml4
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/foo.yaml5
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/foobar-post.yaml33
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent-post.yaml11
-rw-r--r--tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent.yaml5
-rw-r--r--tests/fixtures/config/ansible/git/common-config/zuul.yaml64
-rw-r--r--tests/fixtures/config/ansible/git/org_project/.zuul.yaml4
-rw-r--r--tests/unit/test_v3.py14
-rw-r--r--zuul/configloader.py10
-rw-r--r--zuul/executor/server.py50
14 files changed, 196 insertions, 30 deletions
diff --git a/doc/source/user/config.rst b/doc/source/user/config.rst
index c2053b3..49b5e76 100644
--- a/doc/source/user/config.rst
+++ b/doc/source/user/config.rst
@@ -886,9 +886,9 @@ Here is an example of two job definitions:
886 886
887 .. attr:: run 887 .. attr:: run
888 888
889 The name of the main playbook for this job. If it is not 889 The name of a playbook or list of playbooks for this job. If it
890 supplied, the parent's playbook will be used (and likewise up 890 is not supplied, the parent's playbook will be used (and likewise
891 the inheritance chain). The full path within the repo is 891 up the inheritance chain). The full path within the repo is
892 required. Example: 892 required. Example:
893 893
894 .. code-block:: yaml 894 .. code-block:: yaml
diff --git a/releasenotes/notes/job-run-list-7036fbac9c146098.yaml b/releasenotes/notes/job-run-list-7036fbac9c146098.yaml
new file mode 100644
index 0000000..0a48736
--- /dev/null
+++ b/releasenotes/notes/job-run-list-7036fbac9c146098.yaml
@@ -0,0 +1,4 @@
1---
2features:
3 - |
4 The :attr:`job.run` attribute now supports a single or list of playbooks.
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/bar.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/bar.yaml
new file mode 100644
index 0000000..c219e81
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/bar.yaml
@@ -0,0 +1,5 @@
1- hosts: bar
2 tasks:
3 - copy:
4 content: "bar456"
5 dest: "{{zuul.executor.log_root}}/bar.txt"
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/first-fail-post.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/first-fail-post.yaml
new file mode 100644
index 0000000..7e34c50
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/first-fail-post.yaml
@@ -0,0 +1,11 @@
1- hosts: all
2 tasks:
3 - name: Register bar.txt file.
4 stat:
5 path: "{{zuul.executor.log_root}}/bar.txt"
6 register: bar_st
7
8 - name: Assert bar.txt file.
9 assert:
10 that:
11 - not bar_st.stat.exists
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/first-fail.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/first-fail.yaml
new file mode 100644
index 0000000..3ff27a8
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/first-fail.yaml
@@ -0,0 +1,4 @@
1- hosts: foo
2 tasks:
3 - fail:
4 msg: "Always fail"
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/foo.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/foo.yaml
new file mode 100644
index 0000000..86e22d6
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/foo.yaml
@@ -0,0 +1,5 @@
1- hosts: foo
2 tasks:
3 - copy:
4 content: "foo123"
5 dest: "{{zuul.executor.log_root}}/foo.txt"
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/foobar-post.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/foobar-post.yaml
new file mode 100644
index 0000000..379e5d0
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/foobar-post.yaml
@@ -0,0 +1,33 @@
1- hosts: all
2 tasks:
3 - name: Register parent.txt file.
4 stat:
5 path: "{{zuul.executor.log_root}}/parent.txt"
6 register: parent_st
7
8 - name: Assert parent.txt does not exist.
9 assert:
10 that:
11 - not parent_st.stat.exists
12
13 - name: Register foo.txt file.
14 stat:
15 path: "{{zuul.executor.log_root}}/foo.txt"
16 register: foo_st
17
18 - name: Assert foo.txt exists.
19 assert:
20 that:
21 - foo_st.stat.exists
22 - foo_st.stat.isreg
23
24 - name: Register bar.txt file.
25 stat:
26 path: "{{zuul.executor.log_root}}/bar.txt"
27 register: bar_st
28
29 - name: Assert bar.txt exists.
30 assert:
31 that:
32 - bar_st.stat.exists
33 - bar_st.stat.isreg
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent-post.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent-post.yaml
new file mode 100644
index 0000000..8060fec
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent-post.yaml
@@ -0,0 +1,11 @@
1- hosts: all
2 tasks:
3 - name: Register parent.txt file.
4 stat:
5 path: "{{zuul.executor.log_root}}/parent.txt"
6 register: parent_st
7
8 - name: Assert parent.txt exist.
9 assert:
10 that:
11 - parent_st.stat.exists
diff --git a/tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent.yaml b/tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent.yaml
new file mode 100644
index 0000000..2d3d3fe
--- /dev/null
+++ b/tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent.yaml
@@ -0,0 +1,5 @@
1- hosts: foo
2 tasks:
3 - copy:
4 content: "parent"
5 dest: "{{zuul.executor.log_root}}/parent.txt"
diff --git a/tests/fixtures/config/ansible/git/common-config/zuul.yaml b/tests/fixtures/config/ansible/git/common-config/zuul.yaml
index a7576d6..eb252fd 100644
--- a/tests/fixtures/config/ansible/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/ansible/git/common-config/zuul.yaml
@@ -172,6 +172,70 @@
172 name: renamed_secret 172 name: renamed_secret
173 173
174- job: 174- job:
175 name: multiple-parent
176 run: playbooks/multiple-parent.yaml
177 nodeset:
178 nodes:
179 - name: ubuntu-xenial
180 label: ubuntu-xenial
181 groups:
182 - name: foo
183 nodes:
184 - ubuntu-xenial
185 - name: bar
186 nodes:
187 - ubuntu-xenial
188
189- job:
190 name: multiple-child
191 parent: multiple-parent
192 run:
193 - playbooks/foo.yaml
194 - playbooks/bar.yaml
195 post-run: playbooks/foobar-post.yaml
196
197- job:
198 name: multiple-child-no-run
199 parent: multiple-parent
200 post-run: playbooks/multiple-parent-post.yaml
201
202- job:
203 name: multiple-run
204 run:
205 - playbooks/foo.yaml
206 - playbooks/bar.yaml
207 post-run: playbooks/foobar-post.yaml
208 nodeset:
209 nodes:
210 - name: ubuntu-xenial
211 label: ubuntu-xenial
212 groups:
213 - name: foo
214 nodes:
215 - ubuntu-xenial
216 - name: bar
217 nodes:
218 - ubuntu-xenial
219
220- job:
221 name: multiple-run-failure
222 run:
223 - playbooks/first-fail.yaml
224 - playbooks/bar.yaml
225 post-run: playbooks/first-fail-post.yaml
226 nodeset:
227 nodes:
228 - name: ubuntu-xenial
229 label: ubuntu-xenial
230 groups:
231 - name: foo
232 nodes:
233 - ubuntu-xenial
234 - name: bar
235 nodes:
236 - ubuntu-xenial
237
238- job:
175 parent: base-urls 239 parent: base-urls
176 name: hello 240 name: hello
177 run: playbooks/hello-post.yaml 241 run: playbooks/hello-post.yaml
diff --git a/tests/fixtures/config/ansible/git/org_project/.zuul.yaml b/tests/fixtures/config/ansible/git/org_project/.zuul.yaml
index a1d0d02..2a974c3 100644
--- a/tests/fixtures/config/ansible/git/org_project/.zuul.yaml
+++ b/tests/fixtures/config/ansible/git/org_project/.zuul.yaml
@@ -30,3 +30,7 @@
30 - post-timeout 30 - post-timeout
31 - hello-world 31 - hello-world
32 - failpost 32 - failpost
33 - multiple-child
34 - multiple-child-no-run
35 - multiple-run
36 - multiple-run-failure
diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py
index bd96fa9..4bfea02 100644
--- a/tests/unit/test_v3.py
+++ b/tests/unit/test_v3.py
@@ -2313,6 +2313,20 @@ class TestAnsible(AnsibleZuulTestCase):
2313 build_add_host = self.getJobFromHistory('add-host') 2313 build_add_host = self.getJobFromHistory('add-host')
2314 with self.jobLog(build_add_host): 2314 with self.jobLog(build_add_host):
2315 self.assertEqual(build_add_host.result, 'SUCCESS') 2315 self.assertEqual(build_add_host.result, 'SUCCESS')
2316 build_multiple_child = self.getJobFromHistory('multiple-child')
2317 with self.jobLog(build_multiple_child):
2318 self.assertEqual(build_multiple_child.result, 'SUCCESS')
2319 build_multiple_child_no_run = self.getJobFromHistory(
2320 'multiple-child-no-run')
2321 with self.jobLog(build_multiple_child_no_run):
2322 self.assertEqual(build_multiple_child_no_run.result, 'SUCCESS')
2323 build_multiple_run = self.getJobFromHistory('multiple-run')
2324 with self.jobLog(build_multiple_run):
2325 self.assertEqual(build_multiple_run.result, 'SUCCESS')
2326 build_multiple_run_failure = self.getJobFromHistory(
2327 'multiple-run-failure')
2328 with self.jobLog(build_multiple_run_failure):
2329 self.assertEqual(build_multiple_run_failure.result, 'FAILURE')
2316 build_python27 = self.getJobFromHistory('python27') 2330 build_python27 = self.getJobFromHistory('python27')
2317 with self.jobLog(build_python27): 2331 with self.jobLog(build_python27):
2318 self.assertEqual(build_python27.result, 'SUCCESS') 2332 self.assertEqual(build_python27.result, 'SUCCESS')
diff --git a/zuul/configloader.py b/zuul/configloader.py
index ca5cf5e..aab039b 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -566,7 +566,7 @@ class JobParser(object):
566 'attempts': int, 566 'attempts': int,
567 'pre-run': to_list(str), 567 'pre-run': to_list(str),
568 'post-run': to_list(str), 568 'post-run': to_list(str),
569 'run': str, 569 'run': to_list(str),
570 '_source_context': model.SourceContext, 570 '_source_context': model.SourceContext,
571 '_start_mark': ZuulMark, 571 '_start_mark': ZuulMark,
572 'roles': to_list(role), 572 'roles': to_list(role),
@@ -719,10 +719,12 @@ class JobParser(object):
719 post_run_name, job.roles, 719 post_run_name, job.roles,
720 secrets) 720 secrets)
721 job.post_run = (post_run,) + job.post_run 721 job.post_run = (post_run,) + job.post_run
722
722 if 'run' in conf: 723 if 'run' in conf:
723 run = model.PlaybookContext(job.source_context, conf['run'], 724 for run_name in as_list(conf.get('run')):
724 job.roles, secrets) 725 run = model.PlaybookContext(job.source_context, run_name,
725 job.run = (run,) 726 job.roles, secrets)
727 job.run = job.run + (run,)
726 728
727 for k in self.simple_attributes: 729 for k in self.simple_attributes:
728 a = k.replace('-', '_') 730 a = k.replace('-', '_')
diff --git a/zuul/executor/server.py b/zuul/executor/server.py
index ff3189f..2547408 100644
--- a/zuul/executor/server.py
+++ b/zuul/executor/server.py
@@ -394,7 +394,6 @@ class JobDir(object):
394 'setup-inventory.yaml') 394 'setup-inventory.yaml')
395 self.logging_json = os.path.join(self.ansible_root, 'logging.json') 395 self.logging_json = os.path.join(self.ansible_root, 'logging.json')
396 self.playbooks = [] # The list of candidate playbooks 396 self.playbooks = [] # The list of candidate playbooks
397 self.playbook = None # A pointer to the candidate we have chosen
398 self.pre_playbooks = [] 397 self.pre_playbooks = []
399 self.post_playbooks = [] 398 self.post_playbooks = []
400 self.job_output_file = os.path.join(self.log_root, 'job-output.txt') 399 self.job_output_file = os.path.join(self.log_root, 'job-output.txt')
@@ -1133,26 +1132,30 @@ class AnsibleJob(object):
1133 self.cpu_times['children_system'])) 1132 self.cpu_times['children_system']))
1134 1133
1135 if not pre_failed: 1134 if not pre_failed:
1136 ansible_timeout = self.getAnsibleTimeout(time_started, job_timeout) 1135 for index, playbook in enumerate(self.jobdir.playbooks):
1137 job_status, job_code = self.runAnsiblePlaybook( 1136 ansible_timeout = self.getAnsibleTimeout(
1138 self.jobdir.playbook, ansible_timeout, phase='run') 1137 time_started, job_timeout)
1139 if job_status == self.RESULT_ABORTED: 1138 job_status, job_code = self.runAnsiblePlaybook(
1140 return 'ABORTED' 1139 playbook, ansible_timeout, phase='run', index=index)
1141 elif job_status == self.RESULT_TIMED_OUT: 1140 if job_status == self.RESULT_ABORTED:
1142 # Set the pre-failure flag so this doesn't get 1141 return 'ABORTED'
1143 # overridden by a post-failure. 1142 elif job_status == self.RESULT_TIMED_OUT:
1144 pre_failed = True 1143 # Set the pre-failure flag so this doesn't get
1145 result = 'TIMED_OUT' 1144 # overridden by a post-failure.
1146 elif job_status == self.RESULT_NORMAL: 1145 pre_failed = True
1147 success = (job_code == 0) 1146 result = 'TIMED_OUT'
1148 if success: 1147 break
1149 result = 'SUCCESS' 1148 elif job_status == self.RESULT_NORMAL:
1149 success = (job_code == 0)
1150 if success:
1151 result = 'SUCCESS'
1152 else:
1153 result = 'FAILURE'
1154 break
1150 else: 1155 else:
1151 result = 'FAILURE' 1156 # The result of the job is indeterminate. Zuul will
1152 else: 1157 # run it again.
1153 # The result of the job is indeterminate. Zuul will 1158 return None
1154 # run it again.
1155 return None
1156 1159
1157 # check if we need to pause here 1160 # check if we need to pause here
1158 result_data = self.getResultData() 1161 result_data = self.getResultData()
@@ -1350,14 +1353,15 @@ class AnsibleJob(object):
1350 jobdir_playbook = self.jobdir.addPrePlaybook() 1353 jobdir_playbook = self.jobdir.addPrePlaybook()
1351 self.preparePlaybook(jobdir_playbook, playbook, args) 1354 self.preparePlaybook(jobdir_playbook, playbook, args)
1352 1355
1356 job_playbook = None
1353 for playbook in args['playbooks']: 1357 for playbook in args['playbooks']:
1354 jobdir_playbook = self.jobdir.addPlaybook() 1358 jobdir_playbook = self.jobdir.addPlaybook()
1355 self.preparePlaybook(jobdir_playbook, playbook, args) 1359 self.preparePlaybook(jobdir_playbook, playbook, args)
1356 if jobdir_playbook.path is not None: 1360 if jobdir_playbook.path is not None:
1357 self.jobdir.playbook = jobdir_playbook 1361 if job_playbook is None:
1358 break 1362 job_playbook = jobdir_playbook
1359 1363
1360 if self.jobdir.playbook is None: 1364 if job_playbook is None:
1361 raise ExecutorError("No playbook specified") 1365 raise ExecutorError("No playbook specified")
1362 1366
1363 for playbook in args['post_playbooks']: 1367 for playbook in args['post_playbooks']: