|
Pierre-Yves Chibon |
dd38bc |
#!/usr/bin/env python
|
|
Pierre-Yves Chibon |
dd38bc |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
"""
|
|
Pierre-Yves Chibon |
dd38bc |
(c) 2016 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
Authors:
|
|
Pierre-Yves Chibon |
dd38bc |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
This server listens to message sent via redis and send the corresponding
|
|
Pierre-Yves Chibon |
dd38bc |
web-hook request.
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
Using this mechanism, we no longer block the main application if the
|
|
Pierre-Yves Chibon |
dd38bc |
receiving end is offline or so.
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
"""
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Vadim Rutkovsky |
9b6a62 |
from __future__ import print_function
|
|
Pierre-Yves Chibon |
dd38bc |
import json
|
|
Pierre-Yves Chibon |
dd38bc |
import logging
|
|
Pierre-Yves Chibon |
dd38bc |
import os
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
30e2e6 |
import jenkins
|
|
Pierre-Yves Chibon |
dd38bc |
import trollius
|
|
Pierre-Yves Chibon |
dd38bc |
import trollius_redis
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
b130e5 |
import pagure
|
|
Pierre-Yves Chibon |
b130e5 |
import pagure.lib
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
if 'PAGURE_CONFIG' not in os.environ \
|
|
Pierre-Yves Chibon |
dd38bc |
and os.path.exists('/etc/pagure/pagure.cfg'):
|
|
Vadim Rutkovsky |
9b6a62 |
print('Using configuration file `/etc/pagure/pagure.cfg`')
|
|
Pierre-Yves Chibon |
dd38bc |
os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
b130e5 |
_log = logging.getLogger(__name__)
|
|
Pierre-Yves Chibon |
b130e5 |
_config = pagure.config.config.reload_config()
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
@trollius.coroutine
|
|
Pierre-Yves Chibon |
dd38bc |
def handle_messages():
|
|
Pierre-Yves Chibon |
d31d7e |
''' Handles connecting to redis and acting upon messages received.
|
|
Pierre-Yves Chibon |
d31d7e |
In this case, it means triggering a build on jenkins based on the
|
|
Pierre-Yves Chibon |
d31d7e |
information provided.
|
|
Pierre-Yves Chibon |
d31d7e |
'''
|
|
Pierre-Yves Chibon |
d31d7e |
|
|
Pierre-Yves Chibon |
b130e5 |
host = _config.get('REDIS_HOST', '0.0.0.0')
|
|
Pierre-Yves Chibon |
b130e5 |
port = _config.get('REDIS_PORT', 6379)
|
|
Pierre-Yves Chibon |
b130e5 |
dbname = _config.get('REDIS_DB', 0)
|
|
Pierre-Yves Chibon |
dd38bc |
connection = yield trollius.From(trollius_redis.Connection.create(
|
|
Pierre-Yves Chibon |
d31d7e |
host=host, port=port, db=dbname))
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
# Create subscriber.
|
|
Pierre-Yves Chibon |
dd38bc |
subscriber = yield trollius.From(connection.start_subscribe())
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
# Subscribe to channel.
|
|
Pierre-Yves Chibon |
dd38bc |
yield trollius.From(subscriber.subscribe(['pagure.ci']))
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
# Inside a while loop, wait for incoming events.
|
|
Pierre-Yves Chibon |
dd38bc |
while True:
|
|
Pierre-Yves Chibon |
dd38bc |
reply = yield trollius.From(subscriber.next_published())
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info(
|
|
Pierre-Yves Chibon |
dd38bc |
'Received: %s on channel: %s',
|
|
Pierre-Yves Chibon |
dd38bc |
repr(reply.value), reply.channel)
|
|
Pierre-Yves Chibon |
dd38bc |
data = json.loads(reply.value)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
pr_id = data['pr']['id']
|
|
Pierre-Yves Chibon |
6c8123 |
pr_uid = data['pr']['uid']
|
|
Pierre-Yves Chibon |
dd38bc |
branch = data['pr']['branch_from']
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info('Looking for PR: %s', pr_uid)
|
|
Pierre-Yves Chibon |
b130e5 |
session = pagure.lib.create_session(_config['DB_URL'])
|
|
Pierre-Yves Chibon |
d3ad5b |
request = pagure.lib.get_request_by_uid(session, pr_uid)
|
|
Pierre-Yves Chibon |
be8146 |
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info('PR retrieved: %s', request)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
6c8123 |
if not request:
|
|
Pierre-Yves Chibon |
4635b5 |
_log.warning(
|
|
Pierre-Yves Chibon |
6c8123 |
'No request could be found from the message %s', data)
|
|
Pierre-Yves Chibon |
be8146 |
session.close()
|
|
Pierre-Yves Chibon |
dd38bc |
continue
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info(
|
|
Pierre-Yves Chibon |
bf6903 |
"Trigger on %s PR #%s from %s: %s",
|
|
Pierre-Yves Chibon |
6c8123 |
request.project.fullname, pr_id,
|
|
Pierre-Yves Chibon |
6c8123 |
request.project_from.fullname, branch)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
6c8123 |
url = request.project.ci_hook.ci_url.rstrip('/')
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
if data['ci_type'] == 'jenkins':
|
|
Pierre-Yves Chibon |
2f0ff3 |
_log.info('Jenkins CI')
|
|
Pierre-Yves Chibon |
3e1101 |
repo = '%s/%s' % (
|
|
Pierre-Yves Chibon |
b130e5 |
_config['GIT_URL_GIT'].rstrip('/'),
|
|
Pierre-Yves Chibon |
6c8123 |
request.project_from.path)
|
|
Pierre-Yves Chibon |
30e2e6 |
|
|
Pierre-Yves Chibon |
30e2e6 |
# Jenkins Base URL
|
|
Pierre-Yves Chibon |
30e2e6 |
base_url, name = url.split('/job/', 1)
|
|
Pierre-Yves Chibon |
30e2e6 |
jenkins_name = name.split('/', 1)[0]
|
|
Pierre-Yves Chibon |
30e2e6 |
|
|
Pierre-Yves Chibon |
30e2e6 |
data = {
|
|
Pierre-Yves Chibon |
30e2e6 |
'cause': pr_id,
|
|
Pierre-Yves Chibon |
30e2e6 |
'REPO': repo,
|
|
Pierre-Yves Chibon |
30e2e6 |
'BRANCH': branch
|
|
Pierre-Yves Chibon |
30e2e6 |
}
|
|
Pierre-Yves Chibon |
30e2e6 |
|
|
Pierre-Yves Chibon |
30e2e6 |
server = jenkins.Jenkins(base_url)
|
|
Pierre-Yves Chibon |
fc1fad |
_log.info('Triggering at: %s for: %s - data: %s' % (
|
|
Pierre-Yves Chibon |
fc1fad |
base_url, jenkins_name, data))
|
|
Pierre-Yves Chibon |
2f0ff3 |
try:
|
|
Pierre-Yves Chibon |
2f0ff3 |
server.build_job(
|
|
Pierre-Yves Chibon |
2f0ff3 |
name=jenkins_name,
|
|
Pierre-Yves Chibon |
2f0ff3 |
parameters=data,
|
|
Pierre-Yves Chibon |
2f0ff3 |
token=request.project.ci_hook.pagure_ci_token
|
|
Pierre-Yves Chibon |
2f0ff3 |
)
|
|
Pierre-Yves Chibon |
2f0ff3 |
_log.info('Build triggered')
|
|
Pierre-Yves Chibon |
2f0ff3 |
except Exception as err:
|
|
Pierre-Yves Chibon |
2f0ff3 |
_log.info('An error occured: %s', err)
|
|
Pierre-Yves Chibon |
2f0ff3 |
|
|
Pierre-Yves Chibon |
dd38bc |
else:
|
|
Pierre-Yves Chibon |
4635b5 |
_log.warning('Un-supported CI type')
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
be8146 |
session.close()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info('Ready for another')
|
|
Pierre-Yves Chibon |
bb02dc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
def main():
|
|
Pierre-Yves Chibon |
d31d7e |
''' Start the main async loop. '''
|
|
Pierre-Yves Chibon |
d31d7e |
|
|
Pierre-Yves Chibon |
dd38bc |
try:
|
|
Pierre-Yves Chibon |
dd38bc |
loop = trollius.get_event_loop()
|
|
Pierre-Yves Chibon |
dd38bc |
tasks = [
|
|
Pierre-Yves Chibon |
dd38bc |
trollius.async(handle_messages()),
|
|
Pierre-Yves Chibon |
dd38bc |
]
|
|
Pierre-Yves Chibon |
dd38bc |
loop.run_until_complete(trollius.wait(tasks))
|
|
Pierre-Yves Chibon |
dd38bc |
loop.run_forever()
|
|
Pierre-Yves Chibon |
dd38bc |
except KeyboardInterrupt:
|
|
Pierre-Yves Chibon |
dd38bc |
pass
|
|
Pierre-Yves Chibon |
dd38bc |
except trollius.ConnectionResetError:
|
|
Pierre-Yves Chibon |
dd38bc |
pass
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info("End Connection")
|
|
Pierre-Yves Chibon |
dd38bc |
loop.close()
|
|
Pierre-Yves Chibon |
4635b5 |
_log.info("End")
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
if __name__ == '__main__':
|
|
Pierre-Yves Chibon |
dd38bc |
formatter = logging.Formatter(
|
|
Pierre-Yves Chibon |
dd38bc |
"%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s")
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
fe4b65 |
logging.basicConfig(level=logging.DEBUG)
|
|
Pierre-Yves Chibon |
fe4b65 |
|
|
Pierre-Yves Chibon |
dd38bc |
# setup console logging
|
|
Pierre-Yves Chibon |
4635b5 |
_log.setLevel(logging.DEBUG)
|
|
Pierre-Yves Chibon |
d31d7e |
shellhandler = logging.StreamHandler()
|
|
Pierre-Yves Chibon |
d31d7e |
shellhandler.setLevel(logging.DEBUG)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
aslog = logging.getLogger("asyncio")
|
|
Pierre-Yves Chibon |
dd38bc |
aslog.setLevel(logging.DEBUG)
|
|
Pierre-Yves Chibon |
6c8123 |
aslog = logging.getLogger("trollius")
|
|
Pierre-Yves Chibon |
6c8123 |
aslog.setLevel(logging.DEBUG)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
d31d7e |
shellhandler.setFormatter(formatter)
|
|
Pierre-Yves Chibon |
4635b5 |
_log.addHandler(shellhandler)
|
|
Pierre-Yves Chibon |
dd38bc |
main()
|