|
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 |
|
|
Pierre-Yves Chibon |
dd38bc |
import datetime
|
|
Pierre-Yves Chibon |
dd38bc |
import hashlib
|
|
Pierre-Yves Chibon |
dd38bc |
import hmac
|
|
Pierre-Yves Chibon |
dd38bc |
import json
|
|
Pierre-Yves Chibon |
dd38bc |
import logging
|
|
Pierre-Yves Chibon |
dd38bc |
import os
|
|
Pierre-Yves Chibon |
dd38bc |
import requests
|
|
Pierre-Yves Chibon |
dd38bc |
import time
|
|
Pierre-Yves Chibon |
dd38bc |
import uuid
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
import six
|
|
Pierre-Yves Chibon |
dd38bc |
import trollius
|
|
Pierre-Yves Chibon |
dd38bc |
import trollius_redis
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
from kitchen.text.converters import to_bytes
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
log = logging.getLogger(__name__)
|
|
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'):
|
|
Pierre-Yves Chibon |
dd38bc |
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 |
dd38bc |
import pagure
|
|
Pierre-Yves Chibon |
dd38bc |
import pagure.lib
|
|
Pierre-Yves Chibon |
dd38bc |
from pagure.exceptions import PagureEvException
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
_i = 0
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
@trollius.coroutine
|
|
Pierre-Yves Chibon |
dd38bc |
def handle_messages():
|
|
Pierre-Yves Chibon |
dd38bc |
connection = yield trollius.From(trollius_redis.Connection.create(
|
|
Pierre-Yves Chibon |
dd38bc |
host='0.0.0.0', port=6379, db=0))
|
|
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 |
dd38bc |
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 |
dd38bc |
project = data['pr']['project']['name']
|
|
Pierre-Yves Chibon |
dd38bc |
branch = data['pr']['branch_from']
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
username = None
|
|
Pierre-Yves Chibon |
dd38bc |
projectname = data['pr']['project']
|
|
Pierre-Yves Chibon |
dd38bc |
if data['pr'].get('parent'):
|
|
Pierre-Yves Chibon |
dd38bc |
username, data['pr']['project']['user']['user']
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
project = pagure.lib.get_project(
|
|
Pierre-Yves Chibon |
dd38bc |
session=pagure.SESSION, name=projectname, user=username)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
if not project:
|
|
Pierre-Yves Chibon |
dd38bc |
log.warning(
|
|
Pierre-Yves Chibon |
dd38bc |
'No project could be found from the message %s' % data)
|
|
Pierre-Yves Chibon |
dd38bc |
continue
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
repo = data['pr'].get('remote_git')
|
|
Pierre-Yves Chibon |
dd38bc |
if not repo:
|
|
Pierre-Yves Chibon |
dd38bc |
base = pagure.APP.config['APP_URL']
|
|
Pierre-Yves Chibon |
dd38bc |
if base.endswith('/'):
|
|
Pierre-Yves Chibon |
dd38bc |
base[:-1]
|
|
Pierre-Yves Chibon |
dd38bc |
base += '/%s' % project.path
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
log.info("Trigger on %s PR #%s from %s: %s",
|
|
Pierre-Yves Chibon |
dd38bc |
project.fullname, pr_id, repo, branch)
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
54793f |
url = project.ci_hook[0].ci_url
|
|
Pierre-Yves Chibon |
dd38bc |
if url.endswith('/'):
|
|
Pierre-Yves Chibon |
dd38bc |
url = url[:-1]
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
if data['ci_type'] == 'jenkins':
|
|
Pierre-Yves Chibon |
dd38bc |
url += '/buildWithParameters'
|
|
Pierre-Yves Chibon |
dd38bc |
request.post(
|
|
Pierre-Yves Chibon |
dd38bc |
url,
|
|
Pierre-Yves Chibon |
dd38bc |
data={
|
|
Pierre-Yves Chibon |
dd38bc |
'token': cfg.jenkins_token,
|
|
Pierre-Yves Chibon |
dd38bc |
'cause': pr_id,
|
|
Pierre-Yves Chibon |
dd38bc |
'REPO': repo.fullname,
|
|
Pierre-Yves Chibon |
dd38bc |
'BRANCH': branch
|
|
Pierre-Yves Chibon |
dd38bc |
}
|
|
Pierre-Yves Chibon |
dd38bc |
)
|
|
Pierre-Yves Chibon |
dd38bc |
else:
|
|
Pierre-Yves Chibon |
dd38bc |
log.warning('Un-supported CI type')
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
def main():
|
|
Pierre-Yves Chibon |
dd38bc |
server = None
|
|
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 |
dd38bc |
log.info("End Connection")
|
|
Pierre-Yves Chibon |
dd38bc |
loop.close()
|
|
Pierre-Yves Chibon |
dd38bc |
log.info("End")
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
if __name__ == '__main__':
|
|
Pierre-Yves Chibon |
dd38bc |
log = logging.getLogger("")
|
|
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 |
dd38bc |
# setup console logging
|
|
Pierre-Yves Chibon |
dd38bc |
log.setLevel(logging.DEBUG)
|
|
Pierre-Yves Chibon |
dd38bc |
ch = logging.StreamHandler()
|
|
Pierre-Yves Chibon |
dd38bc |
ch.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 |
dd38bc |
|
|
Pierre-Yves Chibon |
dd38bc |
ch.setFormatter(formatter)
|
|
Pierre-Yves Chibon |
dd38bc |
log.addHandler(ch)
|
|
Pierre-Yves Chibon |
dd38bc |
main()
|