def update_bugs(self, problem_list, template_name="bugzilla_update_comment", dry_run=False): """ Iterate over `problem_list` and add comment to bugs that has no comment from us or where our comment is outdated (report count is less than half of current report count). """ reports_count_regex = re.compile("reports:(\d+)") total = len(problem_list) for num, problem in enumerate(problem_list): logging.info("Processing problem #{0}, {1} of {2}".format( problem.id, num + 1, total)) current_count = problem.reports_count buglist = problem.bugs btotal = len(buglist) for bnum, bug in enumerate(problem.bugs): logging.debug("Checking bug #{0}, {1} of {2}".format( bug.id, bnum + 1, btotal)) new_wb = None if "reports:" in bug.whiteboard: matches = reports_count_regex.finditer(bug.whiteboard) res = list(matches)[0] if res: previous_count = int(res.group(1)) logging.debug("Previous report count: {0}".format( previous_count)) logging.debug("Current report count: {0}".format( current_count)) # previous number of reports should never be smaller # than current number of reports assert(previous_count <= current_count) # if there"s our comment we only add new one # when number of reports is twice as high if previous_count * 2 >= current_count: logging.info("Current number of reports is" " not high enough. Not updating") continue replacement = "reports:{0}".format(current_count) new_wb = reports_count_regex.sub(replacement, bug.whiteboard, count=1) if not new_wb: if not bug.whiteboard: new_wb = "reports:{0}".format(current_count) else: new_wb = "{0} reports:{1}".format(bug.whiteboard, current_count) # get top report if not problem.reports: logging.warning("Refusing to process problem with no reports.") continue report = problem.sorted_reports[0] if not report.backtraces: logging.warning("Refusing to process report with no backtrace.") continue faf_hash = report.backtraces[0].hash comment = template.render(template_name, dict(report_count=current_count, problem=problem, faf_hash=faf_hash)) logging.info("Adding comment to bug #{0}." " Comment:\n\n{1}\n".format(bug.id, comment)) if dry_run: logging.info("Dry run enabled. Not performing any action.") continue try: self.set_whiteboard(bug.id, new_wb, comment) downloaded = self.download_bug(bug.id) if downloaded: bug = self.save_bug(downloaded) except KeyboardInterrupt: return except: logging.error("Unable to add update bug #{0}".format(bug.id))
def create_bugs(self, problem_list, summary_template="bugzilla_new_summary", description_template="bugzilla_new_body", dry_run=False): """ Iterate over `problem_list` and create bugzilla tickets for these problems. After the ticket creation, it downloads the bug and assigns it to respective problem. """ total = len(problem_list) for num, problem in enumerate(problem_list): logging.info("Processing problem #{0}, {1} of {2}".format( problem.id, num + 1, total)) data = dict(problem=problem) components = problem.unique_component_names if not components: logging.error("Problem has no components, skipping.") continue if len(components) > 1: data["all_components"] = " ".join(components) # pick first and assign this bug to it data["component"] = components.pop() if not problem.reports: logging.warning("Refusing to process problem with no reports.") continue report = problem.sorted_reports[0] if not report.backtraces: logging.warning("Refusing to process report with no backtrace.") continue backtrace = report.backtraces[0] if not self.backtrace_reportable(backtrace): logging.warning("Backtrace not reportable, skipping.") continue if pyfaf.kb.report_in_kb(self.db, report): logging.info("Report matches knowledge base entry, skipping.") continue if report.packages: data["package"] = report.packages[0].installed_package if report.reasons: data["reason"] = report.reasons[0] data["type"] = report.type data["first_occurence"] = problem.first_occurence data["reports_count"] = problem.reports_count if report.executables: data["executable"] = report.executables[0].path data["duphash"] = backtrace.hash data["faf_hash"] = backtrace.hash highest_version = -1 highest_release = None for report_release in report.opsysreleases: if report_release.opsysrelease.version > highest_version: highest_version = report_release.opsysrelease.version highest_release = report_release.opsysrelease if not highest_release: logging.error("No OpSysRelease assigned to this report," " skipping") continue data["os_release"] = highest_release if report.arches: data["architecture"] = report.arches[0] # format backtrace backtrace_headers = { "USERSPACE": ["#", "Function", "Path", "Source"], "KERNELOOPS": ["#", "Function", "Binary", "Source"], "PYTHON": ["#", "Function", "Source"], } if not report.type in backtrace_headers: logging.error("Do not know how to format backtrace for report" " type {0}, skipping.".format(report.type)) continue backtrace_header = backtrace_headers[report.type] frames = backtrace.as_named_tuples() our_frames = [] for position, frame in enumerate(frames): more = "" name = frame.name # strip arguments in case of c++ function names containing # long lists of them if "(" in name: name = name.split("(")[0] if frame.source_path and frame.line_num: more = "{0}:{1}".format(frame.source_path, frame.line_num) if report.type == "PYTHON": our_frames.append((position, name, "{0}:{1}".format(frame.source_path, frame.line_num))) else: our_frames.append((position, name, frame.path, more)) data["backtrace"] = pyfaf.support.as_table( backtrace_header, our_frames, margin=2) summary = template.render(summary_template, data) description = template.render(description_template, data) bz_data = dict() bz_data["component"] = str(data["component"]) bz_data["product"] = str(data["os_release"].opsys) bz_data["version"] = str(data["os_release"].version) bz_data["summary"] = summary bz_data["description"] = description bz_data["status_whiteboard"] = "abrt_hash:{0} reports:{1}".format( data["duphash"], data["reports_count"]) if dry_run: print(summary) print(description) logging.info("Dry run enabled. Not performing any action.") continue try: # create new_bug = self.create_bug(**bz_data) except: logging.error("Unable to create new bug") continue bug = None try: # download downloaded = self.download_bug(new_bug.id) if downloaded: bug = self.save_bug(downloaded) except: raise logging.error("Unable to download bug #{0}".format(new_bug.id)) continue # connect to report if bug: new = ReportRhbz() new.report = report new.rhbzbug = bug self.db.session.add(new) self.db.session.flush()