Merge "Allow run to be list of playbooks"

This commit is contained in:
Zuul 2019-02-06 04:38:02 +00:00 committed by Gerrit Code Review
commit 214146209d
14 changed files with 196 additions and 30 deletions

View File

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

View File

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

View File

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

View File

@ -0,0 +1,11 @@
- hosts: all
tasks:
- name: Register bar.txt file.
stat:
path: "{{zuul.executor.log_root}}/bar.txt"
register: bar_st
- name: Assert bar.txt file.
assert:
that:
- not bar_st.stat.exists

View File

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

View File

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

View File

@ -0,0 +1,33 @@
- hosts: all
tasks:
- name: Register parent.txt file.
stat:
path: "{{zuul.executor.log_root}}/parent.txt"
register: parent_st
- name: Assert parent.txt does not exist.
assert:
that:
- not parent_st.stat.exists
- name: Register foo.txt file.
stat:
path: "{{zuul.executor.log_root}}/foo.txt"
register: foo_st
- name: Assert foo.txt exists.
assert:
that:
- foo_st.stat.exists
- foo_st.stat.isreg
- name: Register bar.txt file.
stat:
path: "{{zuul.executor.log_root}}/bar.txt"
register: bar_st
- name: Assert bar.txt exists.
assert:
that:
- bar_st.stat.exists
- bar_st.stat.isreg

View File

@ -0,0 +1,11 @@
- hosts: all
tasks:
- name: Register parent.txt file.
stat:
path: "{{zuul.executor.log_root}}/parent.txt"
register: parent_st
- name: Assert parent.txt exist.
assert:
that:
- parent_st.stat.exists

View File

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

View File

@ -171,6 +171,70 @@
- secret: vartest_secret - secret: vartest_secret
name: renamed_secret name: renamed_secret
- job:
name: multiple-parent
run: playbooks/multiple-parent.yaml
nodeset:
nodes:
- name: ubuntu-xenial
label: ubuntu-xenial
groups:
- name: foo
nodes:
- ubuntu-xenial
- name: bar
nodes:
- ubuntu-xenial
- job:
name: multiple-child
parent: multiple-parent
run:
- playbooks/foo.yaml
- playbooks/bar.yaml
post-run: playbooks/foobar-post.yaml
- job:
name: multiple-child-no-run
parent: multiple-parent
post-run: playbooks/multiple-parent-post.yaml
- job:
name: multiple-run
run:
- playbooks/foo.yaml
- playbooks/bar.yaml
post-run: playbooks/foobar-post.yaml
nodeset:
nodes:
- name: ubuntu-xenial
label: ubuntu-xenial
groups:
- name: foo
nodes:
- ubuntu-xenial
- name: bar
nodes:
- ubuntu-xenial
- job:
name: multiple-run-failure
run:
- playbooks/first-fail.yaml
- playbooks/bar.yaml
post-run: playbooks/first-fail-post.yaml
nodeset:
nodes:
- name: ubuntu-xenial
label: ubuntu-xenial
groups:
- name: foo
nodes:
- ubuntu-xenial
- name: bar
nodes:
- ubuntu-xenial
- job: - job:
parent: base-urls parent: base-urls
name: hello name: hello

View File

@ -30,3 +30,7 @@
- post-timeout - post-timeout
- hello-world - hello-world
- failpost - failpost
- multiple-child
- multiple-child-no-run
- multiple-run
- multiple-run-failure

View File

@ -2313,6 +2313,20 @@ class TestAnsible(AnsibleZuulTestCase):
build_add_host = self.getJobFromHistory('add-host') build_add_host = self.getJobFromHistory('add-host')
with self.jobLog(build_add_host): with self.jobLog(build_add_host):
self.assertEqual(build_add_host.result, 'SUCCESS') self.assertEqual(build_add_host.result, 'SUCCESS')
build_multiple_child = self.getJobFromHistory('multiple-child')
with self.jobLog(build_multiple_child):
self.assertEqual(build_multiple_child.result, 'SUCCESS')
build_multiple_child_no_run = self.getJobFromHistory(
'multiple-child-no-run')
with self.jobLog(build_multiple_child_no_run):
self.assertEqual(build_multiple_child_no_run.result, 'SUCCESS')
build_multiple_run = self.getJobFromHistory('multiple-run')
with self.jobLog(build_multiple_run):
self.assertEqual(build_multiple_run.result, 'SUCCESS')
build_multiple_run_failure = self.getJobFromHistory(
'multiple-run-failure')
with self.jobLog(build_multiple_run_failure):
self.assertEqual(build_multiple_run_failure.result, 'FAILURE')
build_python27 = self.getJobFromHistory('python27') build_python27 = self.getJobFromHistory('python27')
with self.jobLog(build_python27): with self.jobLog(build_python27):
self.assertEqual(build_python27.result, 'SUCCESS') self.assertEqual(build_python27.result, 'SUCCESS')

