Merge "Separate driver interfaces and make abstract" into feature/zuulv3

This commit is contained in:
Jenkins 2017-01-23 21:39:03 +00:00 committed by Gerrit Code Review
commit 473bd3cef6
5 changed files with 120 additions and 65 deletions

View File

@ -12,37 +12,75 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class Driver(object): class Driver(object):
"""A Zuul Driver. """A Driver is an extension component of Zuul that supports
interfacing with a remote system. It can support any of the following
interfaces (but must support at least one to be useful):
A Driver is an extension component of Zuul that supports * ConnectionInterface
interfacing with a remote system. It can support any of the * SourceInterface
following interfaces: * TriggerInterface
* ReporterInterface
* Connection
* Source
* Trigger
* Reporter
Drivers supporting each of these interfaces must implement some of
the following methods, as appropriate.
Zuul will create a single instance of each Driver (which will be Zuul will create a single instance of each Driver (which will be
shared by all tenants), and this instance will persist for the shared by all tenants), and this instance will persist for the life of
life of the process. The Driver class may therefore manage any the process. The Driver class may therefore manage any global state
global state used by all connections. used by all connections.
The class or instance attribute **name** must be provided as a string. The class or instance attribute **name** must be provided as a string.
""" """
name = None name = None
def reconfigure(self, tenant):
"""Called when a tenant is reconfigured.
This method is optional; the base implementation does nothing.
When Zuul performs a reconfiguration for a tenant, this method
is called with the tenant (including the new layout
configuration) as an argument. The driver may establish any
global resources needed by the tenant at this point.
:arg Tenant tenant: The tenant which has been reconfigured.
"""
pass
def registerScheduler(self, scheduler):
"""Register the scheduler with the driver.
This method is optional; the base implementation does nothing.
This method is called once during initialization to allow the
driver to store a handle to the running scheduler.
:arg Scheduler scheduler: The current running scheduler.
"""
pass
@six.add_metaclass(abc.ABCMeta)
class ConnectionInterface(object):
"""The Connection interface.
A driver which is able to supply a Connection should implement
this interface.
"""
@abc.abstractmethod
def getConnection(self, name, config): def getConnection(self, name, config):
"""Create and return a new Connection object. """Create and return a new Connection object.
Required if this driver implements the Connection interface. This method is required by the interface.
This method will be called once for each connection specified This method will be called once for each connection specified
in zuul.conf. The resultant object should be responsible for in zuul.conf. The resultant object should be responsible for
@ -70,12 +108,23 @@ class Driver(object):
:rtype: Connection :rtype: Connection
""" """
raise NotImplementedError pass
@six.add_metaclass(abc.ABCMeta)
class TriggerInterface(object):
"""The trigger interface.
A driver which is able to supply a Trigger should implement this
interface.
"""
@abc.abstractmethod
def getTrigger(self, connection, config=None): def getTrigger(self, connection, config=None):
"""Create and return a new Connection object. """Create and return a new Trigger object.
Required if this driver implements the Trigger interface. This method is required by the interface.
:arg Connection connection: The Connection object associated :arg Connection connection: The Connection object associated
with the trigger (as previously returned by getConnection) with the trigger (as previously returned by getConnection)
@ -87,12 +136,35 @@ class Driver(object):
:rtype: Trigger :rtype: Trigger
""" """
raise NotImplementedError pass
@abc.abstractmethod
def getTriggerSchema(self):
"""Get the schema for this driver's trigger.
This method is required by the interface.
:returns: A voluptuous schema.
:rtype: dict or Schema
"""
pass
@six.add_metaclass(abc.ABCMeta)
class SourceInterface(object):
"""The source interface to be implemented by a driver.
A driver which is able to supply a Source should implement this
interface.
"""
@abc.abstractmethod
def getSource(self, connection): def getSource(self, connection):
"""Create and return a new Source object. """Create and return a new Source object.
Required if this driver implements the Source interface. This method is required by the interface.
:arg Connection connection: The Connection object associated :arg Connection connection: The Connection object associated
with the source (as previously returned by getConnection). with the source (as previously returned by getConnection).
@ -101,12 +173,23 @@ class Driver(object):
:rtype: Source :rtype: Source
""" """
raise NotImplementedError pass
@six.add_metaclass(abc.ABCMeta)
class ReporterInterface(object):
"""The reporter interface to be implemented by a driver.
A driver which is able to supply a Reporter should implement this
interface.
"""
@abc.abstractmethod
def getReporter(self, connection, config=None): def getReporter(self, connection, config=None):
"""Create and return a new Reporter object. """Create and return a new Reporter object.
Required if this driver implements the Reporter interface. This method is required by the interface.
:arg Connection connection: The Connection object associated :arg Connection connection: The Connection object associated
with the reporter (as previously returned by getConnection) with the reporter (as previously returned by getConnection)
@ -118,50 +201,16 @@ class Driver(object):
:rtype: Reporter :rtype: Reporter
""" """
raise NotImplementedError pass
def getTriggerSchema(self):
"""Get the schema for this driver's trigger.
Required if this driver implements the Trigger interface.
:returns: A voluptuous schema.
:rtype: dict or Schema
"""
raise NotImplementedError
@abc.abstractmethod
def getReporterSchema(self): def getReporterSchema(self):
"""Get the schema for this driver's reporter. """Get the schema for this driver's reporter.
Required if this driver implements the Reporter interface. This method is required by the interface.
:returns: A voluptuous schema. :returns: A voluptuous schema.
:rtype: dict or Schema :rtype: dict or Schema
"""
raise NotImplementedError
def reconfigure(self, tenant):
"""Called when a tenant is reconfigured.
When Zuul performs a reconfiguration for a tenant, this method
is called with the tenant (including the new layout
configuration) as an argument. The driver may establish any
global resources needed by the tenant at this point.
:arg Tenant tenant: The tenant which has been reconfigured.
"""
pass
def registerScheduler(self, scheduler):
"""Register the scheduler with the driver.
This method is called once during initialization to allow the
driver to store a handle to the running scheduler.
:arg Scheduler scheduler: The current running scheduler.
""" """
pass pass

