Browse Source

Merge "Allow run to be list of playbooks"

Zuul 2 months ago
parent
commit
214146209d

+ 3
- 3
doc/source/user/config.rst View File

@@ -886,9 +886,9 @@ Here is an example of two job definitions:
886 886
 
887 887
    .. attr:: run
888 888
 
889
-      The name of the main playbook for this job.  If it is not
890
-      supplied, the parent's playbook will be used (and likewise up
891
-      the inheritance chain).  The full path within the repo is
889
+      The name of a playbook or list of playbooks for this job.  If it
890
+      is not supplied, the parent's playbook will be used (and likewise
891
+      up the inheritance chain).  The full path within the repo is
892 892
       required.  Example:
893 893
 
894 894
       .. code-block:: yaml

+ 4
- 0
releasenotes/notes/job-run-list-7036fbac9c146098.yaml View File

@@ -0,0 +1,4 @@
1
+---
2
+features:
3
+  - |
4
+    The :attr:`job.run` attribute now supports a single or list of playbooks.

+ 5
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/bar.yaml View File

@@ -0,0 +1,5 @@
1
+- hosts: bar
2
+  tasks:
3
+    - copy:
4
+        content: "bar456"
5
+        dest: "{{zuul.executor.log_root}}/bar.txt"

+ 11
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/first-fail-post.yaml View File

@@ -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

+ 4
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/first-fail.yaml View File

@@ -0,0 +1,4 @@
1
+- hosts: foo
2
+  tasks:
3
+    - fail:
4
+        msg: "Always fail"

+ 5
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/foo.yaml View File

@@ -0,0 +1,5 @@
1
+- hosts: foo
2
+  tasks:
3
+    - copy:
4
+        content: "foo123"
5
+        dest: "{{zuul.executor.log_root}}/foo.txt"

+ 33
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/foobar-post.yaml View File

@@ -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

+ 11
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent-post.yaml View File

@@ -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

+ 5
- 0
tests/fixtures/config/ansible/git/common-config/playbooks/multiple-parent.yaml View File

@@ -0,0 +1,5 @@
1
+- hosts: foo
2
+  tasks:
3
+    - copy:
4
+        content: "parent"
5
+        dest: "{{zuul.executor.log_root}}/parent.txt"

+ 64
- 0
tests/fixtures/config/ansible/git/common-config/zuul.yaml View File

@@ -171,6 +171,70 @@
171 171
       - secret: vartest_secret
172 172
         name: renamed_secret
173 173
 
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
+
174 238
 - job:
175 239
     parent: base-urls
176 240
     name: hello

+ 4
- 0
tests/fixtures/config/ansible/git/org_project/.zuul.yaml View File

@@ -30,3 +30,7 @@
30 30
         - post-timeout
31 31
         - hello-world
32 32
         - failpost
33
+        - multiple-child
34
+        - multiple-child-no-run
35
+        - multiple-run
36
+        - multiple-run-failure

+ 14
- 0
tests/unit/test_v3.py View File

@@ -2313,6 +2313,20 @@ class TestAnsible(AnsibleZuulTestCase):
2313 2313
         build_add_host = self.getJobFromHistory('add-host')
2314 2314
         with self.jobLog(build_add_host):
2315 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 2330
         build_python27 = self.getJobFromHistory('python27')
2317 2331
         with self.jobLog(build_python27):
2318 2332
             self.assertEqual(build_python27.result, 'SUCCESS')

+ 6
- 4
zuul/configloader.py View File

@@ -566,7 +566,7 @@ class JobParser(object):
566 566
                       'attempts': int,
567 567
                       'pre-run': to_list(str),
568 568
                       'post-run': to_list(str),
569
-                      'run': str,
569
+                      'run': to_list(str),
570 570
                       '_source_context': model.SourceContext,
571 571
                       '_start_mark': ZuulMark,
572 572
                       'roles': to_list(role),
@@ -719,10 +719,12 @@ class JobParser(object):
719 719
                                              post_run_name, job.roles,
720 720
                                              secrets)
721 721
             job.post_run = (post_run,) + job.post_run
722
+
722 723
         if 'run' in conf:
