pagure_ci_server.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. (c) 2016 - Copyright Red Hat Inc
  5. Authors:
  6. Pierre-Yves Chibon <pingou@pingoured.fr>
  7. This server listens to message sent via redis and send the corresponding
  8. web-hook request.
  9. Using this mechanism, we no longer block the main application if the
  10. receiving end is offline or so.
  11. """
  12. import json
  13. import logging
  14. import os
  15. import requests
  16. import trollius
  17. import trollius_redis
  18. _log = logging.getLogger(__name__)
  19. if 'PAGURE_CONFIG' not in os.environ \
  20. and os.path.exists('/etc/pagure/pagure.cfg'):
  21. print 'Using configuration file `/etc/pagure/pagure.cfg`'
  22. os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
  23. import pagure
  24. import pagure.lib
  25. @trollius.coroutine
  26. def handle_messages():
  27. ''' Handles connecting to redis and acting upon messages received.
  28. In this case, it means triggering a build on jenkins based on the
  29. information provided.
  30. '''
  31. host = pagure.APP.config.get('REDIS_HOST', '0.0.0.0')
  32. port = pagure.APP.config.get('REDIS_PORT', 6379)
  33. dbname = pagure.APP.config.get('REDIS_DB', 0)
  34. connection = yield trollius.From(trollius_redis.Connection.create(
  35. host=host, port=port, db=dbname))
  36. # Create subscriber.
  37. subscriber = yield trollius.From(connection.start_subscribe())
  38. # Subscribe to channel.
  39. yield trollius.From(subscriber.subscribe(['pagure.ci']))
  40. # Inside a while loop, wait for incoming events.
  41. while True:
  42. reply = yield trollius.From(subscriber.next_published())
  43. _log.info(
  44. 'Received: %s on channel: %s',
  45. repr(reply.value), reply.channel)
  46. data = json.loads(reply.value)
  47. pr_id = data['pr']['id']
  48. pr_uid = data['pr']['uid']
  49. branch = data['pr']['branch_from']
  50. _log.info('Looking for PR: %s', pr_uid)
  51. session = pagure.lib.create_session(pagure.APP.config['DB_URL'])
  52. request = pagure.lib.get_request_by_uid(session, pr_uid)
  53. _log.info('PR retrieved: %s', request)
  54. if not request:
  55. _log.warning(
  56. 'No request could be found from the message %s', data)
  57. session.close()
  58. continue
  59. _log.info(
  60. "Trigger on %s PR #%s from %s: %s",
  61. request.project.fullname, pr_id,
  62. request.project_from.fullname, branch)
  63. url = request.project.ci_hook.ci_url.rstrip('/')
  64. if data['ci_type'] == 'jenkins':
  65. url = url + '/buildWithParameters'
  66. repo = '%s/%s' % (
  67. pagure.APP.config['GIT_URL_GIT'].rstrip('/'),
  68. request.project_from.path)
  69. _log.info(
  70. 'Triggering the build at: %s, for repo: %s', url, repo)
  71. requests.post(
  72. url,
  73. data={
  74. 'token': request.project.ci_hook.pagure_ci_token,
  75. 'cause': pr_id,
  76. 'REPO': repo,
  77. 'BRANCH': branch
  78. }
  79. )
  80. else:
  81. _log.warning('Un-supported CI type')
  82. session.close()
  83. _log.info('Ready for another')
  84. def main():
  85. ''' Start the main async loop. '''
  86. try:
  87. loop = trollius.get_event_loop()
  88. tasks = [
  89. trollius.async(handle_messages()),
  90. ]
  91. loop.run_until_complete(trollius.wait(tasks))
  92. loop.run_forever()
  93. except KeyboardInterrupt:
  94. pass
  95. except trollius.ConnectionResetError:
  96. pass
  97. _log.info("End Connection")
  98. loop.close()
  99. _log.info("End")
  100. if __name__ == '__main__':
  101. formatter = logging.Formatter(
  102. "%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s")
  103. logging.basicConfig(level=logging.DEBUG)
  104. # setup console logging
  105. _log.setLevel(logging.DEBUG)
  106. shellhandler = logging.StreamHandler()
  107. shellhandler.setLevel(logging.DEBUG)
  108. aslog = logging.getLogger("asyncio")
  109. aslog.setLevel(logging.DEBUG)
  110. aslog = logging.getLogger("trollius")
  111. aslog.setLevel(logging.DEBUG)
  112. shellhandler.setFormatter(formatter)
  113. _log.addHandler(shellhandler)
  114. main()