pagure_ci_server.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 datetime
  13. import hashlib
  14. import hmac
  15. import json
  16. import logging
  17. import os
  18. import requests
  19. import time
  20. import urlparse
  21. import uuid
  22. import six
  23. import trollius
  24. import trollius_redis
  25. from kitchen.text.converters import to_bytes
  26. log = logging.getLogger(__name__)
  27. if 'PAGURE_CONFIG' not in os.environ \
  28. and os.path.exists('/etc/pagure/pagure.cfg'):
  29. print 'Using configuration file `/etc/pagure/pagure.cfg`'
  30. os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
  31. import pagure
  32. import pagure.lib
  33. from pagure.exceptions import PagureEvException
  34. @trollius.coroutine
  35. def handle_messages():
  36. host = pagure.APP.config.get('REDIS_HOST', '0.0.0.0')
  37. port = pagure.APP.config.get('REDIS_PORT', 6379)
  38. db = pagure.APP.config.get('REDIS_DB', 0)
  39. connection = yield trollius.From(trollius_redis.Connection.create(
  40. host=host, port=port, db=db))
  41. # Create subscriber.
  42. subscriber = yield trollius.From(connection.start_subscribe())
  43. # Subscribe to channel.
  44. yield trollius.From(subscriber.subscribe(['pagure.ci']))
  45. # Inside a while loop, wait for incoming events.
  46. while True:
  47. reply = yield trollius.From(subscriber.next_published())
  48. log.info(
  49. 'Received: %s on channel: %s',
  50. repr(reply.value), reply.channel)
  51. data = json.loads(reply.value)
  52. pr_id = data['pr']['id']
  53. project = data['pr']['project']['name']
  54. branch = data['pr']['branch_from']
  55. username = None
  56. projectname = data['pr']['project']['name']
  57. if data['pr'].get('parent'):
  58. username, data['pr']['project']['user']['user']
  59. project = pagure.lib.get_project(
  60. session=pagure.SESSION, name=projectname, user=username)
  61. if not project:
  62. log.warning(
  63. 'No project could be found from the message %s' % data)
  64. continue
  65. repo = data['pr'].get('remote_git')
  66. if not repo:
  67. base = pagure.APP.config['APP_URL']
  68. if base.endswith('/'):
  69. base[:-1]
  70. base += '/%s' % project.path
  71. log.info("Trigger on %s PR #%s from %s: %s",
  72. project.fullname, pr_id, repo, branch)
  73. url = project.ci_hook[0].ci_url
  74. if data['ci_type'] == 'jenkins':
  75. url = urlparse.urljoin(url, '/buildWithParameters')
  76. log.info('Triggering the build at: %s', url)
  77. requests.post(
  78. url,
  79. data={
  80. 'token': project.ci_hook[0].pagure_ci_token,
  81. 'cause': pr_id,
  82. 'REPO': project.fullname,
  83. 'BRANCH': branch
  84. }
  85. )
  86. else:
  87. log.warning('Un-supported CI type')
  88. log.info('Ready for another')
  89. def main():
  90. server = None
  91. try:
  92. loop = trollius.get_event_loop()
  93. tasks = [
  94. trollius.async(handle_messages()),
  95. ]
  96. loop.run_until_complete(trollius.wait(tasks))
  97. loop.run_forever()
  98. except KeyboardInterrupt:
  99. pass
  100. except trollius.ConnectionResetError:
  101. pass
  102. log.info("End Connection")
  103. loop.close()
  104. log.info("End")
  105. if __name__ == '__main__':
  106. log = logging.getLogger("")
  107. formatter = logging.Formatter(
  108. "%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s")
  109. # setup console logging
  110. log.setLevel(logging.DEBUG)
  111. ch = logging.StreamHandler()
  112. ch.setLevel(logging.DEBUG)
  113. aslog = logging.getLogger("asyncio")
  114. aslog.setLevel(logging.DEBUG)
  115. ch.setFormatter(formatter)
  116. log.addHandler(ch)
  117. main()