723
-            run = model.PlaybookContext(job.source_context, conf['run'],
724
-                                        job.roles, secrets)
725
-            job.run = (run,)
724
+            for run_name in as_list(conf.get('run')):
725
+                run = model.PlaybookContext(job.source_context, run_name,
726
+                                            job.roles, secrets)
727
+                job.run = job.run + (run,)
726 728
 
727 729
         for k in self.simple_attributes:
728 730
             a = k.replace('-', '_')

+ 27
- 23
zuul/executor/server.py View File

@@ -394,7 +394,6 @@ class JobDir(object):
394 394
                                             'setup-inventory.yaml')
395 395
         self.logging_json = os.path.join(self.ansible_root, 'logging.json')
396 396
         self.playbooks = []  # The list of candidate playbooks
397
-        self.playbook = None  # A pointer to the candidate we have chosen
398 397
         self.pre_playbooks = []
399 398
         self.post_playbooks = []
400 399
         self.job_output_file = os.path.join(self.log_root, 'job-output.txt')
@@ -1133,26 +1132,30 @@ class AnsibleJob(object):
1133 1132
              self.cpu_times['children_system']))
1134 1133
 
1135 1134
         if not pre_failed:
1136
-            ansible_timeout = self.getAnsibleTimeout(time_started, job_timeout)
1137
-            job_status, job_code = self.runAnsiblePlaybook(
1138
-                self.jobdir.playbook, ansible_timeout, phase='run')
1139
-            if job_status == self.RESULT_ABORTED:
1140
-                return 'ABORTED'
1141
-            elif job_status == self.RESULT_TIMED_OUT:
1142
-                # Set the pre-failure flag so this doesn't get
1143
-                # overridden by a post-failure.
1144
-                pre_failed = True
1145
-                result = 'TIMED_OUT'
1146
-            elif job_status == self.RESULT_NORMAL:
1147
-                success = (job_code == 0)
1148
-                if success:
1149
-                    result = 'SUCCESS'
1135
+            for index, playbook in enumerate(self.jobdir.playbooks):
1136
+                ansible_timeout = self.getAnsibleTimeout(
1137
+                    time_started, job_timeout)
1138
+                job_status, job_code = self.runAnsiblePlaybook(
1139
+                    playbook, ansible_timeout, phase='run', index=index)
1140
+                if job_status == self.RESULT_ABORTED:
1141
+                    return 'ABORTED'
1142
+                elif job_status == self.RESULT_TIMED_OUT:
1143
+                    # Set the pre-failure flag so this doesn't get
1144
+                    # overridden by a post-failure.
1145
+                    pre_failed = True
1146
+                    result = 'TIMED_OUT'
1147
+                    break
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 1155
                 else:
1151
-                    result = 'FAILURE'
1152
-            else:
1153
-                # The result of the job is indeterminate.  Zuul will
1154
-                # run it again.
1155
-                return None
1156
+                    # The result of the job is indeterminate.  Zuul will
1157
+                    # run it again.
1158
+                    return None
1156 1159
 
1157 1160
         # check if we need to pause here
1158 1161
         result_data = self.getResultData()
@@ -1350,14 +1353,15 @@ class AnsibleJob(object):
1350 1353
             jobdir_playbook = self.jobdir.addPrePlaybook()
1351 1354
             self.preparePlaybook(jobdir_playbook, playbook, args)
1352 1355
 
1356
+        job_playbook = None
1353 1357
         for playbook in args['playbooks']:
1354 1358
             jobdir_playbook = self.jobdir.addPlaybook()
1355 1359
             self.preparePlaybook(jobdir_playbook, playbook, args)
1356 1360
             if jobdir_playbook.path is not None:
1357
-                self.jobdir.playbook = jobdir_playbook
1358
-                break
1361
+                if job_playbook is None:
1362
+                    job_playbook = jobdir_playbook
1359 1363
 
1360
-        if self.jobdir.playbook is None:
1364
+        if job_playbook is None:
1361 1365
             raise ExecutorError("No playbook specified")
1362 1366
 
1363 1367
         for playbook in args['post_playbooks']:

Loading…
Cancel
Save