View File

@ -566,7 +566,7 @@ class JobParser(object):
'attempts': int, 'attempts': int,
'pre-run': to_list(str), 'pre-run': to_list(str),
'post-run': to_list(str), 'post-run': to_list(str),
'run': str, 'run': to_list(str),
'_source_context': model.SourceContext, '_source_context': model.SourceContext,
'_start_mark': ZuulMark, '_start_mark': ZuulMark,
'roles': to_list(role), 'roles': to_list(role),
@ -719,10 +719,12 @@ class JobParser(object):
post_run_name, job.roles, post_run_name, job.roles,
secrets) secrets)
job.post_run = (post_run,) + job.post_run job.post_run = (post_run,) + job.post_run
if 'run' in conf: if 'run' in conf:
run = model.PlaybookContext(job.source_context, conf['run'], for run_name in as_list(conf.get('run')):
job.roles, secrets) run = model.PlaybookContext(job.source_context, run_name,
job.run = (run,) job.roles, secrets)
job.run = job.run + (run,)
for k in self.simple_attributes: for k in self.simple_attributes:
a = k.replace('-', '_') a = k.replace('-', '_')

View File

@ -394,7 +394,6 @@ class JobDir(object):
'setup-inventory.yaml') 'setup-inventory.yaml')
self.logging_json = os.path.join(self.ansible_root, 'logging.json') self.logging_json = os.path.join(self.ansible_root, 'logging.json')
self.playbooks = [] # The list of candidate playbooks self.playbooks = [] # The list of candidate playbooks
self.playbook = None # A pointer to the candidate we have chosen
self.pre_playbooks = [] self.pre_playbooks = []
self.post_playbooks = [] self.post_playbooks = []
self.job_output_file = os.path.join(self.log_root, 'job-output.txt') self.job_output_file = os.path.join(self.log_root, 'job-output.txt')
@ -1133,26 +1132,30 @@ class AnsibleJob(object):
self.cpu_times['children_system'])) self.cpu_times['children_system']))
if not pre_failed: if not pre_failed:
ansible_timeout = self.getAnsibleTimeout(time_started, job_timeout) for index, playbook in enumerate(self.jobdir.playbooks):
job_status, job_code = self.runAnsiblePlaybook( ansible_timeout = self.getAnsibleTimeout(
self.jobdir.playbook, ansible_timeout, phase='run') time_started, job_timeout)
if job_status == self.RESULT_ABORTED: job_status, job_code = self.runAnsiblePlaybook(
return 'ABORTED' playbook, ansible_timeout, phase='run', index=index)
elif job_status == self.RESULT_TIMED_OUT: if job_status == self.RESULT_ABORTED:
# Set the pre-failure flag so this doesn't get return 'ABORTED'
# overridden by a post-failure. elif job_status == self.RESULT_TIMED_OUT:
pre_failed = True # Set the pre-failure flag so this doesn't get
result = 'TIMED_OUT' # overridden by a post-failure.
elif job_status == self.RESULT_NORMAL: pre_failed = True
success = (job_code == 0) result = 'TIMED_OUT'
if success: break
result = 'SUCCESS' elif job_status == self.RESULT_NORMAL:
success = (job_code == 0)
if success:
result = 'SUCCESS'
else:
result = 'FAILURE'
break
else: else:
result = 'FAILURE' # The result of the job is indeterminate. Zuul will
else: # run it again.
# The result of the job is indeterminate. Zuul will return None
# run it again.
return None
# check if we need to pause here # check if we need to pause here
result_data = self.getResultData() result_data = self.getResultData()
@ -1350,14 +1353,15 @@ class AnsibleJob(object):
jobdir_playbook = self.jobdir.addPrePlaybook() jobdir_playbook = self.jobdir.addPrePlaybook()
self.preparePlaybook(jobdir_playbook, playbook, args) self.preparePlaybook(jobdir_playbook, playbook, args)
job_playbook = None
for playbook in args['playbooks']: for playbook in args['playbooks']:
jobdir_playbook = self.jobdir.addPlaybook() jobdir_playbook = self.jobdir.addPlaybook()
self.preparePlaybook(jobdir_playbook, playbook, args) self.preparePlaybook(jobdir_playbook, playbook, args)
if jobdir_playbook.path is not None: if jobdir_playbook.path is not None:
self.jobdir.playbook = jobdir_playbook if job_playbook is None:
break job_playbook = jobdir_playbook
if self.jobdir.playbook is None: if job_playbook is None:
raise ExecutorError("No playbook specified") raise ExecutorError("No playbook specified")
for playbook in args['post_playbooks']: for playbook in args['post_playbooks']: