Configure triggers dynamically
Move EventFilter configuration into the triggers to allow dynamic inclusion of triggers rather than specifying each one in the sechduler. Change-Id: I4ed345058ff1ffdd662fafa854e36782cc7f047b
This commit is contained in:
parent
c94afc4605
commit
70b13490a3
|
@ -2164,12 +2164,7 @@ class TestScheduler(ZuulTestCase):
|
|||
|
||||
def test_test_config(self):
|
||||
"Test that we can test the config"
|
||||
sched = zuul.scheduler.Scheduler()
|
||||
sched.registerSource(None, 'gerrit')
|
||||
sched.registerTrigger(None, 'gerrit')
|
||||
sched.registerTrigger(None, 'timer')
|
||||
sched.registerTrigger(None, 'zuul')
|
||||
sched.testConfig(self.config.get('zuul', 'layout_config'))
|
||||
self.sched.testConfig(self.config.get('zuul', 'layout_config'))
|
||||
|
||||
def test_build_description(self):
|
||||
"Test that build descriptions update"
|
||||
|
|
|
@ -30,7 +30,7 @@ import yaml
|
|||
import layoutvalidator
|
||||
import model
|
||||
from model import ActionReporter, Pipeline, Project, ChangeQueue
|
||||
from model import EventFilter, ChangeishFilter, NullChange
|
||||
from model import ChangeishFilter, NullChange
|
||||
from zuul import change_matcher
|
||||
from zuul import version as zuul_version
|
||||
|
||||
|
@ -339,63 +339,10 @@ class Scheduler(threading.Thread):
|
|||
)
|
||||
manager.changeish_filters.append(f)
|
||||
|
||||
# TODO: move this into triggers (may require pluggable
|
||||
# configuration)
|
||||
if 'gerrit' in conf_pipeline['trigger']:
|
||||
for trigger in toList(conf_pipeline['trigger']['gerrit']):
|
||||
approvals = {}
|
||||
for approval_dict in toList(trigger.get('approval')):
|
||||
for k, v in approval_dict.items():
|
||||
approvals[k] = v
|
||||
# Backwards compat for *_filter versions of these args
|
||||
comments = toList(trigger.get('comment'))
|
||||
if not comments:
|
||||
comments = toList(trigger.get('comment_filter'))
|
||||
emails = toList(trigger.get('email'))
|
||||
if not emails:
|
||||
emails = toList(trigger.get('email_filter'))
|
||||
usernames = toList(trigger.get('username'))
|
||||
if not usernames:
|
||||
usernames = toList(trigger.get('username_filter'))
|
||||
ignore_deletes = trigger.get('ignore-deletes', True)
|
||||
f = EventFilter(
|
||||
trigger=self.triggers['gerrit'],
|
||||
types=toList(trigger['event']),
|
||||
branches=toList(trigger.get('branch')),
|
||||
refs=toList(trigger.get('ref')),
|
||||
event_approvals=approvals,
|
||||
comments=comments,
|
||||
emails=emails,
|
||||
usernames=usernames,
|
||||
required_approvals=(
|
||||
toList(trigger.get('require-approval'))
|
||||
),
|
||||
reject_approvals=toList(
|
||||
trigger.get('reject-approval')
|
||||
),
|
||||
ignore_deletes=ignore_deletes
|
||||
)
|
||||
manager.event_filters.append(f)
|
||||
if 'timer' in conf_pipeline['trigger']:
|
||||
for trigger in toList(conf_pipeline['trigger']['timer']):
|
||||
f = EventFilter(trigger=self.triggers['timer'],
|
||||
types=['timer'],
|
||||
timespecs=toList(trigger['time']))
|
||||
manager.event_filters.append(f)
|
||||
if 'zuul' in conf_pipeline['trigger']:
|
||||
for trigger in toList(conf_pipeline['trigger']['zuul']):
|
||||
f = EventFilter(
|
||||
trigger=self.triggers['zuul'],
|
||||
types=toList(trigger['event']),
|
||||
pipelines=toList(trigger.get('pipeline')),
|
||||
required_approvals=(
|
||||
toList(trigger.get('require-approval'))
|
||||
),
|
||||
reject_approvals=toList(
|
||||
trigger.get('reject-approval')
|
||||
),
|
||||
)
|
||||
manager.event_filters.append(f)
|
||||
# TODO(jhesketh): Allow multiple triggers per pipeline
|
||||
for trigger in self.triggers.values():
|
||||
manager.event_filters += \
|
||||
trigger.getEventFilters(conf_pipeline['trigger'])
|
||||
|
||||
for project_template in data.get('project-templates', []):
|
||||
# Make sure the template only contains valid pipelines
|
||||
|
|
|
@ -30,6 +30,11 @@ class BaseTrigger(object):
|
|||
def stop(self):
|
||||
"""Stop the trigger."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def getEventFilters(self, trigger_conf):
|
||||
"""Return a list of EventFilter's for the scheduler to match against.
|
||||
"""
|
||||
|
||||
def postConfig(self):
|
||||
"""Called after config is loaded."""
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import logging
|
|||
import threading
|
||||
import time
|
||||
import voluptuous
|
||||
from zuul.model import TriggerEvent
|
||||
from zuul.model import EventFilter, TriggerEvent
|
||||
from zuul.trigger import BaseTrigger
|
||||
|
||||
|
||||
|
@ -136,6 +136,53 @@ class GerritTrigger(BaseTrigger):
|
|||
self.gerrit_connector.stop()
|
||||
self.gerrit_connector.join()
|
||||
|
||||
def getEventFilters(self, trigger_conf):
|
||||
def toList(item):
|
||||
if not item:
|
||||
return []
|
||||
if isinstance(item, list):
|
||||
return item
|
||||
return [item]
|
||||
|
||||
efilters = []
|
||||
if 'gerrit' in trigger_conf:
|
||||
for trigger in toList(trigger_conf['gerrit']):
|
||||
approvals = {}
|
||||
for approval_dict in toList(trigger.get('approval')):
|
||||
for k, v in approval_dict.items():
|
||||
approvals[k] = v
|
||||
# Backwards compat for *_filter versions of these args
|
||||
comments = toList(trigger.get('comment'))
|
||||
if not comments:
|
||||
comments = toList(trigger.get('comment_filter'))
|
||||
emails = toList(trigger.get('email'))
|
||||
if not emails:
|
||||
emails = toList(trigger.get('email_filter'))
|
||||
usernames = toList(trigger.get('username'))
|
||||
if not usernames:
|
||||
usernames = toList(trigger.get('username_filter'))
|
||||
ignore_deletes = trigger.get('ignore-deletes', True)
|
||||
f = EventFilter(
|
||||
trigger=self,
|
||||
types=toList(trigger['event']),
|
||||
branches=toList(trigger.get('branch')),
|
||||
refs=toList(trigger.get('ref')),
|
||||
event_approvals=approvals,
|
||||
comments=comments,
|
||||
emails=emails,
|
||||
usernames=usernames,
|
||||
required_approvals=(
|
||||
toList(trigger.get('require-approval'))
|
||||
),
|
||||
reject_approvals=toList(
|
||||
trigger.get('reject-approval')
|
||||
),
|
||||
ignore_deletes=ignore_deletes
|
||||
)
|
||||
efilters.append(f)
|
||||
|
||||
return efilters
|
||||
|
||||
|
||||
def validate_trigger(trigger_data):
|
||||
"""Validates the layout's trigger data."""
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
import apscheduler.scheduler
|
||||
import logging
|
||||
from zuul.model import TriggerEvent
|
||||
from zuul.model import EventFilter, TriggerEvent
|
||||
from zuul.trigger import BaseTrigger
|
||||
|
||||
|
||||
|
@ -42,6 +42,25 @@ class TimerTrigger(BaseTrigger):
|
|||
def stop(self):
|
||||
self.apsched.shutdown()
|
||||
|
||||
def getEventFilters(self, trigger_conf):
|
||||
def toList(item):
|
||||
if not item:
|
||||
return []
|
||||
if isinstance(item, list):
|
||||
return item
|
||||
return [item]
|
||||
|
||||
efilters = []
|
||||
if 'timer' in trigger_conf:
|
||||
for trigger in toList(trigger_conf['timer']):
|
||||
f = EventFilter(trigger=self,
|
||||
types=['timer'],
|
||||
timespecs=toList(trigger['time']))
|
||||
|
||||
efilters.append(f)
|
||||
|
||||
return efilters
|
||||
|
||||
def postConfig(self):
|
||||
for job in self.apsched.get_jobs():
|
||||
self.apsched.unschedule_job(job)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# under the License.
|
||||
|
||||
import logging
|
||||
from zuul.model import TriggerEvent
|
||||
from zuul.model import EventFilter, TriggerEvent
|
||||
from zuul.trigger import BaseTrigger
|
||||
|
||||
|
||||
|
@ -28,6 +28,32 @@ class ZuulTrigger(BaseTrigger):
|
|||
self._handle_parent_change_enqueued_events = False
|
||||
self._handle_project_change_merged_events = False
|
||||
|
||||
def getEventFilters(self, trigger_conf):
|
||||
def toList(item):
|
||||
if not item:
|
||||
return []
|
||||
if isinstance(item, list):
|
||||
return item
|
||||
return [item]
|
||||
|
||||
efilters = []
|
||||
if 'zuul' in trigger_conf:
|
||||
for trigger in toList(trigger_conf['zuul']):
|
||||
f = EventFilter(
|
||||
trigger=self,
|
||||
types=toList(trigger['event']),
|
||||
pipelines=toList(trigger.get('pipeline')),
|
||||
required_approvals=(
|
||||
toList(trigger.get('require-approval'))
|
||||
),
|
||||
reject_approvals=toList(
|
||||
trigger.get('reject-approval')
|
||||
),
|
||||
)
|
||||
efilters.append(f)
|
||||
|
||||
return efilters
|
||||
|
||||
def onChangeMerged(self, change):
|
||||
# Called each time zuul merges a change
|
||||
if self._handle_project_change_merged_events:
|
||||
|
|
Loading…
Reference in New Issue