summaryrefslogtreecommitdiff
path: root/zuul
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2017-12-15 18:14:16 +0000
committerGerrit Code Review <review@openstack.org>2017-12-15 18:14:16 +0000
commit48a6310057710ebf11a0f45642adeabf4dd288e9 (patch)
tree0c8544b32c7be46a34b3455805d2a6cff92d1f53 /zuul
parentc1d66e35ec4751d1f96b665e9fbc1bd4f2508d0a (diff)
parent1ef8f7c65fd0c30e55faad035e8780438e0e9682 (diff)
downloadzuul-48a6310057710ebf11a0f45642adeabf4dd288e9.tar.gz
Merge "Add debug project-pipeline option" into feature/zuulv3
Diffstat (limited to 'zuul')
-rw-r--r--zuul/configloader.py18
-rw-r--r--zuul/model.py45
-rw-r--r--zuul/reporter/__init__.py4
3 files changed, 60 insertions, 7 deletions
diff --git a/zuul/configloader.py b/zuul/configloader.py
index 10e023fd6..71c4ccc83 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -789,7 +789,11 @@ class ProjectTemplateParser(object):
job = {str: vs.Any(str, JobParser.job_attributes)}
job_list = [vs.Any(str, job)]
- pipeline_contents = {'queue': str, 'jobs': job_list}
+ pipeline_contents = {
+ 'queue': str,
+ 'debug': bool,
+ 'jobs': job_list,
+ }
for p in self.layout.pipelines.values():
project_template[p.name] = pipeline_contents
@@ -809,6 +813,7 @@ class ProjectTemplateParser(object):
project_pipeline = model.ProjectPipelineConfig()
project_template.pipelines[pipeline.name] = project_pipeline
project_pipeline.queue_name = conf_pipeline.get('queue')
+ project_pipeline.debug = conf_pipeline.get('debug')
self.parseJobList(
conf_pipeline.get('jobs', []),
source_context, start_mark, project_pipeline.job_list)
@@ -859,7 +864,11 @@ class ProjectParser(object):
job = {str: vs.Any(str, JobParser.job_attributes)}
job_list = [vs.Any(str, job)]
- pipeline_contents = {'queue': str, 'jobs': job_list}
+ pipeline_contents = {
+ 'queue': str,
+ 'debug': bool,
+ 'jobs': job_list
+ }
for p in self.layout.pipelines.values():
project[p.name] = pipeline_contents
@@ -920,6 +929,7 @@ class ProjectParser(object):
for pipeline in self.layout.pipelines.values():
project_pipeline = model.ProjectPipelineConfig()
queue_name = None
+ debug = False
# For every template, iterate over the job tree and replace or
# create the jobs in the final definition as needed.
pipeline_defined = False
@@ -932,8 +942,12 @@ class ProjectParser(object):
implied_branch)
if template_pipeline.queue_name:
queue_name = template_pipeline.queue_name
+ if template_pipeline.debug is not None:
+ debug = template_pipeline.debug
if queue_name:
project_pipeline.queue_name = queue_name
+ if debug:
+ project_pipeline.debug = True
if pipeline_defined:
project_config.pipelines[pipeline.name] = project_pipeline
return project_config
diff --git a/zuul/model.py b/zuul/model.py
index 12b85c9d9..77770b793 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -1337,6 +1337,7 @@ class BuildSet(object):
self.unable_to_merge = False
self.config_error = None # None or an error message string.
self.failing_reasons = []
+ self.debug_messages = []
self.merge_state = self.NEW
self.nodesets = {} # job -> nodeset
self.node_requests = {} # job -> reqs
@@ -1501,6 +1502,17 @@ class QueueItem(object):
def setReportedResult(self, result):
self.current_build_set.result = result
+ def debug(self, msg, indent=0):
+ ppc = self.layout.getProjectPipelineConfig(self.change.project,
+ self.pipeline)
+ if not ppc.debug:
+ return
+ if indent:
+ indent = ' ' * indent
+ else:
+ indent = ''
+ self.current_build_set.debug_messages.append(indent + msg)
+
def freezeJobGraph(self):
"""Find or create actual matching jobs for this item's change and
store the resulting job tree."""
@@ -2220,6 +2232,7 @@ class ProjectPipelineConfig(object):
def __init__(self):
self.job_list = JobList()
self.queue_name = None
+ self.debug = False
self.merge_mode = None
@@ -2545,7 +2558,8 @@ class Layout(object):
def addProjectConfig(self, project_config):
self.project_configs[project_config.name] = project_config
- def collectJobs(self, jobname, change, path=None, jobs=None, stack=None):
+ def collectJobs(self, item, jobname, change, path=None, jobs=None,
+ stack=None):
if stack is None:
stack = []
if jobs is None:
@@ -2554,13 +2568,20 @@ class Layout(object):
path = []
path.append(jobname)
matched = False
+ indent = len(path) + 1
+ item.debug("Collecting job variants for {jobname}".format(
+ jobname=jobname), indent=indent)
for variant in self.getJobs(jobname):
if not variant.changeMatches(change):
self.log.debug("Variant %s did not match %s", repr(variant),
change)
+ item.debug("Variant {variant} did not match".format(
+ variant=repr(variant)), indent=indent)
continue
else:
self.log.debug("Variant %s matched %s", repr(variant), change)
+ item.debug("Variant {variant} matched".format(
+ variant=repr(variant)), indent=indent)
if not variant.isBase():
parent = variant.parent
if not jobs and parent is None:
@@ -2570,30 +2591,38 @@ class Layout(object):
if parent and parent not in path:
if parent in stack:
raise Exception("Dependency cycle in jobs: %s" % stack)
- self.collectJobs(parent, change, path, jobs, stack + [jobname])
+ self.collectJobs(item, parent, change, path, jobs,
+ stack + [jobname])
matched = True
jobs.append(variant)
if not matched:
+ self.log.debug("No matching parents for job %s and change %s",
+ jobname, change)
+ item.debug("No matching parent for {jobname}".format(
+ jobname=repr(jobname)), indent=indent)
raise NoMatchingParentError()
return jobs
def _createJobGraph(self, item, job_list, job_graph):
change = item.change
pipeline = item.pipeline
+ item.debug("Freezing job graph")
for jobname in job_list.jobs:
# This is the final job we are constructing
frozen_job = None
self.log.debug("Collecting jobs %s for %s", jobname, change)
+ item.debug("Freezing job {jobname}".format(
+ jobname=jobname), indent=1)
try:
- variants = self.collectJobs(jobname, change)
+ variants = self.collectJobs(item, jobname, change)
except NoMatchingParentError:
- self.log.debug("No matching parents for job %s and change %s",
- jobname, change)
variants = None
if not variants:
# A change must match at least one defined job variant
# (that is to say that it must match more than just
# the job that is defined in the tree).
+ item.debug("No matching variants for {jobname}".format(
+ jobname=jobname), indent=2)
continue
for variant in variants:
if frozen_job is None:
@@ -2612,12 +2641,18 @@ class Layout(object):
matched = True
self.log.debug("Pipeline variant %s matched %s",
repr(variant), change)
+ item.debug("Pipeline variant {variant} matched".format(
+ variant=repr(variant)), indent=2)
else:
self.log.debug("Pipeline variant %s did not match %s",
repr(variant), change)
+ item.debug("Pipeline variant {variant} did not match".format(
+ variant=repr(variant)), indent=2)
if not matched:
# A change must match at least one project pipeline
# job variant.
+ item.debug("No matching pipeline variants for {jobname}".
+ format(jobname=jobname), indent=2)
continue
if (frozen_job.allowed_projects and
change.project.name not in frozen_job.allowed_projects):
diff --git a/zuul/reporter/__init__.py b/zuul/reporter/__init__.py
index 49181a77f..ecf88553a 100644
--- a/zuul/reporter/__init__.py
+++ b/zuul/reporter/__init__.py
@@ -64,6 +64,10 @@ class BaseReporter(object, metaclass=abc.ABCMeta):
a reporter taking free-form text."""
ret = self._getFormatter()(item, with_jobs)
+ if item.current_build_set.debug_messages:
+ debug = '\n '.join(item.current_build_set.debug_messages)
+ ret += '\nDebug information:\n ' + debug + '\n'
+
if item.pipeline.footer_message:
ret += '\n' + item.pipeline.footer_message