bugzilla.bbclass 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #
  2. # Small event handler to automatically open URLs and file
  3. # bug reports at a bugzilla of your choiche
  4. # it uses XML-RPC interface, so you must have it enabled
  5. #
  6. # Before using you must define BUGZILLA_USER, BUGZILLA_PASS credentials,
  7. # BUGZILLA_XMLRPC - uri of xmlrpc.cgi,
  8. # BUGZILLA_PRODUCT, BUGZILLA_COMPONENT - a place in BTS for build bugs
  9. # BUGZILLA_VERSION - version against which to report new bugs
  10. #
  11. def bugzilla_find_bug_report(debug_file, server, args, bugname):
  12. args['summary'] = bugname
  13. bugs = server.Bug.search(args)
  14. if len(bugs['bugs']) == 0:
  15. print >> debug_file, "Bugs not found"
  16. return (False,None)
  17. else: # silently pick the first result
  18. print >> debug_file, "Result of bug search is "
  19. print >> debug_file, bugs
  20. status = bugs['bugs'][0]['status']
  21. id = bugs['bugs'][0]['id']
  22. return (not status in ["CLOSED", "RESOLVED", "VERIFIED"],id)
  23. def bugzilla_file_bug(debug_file, server, args, name, text, version):
  24. args['summary'] = name
  25. args['comment'] = text
  26. args['version'] = version
  27. args['op_sys'] = 'Linux'
  28. args['platform'] = 'Other'
  29. args['severity'] = 'normal'
  30. args['priority'] = 'Normal'
  31. try:
  32. return server.Bug.create(args)['id']
  33. except Exception, e:
  34. print >> debug_file, repr(e)
  35. return None
  36. def bugzilla_reopen_bug(debug_file, server, args, bug_number):
  37. args['ids'] = [bug_number]
  38. args['status'] = "CONFIRMED"
  39. try:
  40. server.Bug.update(args)
  41. return True
  42. except Exception, e:
  43. print >> debug_file, repr(e)
  44. return False
  45. def bugzilla_create_attachment(debug_file, server, args, bug_number, text, file_name, log, logdescription):
  46. args['ids'] = [bug_number]
  47. args['file_name'] = file_name
  48. args['summary'] = logdescription
  49. args['content_type'] = "text/plain"
  50. args['data'] = log
  51. args['comment'] = text
  52. try:
  53. server.Bug.add_attachment(args)
  54. return True
  55. except Exception, e:
  56. print >> debug_file, repr(e)
  57. return False
  58. def bugzilla_add_comment(debug_file, server, args, bug_number, text):
  59. args['id'] = bug_number
  60. args['comment'] = text
  61. try:
  62. server.Bug.add_comment(args)
  63. return True
  64. except Exception, e:
  65. print >> debug_file, repr(e)
  66. return False
  67. addhandler bugzilla_eventhandler
  68. bugzilla_eventhandler[eventmask] = "bb.event.MsgNote bb.build.TaskFailed"
  69. python bugzilla_eventhandler() {
  70. import glob
  71. import xmlrpclib, httplib
  72. class ProxiedTransport(xmlrpclib.Transport):
  73. def __init__(self, proxy, use_datetime = 0):
  74. xmlrpclib.Transport.__init__(self, use_datetime)
  75. self.proxy = proxy
  76. self.user = None
  77. self.password = None
  78. def set_user(self, user):
  79. self.user = user
  80. def set_password(self, password):
  81. self.password = password
  82. def make_connection(self, host):
  83. self.realhost = host
  84. return httplib.HTTP(self.proxy)
  85. def send_request(self, connection, handler, request_body):
  86. connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
  87. if self.user != None:
  88. if self.password != None:
  89. auth = "%s:%s" % (self.user, self.password)
  90. else:
  91. auth = self.user
  92. connection.putheader("Proxy-authorization", "Basic " + base64.encodestring(auth))
  93. event = e
  94. data = e.data
  95. name = bb.event.getName(event)
  96. if name == "MsgNote":
  97. # avoid recursion
  98. return
  99. if name == "TaskFailed":
  100. xmlrpc = data.getVar("BUGZILLA_XMLRPC")
  101. user = data.getVar("BUGZILLA_USER")
  102. passw = data.getVar("BUGZILLA_PASS")
  103. product = data.getVar("BUGZILLA_PRODUCT")
  104. compon = data.getVar("BUGZILLA_COMPONENT")
  105. version = data.getVar("BUGZILLA_VERSION")
  106. proxy = data.getVar('http_proxy')
  107. if (proxy):
  108. import urllib2
  109. s, u, p, hostport = urllib2._parse_proxy(proxy)
  110. transport = ProxiedTransport(hostport)
  111. else:
  112. transport = None
  113. server = xmlrpclib.ServerProxy(xmlrpc, transport=transport, verbose=0)
  114. args = {
  115. 'Bugzilla_login': user,
  116. 'Bugzilla_password': passw,
  117. 'product': product,
  118. 'component': compon}
  119. # evil hack to figure out what is going on
  120. debug_file = open(os.path.join(data.getVar("TMPDIR"),"..","bugzilla-log"),"a")
  121. file = None
  122. bugname = "%(package)s-%(pv)s-autobuild" % { "package" : data.getVar("PN"),
  123. "pv" : data.getVar("PV"),
  124. }
  125. log_file = glob.glob("%s/log.%s.*" % (event.data.getVar('T'), event.task))
  126. text = "The %s step in %s failed at %s for machine %s" % (e.task, data.getVar("PN"), data.getVar('DATETIME'), data.getVar('MACHINE') )
  127. if len(log_file) != 0:
  128. print >> debug_file, "Adding log file %s" % log_file[0]
  129. file = open(log_file[0], 'r')
  130. log = file.read()
  131. file.close();
  132. else:
  133. print >> debug_file, "No log file found for the glob"
  134. log = None
  135. (bug_open, bug_number) = bugzilla_find_bug_report(debug_file, server, args.copy(), bugname)
  136. print >> debug_file, "Bug is open: %s and bug number: %s" % (bug_open, bug_number)
  137. # The bug is present and still open, attach an error log
  138. if not bug_number:
  139. bug_number = bugzilla_file_bug(debug_file, server, args.copy(), bugname, text, version)
  140. if not bug_number:
  141. print >> debug_file, "Couldn't acquire a new bug_numer, filing a bugreport failed"
  142. else:
  143. print >> debug_file, "The new bug_number: '%s'" % bug_number
  144. elif not bug_open:
  145. if not bugzilla_reopen_bug(debug_file, server, args.copy(), bug_number):
  146. print >> debug_file, "Failed to reopen the bug #%s" % bug_number
  147. else:
  148. print >> debug_file, "Reopened the bug #%s" % bug_number
  149. if bug_number and log:
  150. print >> debug_file, "The bug is known as '%s'" % bug_number
  151. desc = "Build log for machine %s" % (data.getVar('MACHINE'))
  152. if not bugzilla_create_attachment(debug_file, server, args.copy(), bug_number, text, log_file[0], log, desc):
  153. print >> debug_file, "Failed to attach the build log for bug #%s" % bug_number
  154. else:
  155. print >> debug_file, "Created an attachment for '%s' '%s' '%s'" % (product, compon, bug_number)
  156. else:
  157. print >> debug_file, "Not trying to create an attachment for bug #%s" % bug_number
  158. if not bugzilla_add_comment(debug_file, server, args.copy(), bug_number, text, ):
  159. print >> debug_file, "Failed to create a comment the build log for bug #%s" % bug_number
  160. else:
  161. print >> debug_file, "Created an attachment for '%s' '%s' '%s'" % (product, compon, bug_number)
  162. # store bug number for oestats-client
  163. if bug_number:
  164. data.setVar('OESTATS_BUG_NUMBER', bug_number)
  165. }