View File

@ -12,13 +12,16 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from zuul.driver import Driver, ConnectionInterface, TriggerInterface
from zuul.driver import SourceInterface, ReporterInterface
import gerritconnection import gerritconnection
import gerrittrigger import gerrittrigger
import gerritsource import gerritsource
import gerritreporter import gerritreporter
class GerritDriver(object): class GerritDriver(Driver, ConnectionInterface, TriggerInterface,
SourceInterface, ReporterInterface):
name = 'gerrit' name = 'gerrit'
def getConnection(self, name, config): def getConnection(self, name, config):

View File

@ -12,11 +12,12 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from zuul.driver import Driver, ConnectionInterface, ReporterInterface
import smtpconnection import smtpconnection
import smtpreporter import smtpreporter
class SMTPDriver(object): class SMTPDriver(Driver, ConnectionInterface, ReporterInterface):
name = 'smtp' name = 'smtp'
def getConnection(self, name, config): def getConnection(self, name, config):

View File

@ -19,11 +19,12 @@ import logging
from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.cron import CronTrigger
from zuul.driver import Driver, TriggerInterface
from zuul.model import TriggerEvent from zuul.model import TriggerEvent
import timertrigger import timertrigger
class TimerDriver(object): class TimerDriver(Driver, TriggerInterface):
name = 'timer' name = 'timer'
log = logging.getLogger("zuul.Timer") log = logging.getLogger("zuul.Timer")

View File

@ -14,6 +14,7 @@
import logging import logging
from zuul.driver import Driver, TriggerInterface
from zuul.model import TriggerEvent from zuul.model import TriggerEvent
import zuultrigger import zuultrigger
@ -22,7 +23,7 @@ PARENT_CHANGE_ENQUEUED = 'parent-change-enqueued'
PROJECT_CHANGE_MERGED = 'project-change-merged' PROJECT_CHANGE_MERGED = 'project-change-merged'
class ZuulDriver(object): class ZuulDriver(Driver, TriggerInterface):
name = 'zuul' name = 'zuul'
log = logging.getLogger("zuul.ZuulTrigger") log = logging.getLogger("zuul.ZuulTrigger")