Adding hipchat notification capability.
Tweaks the Builder and YamlParser classes to accept a config object which is passed to the parser's ModuleRegistry object. This makes it available to the HipChat object. Change-Id: I3017658336b949c0fda7c82945e7014dbcf6e152 Reviewed-on: https://review.openstack.org/12794 Reviewed-by: James E. Blair <corvus@inaugust.com> Reviewed-by: Clark Boylan <clark.boylan@gmail.com> Approved: James E. Blair <corvus@inaugust.com> Tested-by: Jenkins
This commit is contained in:
parent
b6af0f0060
commit
5465ab6d4f
@ -184,6 +184,7 @@ The bulk of the job definitions come from the following modules.
|
||||
project_maven
|
||||
general
|
||||
builders
|
||||
hipchat
|
||||
notifications
|
||||
parameters
|
||||
properties
|
||||
|
7
doc/source/hipchat.rst
Normal file
7
doc/source/hipchat.rst
Normal file
@ -0,0 +1,7 @@
|
||||
.. _hipchat:
|
||||
|
||||
Hipchat
|
||||
==========
|
||||
|
||||
.. automodule:: hipchat_notif
|
||||
:members:
|
@ -45,7 +45,8 @@ def main():
|
||||
logger.debug("Config: {0}".format(config))
|
||||
builder = jenkins_jobs.builder.Builder(config.get('jenkins', 'url'),
|
||||
config.get('jenkins', 'user'),
|
||||
config.get('jenkins', 'password'))
|
||||
config.get('jenkins', 'password'),
|
||||
config)
|
||||
|
||||
if options.command == 'delete':
|
||||
for job in options.name:
|
||||
|
@ -29,8 +29,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class YamlParser(object):
|
||||
def __init__(self):
|
||||
self.registry = ModuleRegistry()
|
||||
def __init__(self, config=None):
|
||||
self.registry = ModuleRegistry(config)
|
||||
self.data = {}
|
||||
self.jobs = []
|
||||
|
||||
@ -150,9 +150,10 @@ class YamlParser(object):
|
||||
|
||||
|
||||
class ModuleRegistry(object):
|
||||
def __init__(self):
|
||||
def __init__(self, config):
|
||||
self.modules = []
|
||||
self.handlers = {}
|
||||
self.global_config = config
|
||||
|
||||
for entrypoint in pkg_resources.iter_entry_points(
|
||||
group='jenkins_jobs.modules'):
|
||||
@ -242,9 +243,11 @@ class Jenkins(object):
|
||||
|
||||
|
||||
class Builder(object):
|
||||
def __init__(self, jenkins_url, jenkins_user, jenkins_password):
|
||||
def __init__(self, jenkins_url, jenkins_user, jenkins_password,
|
||||
config=None):
|
||||
self.jenkins = Jenkins(jenkins_url, jenkins_user, jenkins_password)
|
||||
self.cache = CacheStorage()
|
||||
self.global_config = config
|
||||
|
||||
def delete_job(self, name):
|
||||
self.jenkins.delete_job(name)
|
||||
@ -258,7 +261,7 @@ class Builder(object):
|
||||
if (f.endswith('.yml') or f.endswith('.yaml'))]
|
||||
else:
|
||||
files_to_process = [fn]
|
||||
parser = YamlParser()
|
||||
parser = YamlParser(self.global_config)
|
||||
for in_file in files_to_process:
|
||||
logger.debug("Parsing YAML file {0}".format(in_file))
|
||||
parser.parse(in_file)
|
||||
|
106
jenkins_jobs/modules/hipchat_notif.py
Normal file
106
jenkins_jobs/modules/hipchat_notif.py
Normal file
@ -0,0 +1,106 @@
|
||||
# Copyright 2012 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Enable hipchat notification of build execution.
|
||||
|
||||
Example::
|
||||
|
||||
- job:
|
||||
name: test_job
|
||||
hipchat:
|
||||
enabled: true
|
||||
room: Testjob Build Notifications
|
||||
start-notify: true
|
||||
|
||||
In the jenkins UI specification, the hipchat plugin must be explicitly
|
||||
selected as a publisher. This is not required (or supported) here - use the
|
||||
``enabled`` parameter to enable/disable the publisher action.
|
||||
If you set ``enabled: false``, no hipchat parameters are written to XML.
|
||||
"""
|
||||
|
||||
# Enabling hipchat notifications on a job requires specifying the hipchat
|
||||
# config in job properties, and adding the hipchat notifier to the job's
|
||||
# publishers list.
|
||||
# The publisher configuration contains extra details not specified per job:
|
||||
# - the hipchat authorisation token.
|
||||
# - the jenkins server url.
|
||||
# - a default room name/id.
|
||||
# This complicates matters somewhat since the sensible place to store these
|
||||
# details is in the global config file.
|
||||
# The global config object is therefore passed down to the registry object,
|
||||
# and this object is passed to the HipChat() class initialiser.
|
||||
|
||||
import xml.etree.ElementTree as XML
|
||||
import jenkins_jobs.modules.base
|
||||
import jenkins_jobs.errors
|
||||
import logging
|
||||
import ConfigParser
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HipChat(jenkins_jobs.modules.base.Base):
|
||||
sequence = 80
|
||||
|
||||
def __init__(self, registry):
|
||||
self.authToken = None
|
||||
self.jenkinsUrl = None
|
||||
self.registry = registry
|
||||
|
||||
def _load_global_data(self):
|
||||
"""Load data from the global config object.
|
||||
This is done lazily to avoid looking up the '[hipchat]' section
|
||||
unless actually required.
|
||||
"""
|
||||
if(not self.authToken):
|
||||
# Verify that the config object in the registry is of type
|
||||
# ConfigParser (it could possibly be a regular 'dict' object which
|
||||
# doesn't have the right get() method).
|
||||
if(not isinstance(self.registry.global_config,
|
||||
ConfigParser.ConfigParser)):
|
||||
raise jenkins_jobs.errors.JenkinsJobsException(
|
||||
'HipChat requires a config object in the registry.')
|
||||
self.authToken = self.registry.global_config.get(
|
||||
'hipchat', 'authtoken')
|
||||
self.jenkinsUrl = self.registry.global_config.get('jenkins', 'url')
|
||||
|
||||
def gen_xml(self, parser, xml_parent, data):
|
||||
hipchat = data.get('hipchat')
|
||||
if not hipchat or not hipchat.get('enabled', True):
|
||||
return
|
||||
if('room' not in hipchat):
|
||||
raise jenkins_jobs.errors.YAMLFormatError(
|
||||
"Missing hipchat 'room' specifier")
|
||||
self._load_global_data()
|
||||
|
||||
properties = xml_parent.find('properties')
|
||||
if properties is None:
|
||||
properties = XML.SubElement(xml_parent, 'properties')
|
||||
pdefhip = XML.SubElement(properties,
|
||||
'jenkins.plugins.hipchat.HipChatNotifier_-HipChatJobProperty')
|
||||
XML.SubElement(pdefhip, 'room').text = hipchat['room']
|
||||
XML.SubElement(pdefhip, 'startNotification').text = str(
|
||||
hipchat.get('start-notify', 'false')).lower()
|
||||
|
||||
publishers = xml_parent.find('publishers')
|
||||
if publishers is None:
|
||||
publishers = XML.SubElement(xml_parent, 'publishers')
|
||||
hippub = XML.SubElement(publishers,
|
||||
'jenkins.plugins.hipchat.HipChatNotifier')
|
||||
XML.SubElement(hippub, 'jenkinsUrl').text = self.jenkinsUrl
|
||||
XML.SubElement(hippub, 'authToken').text = self.authToken
|
||||
# The room specified here is the default room. The default is
|
||||
# redundant in this case since a room must be specified. Leave empty.
|
||||
XML.SubElement(hippub, 'room').text = ''
|
1
setup.py
1
setup.py
@ -95,6 +95,7 @@ setup(name='jenkins_job_builder',
|
||||
'triggers=jenkins_jobs.modules.triggers:Triggers',
|
||||
'wrappers=jenkins_jobs.modules.wrappers:Wrappers',
|
||||
'zuul=jenkins_jobs.modules.zuul:Zuul',
|
||||
'hipchat=jenkins_jobs.modules.hipchat_notif:HipChat',
|
||||
]
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user