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:
@@ -247,6 +247,11 @@ success, the pipeline reports back to Gerrit with ``Verified`` vote of
|
|||||||
Three replacement fields are available ``status_url``, ``pipeline`` and
|
Three replacement fields are available ``status_url``, ``pipeline`` and
|
||||||
``change``.
|
``change``.
|
||||||
|
|
||||||
|
.. attr:: enqueue-message
|
||||||
|
|
||||||
|
The introductory text in reports when an item is enqueued.
|
||||||
|
Empty by default.
|
||||||
|
|
||||||
.. attr:: merge-failure-message
|
.. attr:: merge-failure-message
|
||||||
:default: Merge failed.
|
: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
|
then the ``failure`` reporters will be used to notify of
|
||||||
unsuccessful merges.
|
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
|
.. attr:: start
|
||||||
|
|
||||||
These reporters describe what Zuul should do when a change is
|
These reporters describe what Zuul should do when jobs start
|
||||||
added to the pipeline. This can be used, for example, to reset
|
running for an item in the pipeline. This can be used, for
|
||||||
a previously reported result.
|
example, to reset a previously reported result.
|
||||||
|
|
||||||
.. attr:: disabled
|
.. attr:: disabled
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -1119,6 +1119,7 @@ class ProjectParser(object):
|
|||||||
class PipelineParser(object):
|
class PipelineParser(object):
|
||||||
# A set of reporter configuration keys to action mapping
|
# A set of reporter configuration keys to action mapping
|
||||||
reporter_actions = {
|
reporter_actions = {
|
||||||
|
'enqueue': 'enqueue_actions',
|
||||||
'start': 'start_actions',
|
'start': 'start_actions',
|
||||||
'success': 'success_actions',
|
'success': 'success_actions',
|
||||||
'failure': 'failure_actions',
|
'failure': 'failure_actions',
|
||||||
@@ -1188,8 +1189,8 @@ class PipelineParser(object):
|
|||||||
pipeline['require'] = self.getDriverSchema('require')
|
pipeline['require'] = self.getDriverSchema('require')
|
||||||
pipeline['reject'] = self.getDriverSchema('reject')
|
pipeline['reject'] = self.getDriverSchema('reject')
|
||||||
pipeline['trigger'] = vs.Required(self.getDriverSchema('trigger'))
|
pipeline['trigger'] = vs.Required(self.getDriverSchema('trigger'))
|
||||||
for action in ['start', 'success', 'failure', 'merge-failure',
|
for action in ['enqueue', 'start', 'success', 'failure',
|
||||||
'disabled']:
|
'merge-failure', 'disabled']:
|
||||||
pipeline[action] = self.getDriverSchema('reporter')
|
pipeline[action] = self.getDriverSchema('reporter')
|
||||||
return vs.Schema(pipeline)
|
return vs.Schema(pipeline)
|
||||||
|
|
||||||
@@ -1216,6 +1217,7 @@ class PipelineParser(object):
|
|||||||
pipeline.footer_message = conf.get('footer-message', "")
|
pipeline.footer_message = conf.get('footer-message', "")
|
||||||
pipeline.start_message = conf.get('start-message',
|
pipeline.start_message = conf.get('start-message',
|
||||||
"Starting {pipeline.name} jobs.")
|
"Starting {pipeline.name} jobs.")
|
||||||
|
pipeline.enqueue_message = conf.get('enqueue-message', "")
|
||||||
pipeline.dequeue_on_new_patchset = conf.get(
|
pipeline.dequeue_on_new_patchset = conf.get(
|
||||||
'dequeue-on-new-patchset', True)
|
'dequeue-on-new-patchset', True)
|
||||||
pipeline.ignore_dependencies = conf.get(
|
pipeline.ignore_dependencies = conf.get(
|
||||||
|
|||||||
@@ -150,6 +150,15 @@ class PipelineManager(object):
|
|||||||
return True
|
return True
|
||||||
return False
|
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):
|
def reportStart(self, item):
|
||||||
if not self.pipeline._disabled:
|
if not self.pipeline._disabled:
|
||||||
self.log.info("Reporting start, action %s item %s" %
|
self.log.info("Reporting start, action %s item %s" %
|
||||||
@@ -339,6 +348,9 @@ class PipelineManager(object):
|
|||||||
item.live = live
|
item.live = live
|
||||||
self.reportStats(item)
|
self.reportStats(item)
|
||||||
item.quiet = quiet
|
item.quiet = quiet
|
||||||
|
if not item.reported_enqueue:
|
||||||
|
self.reportEnqueue(item)
|
||||||
|
item.reported_enqueue = True
|
||||||
self.enqueueChangesBehind(change, event, quiet,
|
self.enqueueChangesBehind(change, event, quiet,
|
||||||
ignore_requirements, change_queue)
|
ignore_requirements, change_queue)
|
||||||
zuul_driver = self.sched.connections.drivers['zuul']
|
zuul_driver = self.sched.connections.drivers['zuul']
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ class Pipeline(object):
|
|||||||
self.merge_failure_message = None
|
self.merge_failure_message = None
|
||||||
self.success_message = None
|
self.success_message = None
|
||||||
self.footer_message = None
|
self.footer_message = None
|
||||||
|
self.enqueue_message = None
|
||||||
self.start_message = None
|
self.start_message = None
|
||||||
self.post_review = False
|
self.post_review = False
|
||||||
self.dequeue_on_new_patchset = True
|
self.dequeue_on_new_patchset = True
|
||||||
@@ -267,6 +268,7 @@ class Pipeline(object):
|
|||||||
self.relative_priority_queues = {}
|
self.relative_priority_queues = {}
|
||||||
self.precedence = PRECEDENCE_NORMAL
|
self.precedence = PRECEDENCE_NORMAL
|
||||||
self.triggers = []
|
self.triggers = []
|
||||||
|
self.enqueue_actions = []
|
||||||
self.start_actions = []
|
self.start_actions = []
|
||||||
self.success_actions = []
|
self.success_actions = []
|
||||||
self.failure_actions = []
|
self.failure_actions = []
|
||||||
@@ -285,6 +287,7 @@ class Pipeline(object):
|
|||||||
@property
|
@property
|
||||||
def actions(self):
|
def actions(self):
|
||||||
return (
|
return (
|
||||||
|
self.enqueue_actions +
|
||||||
self.start_actions +
|
self.start_actions +
|
||||||
self.success_actions +
|
self.success_actions +
|
||||||
self.failure_actions +
|
self.failure_actions +
|
||||||
@@ -2122,6 +2125,7 @@ class QueueItem(object):
|
|||||||
self.enqueue_time = None
|
self.enqueue_time = None
|
||||||
self.dequeue_time = None
|
self.dequeue_time = None
|
||||||
self.reported = False
|
self.reported = False
|
||||||
|
self.reported_enqueue = False
|
||||||
self.reported_start = False
|
self.reported_start = False
|
||||||
self.quiet = False
|
self.quiet = False
|
||||||
self.active = False # Whether an item is within an active window
|
self.active = False # Whether an item is within an active window
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ class BaseReporter(object, metaclass=abc.ABCMeta):
|
|||||||
|
|
||||||
def _getFormatter(self):
|
def _getFormatter(self):
|
||||||
format_methods = {
|
format_methods = {
|
||||||
|
'enqueue': self._formatItemReportEnqueue,
|
||||||
'start': self._formatItemReportStart,
|
'start': self._formatItemReportStart,
|
||||||
'success': self._formatItemReportSuccess,
|
'success': self._formatItemReportSuccess,
|
||||||
'failure': self._formatItemReportFailure,
|
'failure': self._formatItemReportFailure,
|
||||||
@@ -125,6 +126,17 @@ class BaseReporter(object, metaclass=abc.ABCMeta):
|
|||||||
|
|
||||||
return ret
|
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):
|
def _formatItemReportStart(self, item, with_jobs=True):
|
||||||
status_url = get_default(self.connection.sched.config,
|
status_url = get_default(self.connection.sched.config,
|
||||||
'web', 'status_url', '')
|
'web', 'status_url', '')
|
||||||
|
|||||||
Reference in New Issue
Block a user