Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    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()