Add enqueue reporter action

This facilitates integration with the gerrit checks API (and may
prove useful for other similar APIs).  It will allow us to report
that a change has been enqueued in a particular pipeline.  A Zuul
pipeline will correspond to a Gerrit check, which means we can
update the status for that check from "NOT_STARTED" to "SCHEDULED"
when it enters the pipeline.  This is important for our check
polling loop, and it will cause that check to stop appearing in
the list of pending checks.

Test coverage for this is added in change
Ida0cdef682ca2ce117617eacfb67f371426a3131.

Change-Id: I9ec329b446fa51e0911d4d9ff67eea7ddd55ab5d
This commit is contained in:
James E. Blair 2019-09-09 14:18:14 -07:00
parent cfe6a7b985
commit c8d7119de4
6 changed files with 52 additions and 5 deletions

View File

@ -247,6 +247,11 @@ success, the pipeline reports back to Gerrit with ``Verified`` vote of
Three replacement fields are available ``status_url``, ``pipeline`` and
``change``.
.. attr:: enqueue-message
The introductory text in reports when an item is enqueued.
Empty by default.
.. attr:: merge-failure-message
:default: Merge failed.
@ -364,11 +369,18 @@ success, the pipeline reports back to Gerrit with ``Verified`` vote of
then the ``failure`` reporters will be used to notify of
unsuccessful merges.
.. attr:: enqueue
These reporters describe what Zuul should do when an item is
enqueued into the pipeline. This may be used to indicate to a
system or user that Zuul is aware of the triggering event even
though it has not evaluated whether any jobs will run.
.. attr:: start
These reporters describe what Zuul should do when a change is
added to the pipeline. This can be used, for example, to reset
a previously reported result.
These reporters describe what Zuul should do when jobs start
running for an item in the pipeline. This can be used, for
example, to reset a previously reported result.
.. attr:: disabled

View File

@ -0,0 +1,5 @@
---
features:
- |
Added the :attr:`pipeline.enqueue` reporter action so that
reporters may be run when an item is enqueued into a pipeline.

View File

@ -1119,6 +1119,7 @@ class ProjectParser(object):
class PipelineParser(object):
# A set of reporter configuration keys to action mapping
reporter_actions = {
'enqueue': 'enqueue_actions',
'start': 'start_actions',
'success': 'success_actions',
'failure': 'failure_actions',
@ -1188,8 +1189,8 @@ class PipelineParser(object):
pipeline['require'] = self.getDriverSchema('require')
pipeline['reject'] = self.getDriverSchema('reject')
pipeline['trigger'] = vs.Required(self.getDriverSchema('trigger'))
for action in ['start', 'success', 'failure', 'merge-failure',
'disabled']:
for action in ['enqueue', 'start', 'success', 'failure',
'merge-failure', 'disabled']:
pipeline[action] = self.getDriverSchema('reporter')
return vs.Schema(pipeline)
@ -1216,6 +1217,7 @@ class PipelineParser(object):
pipeline.footer_message = conf.get('footer-message', "")
pipeline.start_message = conf.get('start-message',
"Starting {pipeline.name} jobs.")
pipeline.enqueue_message = conf.get('enqueue-message', "")
pipeline.dequeue_on_new_patchset = conf.get(
'dequeue-on-new-patchset', True)
pipeline.ignore_dependencies = conf.get(

View File

@ -150,6 +150,15 @@ class PipelineManager(object):
return True
return False
def reportEnqueue(self, item):
if not self.pipeline._disabled:
self.log.info("Reporting enqueue, action %s item %s" %
(self.pipeline.enqueue_actions, item))
ret = self.sendReport(self.pipeline.enqueue_actions, item)
if ret:
self.log.error("Reporting item enqueued %s received: %s" %
(item, ret))
def reportStart(self, item):
if not self.pipeline._disabled:
self.log.info("Reporting start, action %s item %s" %
@ -339,6 +348,9 @@ class PipelineManager(object):
item.live = live
self.reportStats(item)
item.quiet = quiet
if not item.reported_enqueue:
self.reportEnqueue(item)
item.reported_enqueue = True
self.enqueueChangesBehind(change, event, quiet,
ignore_requirements, change_queue)
zuul_driver = self.sched.connections.drivers['zuul']

View File

@ -258,6 +258,7 @@ class Pipeline(object):
self.merge_failure_message = None
self.success_message = None
self.footer_message = None
self.enqueue_message = None
self.start_message = None
self.post_review = False
self.dequeue_on_new_patchset = True
@ -267,6 +268,7 @@ class Pipeline(object):
self.relative_priority_queues = {}
self.precedence = PRECEDENCE_NORMAL
self.triggers = []
self.enqueue_actions = []
self.start_actions = []
self.success_actions = []
self.failure_actions = []
@ -285,6 +287,7 @@ class Pipeline(object):
@property
def actions(self):
return (
self.enqueue_actions +
self.start_actions +
self.success_actions +
self.failure_actions +
@ -2122,6 +2125,7 @@ class QueueItem(object):
self.enqueue_time = None
self.dequeue_time = None
self.reported = False
self.reported_enqueue = False
self.reported_start = False
self.quiet = False
self.active = False # Whether an item is within an active window

View File

@ -99,6 +99,7 @@ class BaseReporter(object, metaclass=abc.ABCMeta):
def _getFormatter(self):
format_methods = {
'enqueue': self._formatItemReportEnqueue,
'start': self._formatItemReportStart,
'success': self._formatItemReportSuccess,
'failure': self._formatItemReportFailure,
@ -125,6 +126,17 @@ class BaseReporter(object, metaclass=abc.ABCMeta):
return ret
def _formatItemReportEnqueue(self, item, with_jobs=True):
status_url = get_default(self.connection.sched.config,
'web', 'status_url', '')
if status_url:
status_url = item.formatUrlPattern(status_url)
return item.pipeline.enqueue_message.format(
pipeline=item.pipeline.getSafeAttributes(),
change=item.change.getSafeAttributes(),
status_url=status_url)
def _formatItemReportStart(self, item, with_jobs=True):
status_url = get_default(self.connection.sched.config,
'web', 'status_url', '')