Пример #1
0
def save_attachment(db, attachment):
    atype = attachment["type"].lower()

    if not attachment_type_allowed(atype):
        raise FafError(
            "Attachment type '{}' not allowed on this server".format(atype))

    report = get_report(db, attachment["bthash"])
    if not report:
        raise FafError("Report for given bthash not found")

    if atype in ["rhbz", "fedora-bugzilla", "rhel-bugzilla"]:
        bug_id = int(attachment["data"])

        reportbug = (db.session.query(
            ReportBz).filter((ReportBz.report_id == report.id)
                             & (ReportBz.bzbug_id == bug_id)).first())

        if reportbug:
            log.debug("Skipping existing attachment")
            return

        bug = get_bz_bug(db, bug_id)
        if not bug:
            if atype in bugtrackers:
                # download from bugtracker identified by atype
                tracker = bugtrackers[atype]

                if not tracker.installed(db):
                    raise FafError("Bugtracker used in this attachment"
                                   " is not installed")

                bug = tracker.download_bug_to_storage(db, bug_id)
            elif atype == "rhbz":
                # legacy value
                # - we need to guess the bugtracker:
                # either fedora-bugzilla or rhel-bugzilla,
                # former is more probable
                for possible_tracker in ["fedora-bugzilla", "rhel-bugzilla"]:
                    if possible_tracker not in bugtrackers:
                        continue

                    tracker = bugtrackers[possible_tracker]
                    if not tracker.installed(db):
                        continue

                    bug = tracker.download_bug_to_storage(db, bug_id)
                    if bug:
                        break

        if bug:
            new = ReportBz()
            new.report = report
            new.bzbug = bug
            db.session.add(new)
            db.session.flush()
        else:
            log.error("Failed to fetch bug #{0} from '{1}'".format(
                bug_id, atype))

    elif atype == "centos-mantisbt":
        bug_id = int(attachment["data"])

        reportbug = (db.session.query(ReportMantis).filter(
            (ReportMantis.report_id == report.id)
            & (ReportMantis.mantisbug_id == bug_id)).first())

        if reportbug:
            log.debug("Skipping existing attachment")
            return

        bug = get_mantis_bug(db, bug_id)
        if not bug:
            if atype in bugtrackers:
                # download from bugtracker identified by atype
                tracker = bugtrackers[atype]

                if not tracker.installed(db):
                    raise FafError("Bugtracker used in this attachment"
                                   " is not installed")

                bug = tracker.download_bug_to_storage(db, bug_id)

        if bug:
            new = ReportMantis()
            new.report = report
            new.mantisbug = bug
            db.session.add(new)
            db.session.flush()
        else:
            log.error("Failed to fetch bug #{0} from '{1}'".format(
                bug_id, atype))

    elif atype == "comment":
        comment = ReportComment()
        comment.report = report
        comment.text = attachment["data"]
        comment.saved = datetime.datetime.utcnow()
        db.session.add(comment)
        db.session.flush()

    elif atype == "email":
        db_contact_email = get_contact_email(db, attachment["data"])
        if db_contact_email is None:
            db_contact_email = ContactEmail()
            db_contact_email.email_address = attachment["data"]
            db.session.add(db_contact_email)

            db_report_contact_email = ReportContactEmail()
            db_report_contact_email.contact_email = db_contact_email
            db_report_contact_email.report = report
            db.session.add(db_report_contact_email)
        else:
            db_report_contact_email = \
                get_report_contact_email(db, db_contact_email.id, report.id)
            if db_report_contact_email is None:
                db_report_contact_email = ReportContactEmail()
                db_report_contact_email.contact_email = db_contact_email
                db_report_contact_email.report = report
                db.session.add(db_report_contact_email)

        try:
            db.session.flush()
        except IntegrityError:
            raise FafError("Email address already assigned to the report")

    elif atype == "url":
        url = attachment["data"]

        # 0ne URL can be attached to many Reports, but every reports must
        # have unique url's
        db_url = (db.session.query(ReportURL).filter(
            ReportURL.url == url).filter(
                ReportURL.report_id == report.id).first())

        if db_url:
            log.debug("Skipping existing URL")
            return

        db_url = ReportURL()
        db_url.report = report
        db_url.url = url
        db_url.saved = datetime.datetime.utcnow()

        try:
            db.session.flush()
        except IntegrityError:
            raise FafError("Unable to save URL")

    else:
        log.warning("Unknown attachment type")
Пример #2
0
    def _save_bug(self, db, bug):
        """
        Save bug represented by `bug_dict` to the database.

        If bug is marked as duplicate, the duplicate bug is downloaded
        as well.
        """

        bug_dict = self._preprocess_bug(bug)
        if not bug_dict:
            self.log_error("Bug pre-processing failed")
            raise FafError("Bug pre-processing failed")

        self.log_debug("Saving bug #{0}: {1}".format(bug_dict["bug_id"],
                                                     bug_dict["summary"]))

        bug_id = bug_dict["bug_id"]

        # check if we already have this bug up-to-date
        old_bug = (
            db.session.query(BzBug)
            .filter(BzBug.id == bug_id)
            .filter(BzBug.last_change_time == bug_dict["last_change_time"])
            .first())

        if old_bug:
            self.log_info("Bug already up-to-date")
            return old_bug

        tracker = queries.get_bugtracker_by_name(db, self.name)
        if not tracker:
            self.log_error("Tracker with name '{0}' is not installed"
                           .format(self.name))
            raise FafError("Tracker with name '{0}' is not installed"
                           .format(self.name))

        opsysrelease = queries.get_osrelease(db, bug_dict["product"],
                                             bug_dict["version"])

        if not opsysrelease:
            self.log_error("Unable to save this bug due to unknown "
                           "release '{0} {1}'".format(bug_dict["product"],
                                                      bug_dict["version"]))
            raise FafError("Unable to save this bug due to unknown "
                           "release '{0} {1}'".format(bug_dict["product"],
                                                      bug_dict["version"]))

        relcomponent = queries.get_component_by_name_release(
            db, opsysrelease, bug_dict["component"])

        if not relcomponent:
            self.log_error("Unable to save this bug due to unknown "
                           "component '{0}'".format(bug_dict["component"]))
            raise FafError("Unable to save this bug due to unknown "
                           "component '{0}'".format(bug_dict["component"]))

        component = relcomponent.component

        reporter = queries.get_bz_user(db, bug_dict["reporter"])
        if not reporter:
            self.log_debug("Creator {0} not found".format(
                bug_dict["reporter"]))

            downloaded = self._download_user(bug_dict["reporter"])
            if not downloaded:
                self.log_error("Unable to download user, skipping.")
                raise FafError("Unable to download user, skipping.")

            reporter = self._save_user(db, downloaded)

        new_bug = BzBug()
        new_bug.id = bug_dict["bug_id"]
        new_bug.summary = bug_dict["summary"]
        new_bug.status = bug_dict["status"]
        new_bug.creation_time = bug_dict["creation_time"]
        new_bug.last_change_time = bug_dict["last_change_time"]
        new_bug.private = True if bug_dict["groups"] else False

        if bug_dict["status"] == "CLOSED":
            new_bug.resolution = bug_dict["resolution"]
            if bug_dict["resolution"] == "DUPLICATE":
                if not queries.get_bz_bug(db, bug_dict["dupe_id"]):
                    self.log_debug("Duplicate #{0} not found".format(
                        bug_dict["dupe_id"]))

                    dup = self.download_bug_to_storage(db, bug_dict["dupe_id"])
                    if dup:
                        new_bug.duplicate = dup.id

        new_bug.tracker_id = tracker.id
        new_bug.component_id = component.id
        new_bug.opsysrelease_id = opsysrelease.id
        new_bug.creator_id = reporter.id
        new_bug.whiteboard = bug_dict["status_whiteboard"]

        # the bug itself might be downloaded during duplicate processing
        # exit in this case - it would cause duplicate database entry
        if queries.get_bz_bug(db, bug_dict["bug_id"]):
            self.log_debug("Bug #{0} already exists in storage,"
                           " updating".format(bug_dict["bug_id"]))

            bugdict = {}
            for col in new_bug.__table__._columns:
                bugdict[col.name] = getattr(new_bug, col.name)

            (db.session.query(BzBug)
             .filter(BzBug.id == bug_id).update(bugdict))

            new_bug = queries.get_bz_bug(db, bug_dict["bug_id"])
        else:
            db.session.add(new_bug)

        db.session.flush()

        self._save_ccs(db, bug_dict["cc"], new_bug.id)
        self._save_history(db, bug_dict["history"], new_bug.id)
        if self.save_attachments:
            self._save_attachments(db, bug_dict["attachments"], new_bug.id)
        if self.save_comments:
            self._save_comments(db, bug_dict["comments"], new_bug.id)

        return new_bug
Пример #3
0
def associate_bug(report_id):
    result = (db.session.query(Report,
                               OpSysComponent).join(OpSysComponent).filter(
                                   Report.id == report_id).first())

    if result is None:
        abort(404)

    report, component = result

    is_maintainer = app.config["EVERYONE_IS_MAINTAINER"]
    if not is_maintainer and g.user is not None:
        if user_is_maintainer(db, g.user.username, component.id):
            is_maintainer = True

    if not is_maintainer:
        flash("You are not the maintainer of this component.", "danger")
        return redirect(url_for("reports.item", report_id=report_id))

    form = AssociateBzForm(request.form)
    if request.method == "POST" and form.validate():
        bug_id = form.bug_id.data

        reportbug = (db.session.query(
            ReportBz).filter((ReportBz.report_id == report.id)
                             & (ReportBz.bzbug_id == bug_id)).first())

        if reportbug:
            flash("Bug already associated.", "danger")
        else:
            bug = get_bz_bug(db, bug_id)
            if not bug:
                tracker = bugtrackers[form.bugtracker.data]

                try:
                    bug = tracker.download_bug_to_storage_no_retry(db, bug_id)
                except Exception as e:
                    flash("Failed to fetch bug. {0}".format(str(e)), "danger")
                    raise

            if bug:
                new = ReportBz()
                new.report = report
                new.bzbug = bug
                db.session.add(new)
                db.session.flush()
                db.session.commit()

                flash("Bug successfully associated.", "success")
                return redirect(url_for("reports.item", report_id=report_id))
            else:
                flash("Failed to fetch bug.", "danger")

    bthash_url = url_for("reports.bthash_forward",
                         bthash=report.hashes[0].hash,
                         _external=True)
    new_bug_params = {
        "component":
        component.name,
        "short_desc":
        "[abrt] [faf] {0}: {1}(): {2} killed by {3}".format(
            component.name, report.crash_function,
            ",".join(exe.path for exe in report.executables), report.errname),
        "comment":
        "This bug has been created based on an anonymous crash "
        "report requested by the package maintainer.\n\n"
        "Report URL: {0}".format(bthash_url),
        "bug_file_loc":
        bthash_url
    }

    new_bug_urls = []
    for rosr in report.opsysreleases:
        osr = rosr.opsysrelease
        for bugtracker in bugtrackers.keys():
            try:
                params = new_bug_params.copy()
                if osr.opsys.name.startswith("Red Hat"):
                    params.update(product="{0} {1}".format(
                        osr.opsys.name, osr.version[0]),
                                  version=osr.version)
                else:
                    params.update(product=osr.opsys.name, version=osr.version)
                print(params)
                new_bug_urls.append(
                    ("{0} {1} in {2}".format(osr.opsys.name, osr.version,
                                             bugtracker),
                     "{0}?{1}".format(bugtrackers[bugtracker].new_bug_url,
                                      urllib.urlencode(params))))
            except:
                pass

    return render_template("reports/associate_bug.html",
                           form=form,
                           report=report,
                           new_bug_urls=new_bug_urls)
Пример #4
0
def save_attachment(db, attachment):
    atype = attachment["type"].lower()

    if not attachment_type_allowed(atype):
        raise FafError("Attachment type '{}' not allowed on this server"
                       .format(atype))

    report = get_report(db, attachment["bthash"])
    if not report:
        raise FafError("Report for given bthash not found")

    if atype in ["rhbz", "fedora-bugzilla", "rhel-bugzilla"]:
        bug_id = int(attachment["data"])

        reportbug = (db.session.query(ReportBz)
                     .filter(
                         (ReportBz.report_id == report.id) &
                         (ReportBz.bzbug_id == bug_id)
                     )
                     .first())

        if reportbug:
            log.debug("Skipping existing attachment")
            return

        bug = get_bz_bug(db, bug_id)
        if not bug:
            if atype in bugtrackers:
                # download from bugtracker identified by atype
                tracker = bugtrackers[atype]

                if not tracker.installed(db):
                    raise FafError("Bugtracker used in this attachment"
                                   " is not installed")

                bug = tracker.download_bug_to_storage(db, bug_id)
            elif atype == "rhbz":
                # legacy value
                # - we need to guess the bugtracker:
                # either fedora-bugzilla or rhel-bugzilla,
                # former is more probable
                for possible_tracker in ["fedora-bugzilla", "rhel-bugzilla"]:
                    if possible_tracker not in bugtrackers:
                        continue

                    tracker = bugtrackers[possible_tracker]
                    if not tracker.installed(db):
                        continue

                    bug = tracker.download_bug_to_storage(db, bug_id)
                    if bug:
                        break

        if bug:
            new = ReportBz()
            new.report = report
            new.bzbug = bug
            db.session.add(new)
            db.session.flush()
        else:
            log.error("Failed to fetch bug #{0} from '{1}'"
                      .format(bug_id, atype))

    elif atype == "centos-mantisbt":
        bug_id = int(attachment["data"])

        reportbug = (db.session.query(ReportMantis)
                     .filter(
                         (ReportMantis.report_id == report.id) &
                         (ReportMantis.mantisbug_id == bug_id))
                     .first())

        if reportbug:
            log.debug("Skipping existing attachment")
            return

        bug = get_mantis_bug(db, bug_id)
        if not bug:
            if atype in bugtrackers:
                # download from bugtracker identified by atype
                tracker = bugtrackers[atype]

                if not tracker.installed(db):
                    raise FafError("Bugtracker used in this attachment"
                                   " is not installed")

                bug = tracker.download_bug_to_storage(db, bug_id)

        if bug:
            new = ReportMantis()
            new.report = report
            new.mantisbug = bug
            db.session.add(new)
            db.session.flush()
        else:
            log.error("Failed to fetch bug #{0} from '{1}'"
                      .format(bug_id, atype))

    elif atype == "comment":
        comment = ReportComment()
        comment.report = report
        comment.text = attachment["data"]
        comment.saved = datetime.datetime.utcnow()
        db.session.add(comment)
        db.session.flush()

    elif atype == "email":
        db_contact_email = get_contact_email(db, attachment["data"])
        if db_contact_email is None:
            db_contact_email = ContactEmail()
            db_contact_email.email_address = attachment["data"]
            db.session.add(db_contact_email)

            db_report_contact_email = ReportContactEmail()
            db_report_contact_email.contact_email = db_contact_email
            db_report_contact_email.report = report
            db.session.add(db_report_contact_email)
        else:
            db_report_contact_email = \
                get_report_contact_email(db, db_contact_email.id, report.id)
            if db_report_contact_email is None:
                db_report_contact_email = ReportContactEmail()
                db_report_contact_email.contact_email = db_contact_email
                db_report_contact_email.report = report
                db.session.add(db_report_contact_email)

        try:
            db.session.flush()
        except IntegrityError:
            raise FafError("Email address already assigned to the report")

    elif atype == "url":
        url = attachment["data"]

        # 0ne URL can be attached to many Reports, but every reports must
        # have unique url's
        db_url = (db.session.query(ReportURL)
                  .filter(ReportURL.url == url)
                  .filter(ReportURL.report_id == report.id)
                  .first())

        if db_url:
            log.debug("Skipping existing URL")
            return

        db_url = ReportURL()
        db_url.report = report
        db_url.url = url
        db_url.saved = datetime.datetime.utcnow()

        try:
            db.session.flush()
        except IntegrityError:
            raise FafError("Unable to save URL")

    else:
        log.warning("Unknown attachment type")
Пример #5
0
    def _save_bug(self, db, bug):
        """
        Save bug represented by `bug_dict` to the database.

        If bug is marked as duplicate, the duplicate bug is downloaded
        as well.
        """

        bug_dict = self.preprocess_bug(bug)
        if not bug_dict:
            self.log_error("Bug pre-processing failed")
            raise FafError("Bug pre-processing failed")

        self.log_debug("Saving bug #{0}: {1}".format(bug_dict["bug_id"],
                                                     bug_dict["summary"]))

        bug_id = bug_dict["bug_id"]

        # check if we already have this bug up-to-date
        old_bug = (
            db.session.query(BzBug)
            .filter(BzBug.id == bug_id)
            .filter(BzBug.last_change_time == bug_dict["last_change_time"])
            .first())

        if old_bug:
            self.log_info("Bug already up-to-date")
            return old_bug

        tracker = queries.get_bugtracker_by_name(db, self.name)
        if not tracker:
            self.log_error("Tracker with name '{0}' is not installed"
                           .format(self.name))
            raise FafError("Tracker with name '{0}' is not installed"
                           .format(self.name))

        opsysrelease = queries.get_osrelease(db, bug_dict["product"],
                                             bug_dict["version"])

        if not opsysrelease:
            self.log_error("Unable to save this bug due to unknown "
                           "release '{0} {1}'".format(bug_dict["product"],
                                                      bug_dict["version"]))
            raise FafError("Unable to save this bug due to unknown "
                           "release '{0} {1}'".format(bug_dict["product"],
                                                      bug_dict["version"]))

        relcomponent = queries.get_component_by_name_release(
            db, opsysrelease, bug_dict["component"])

        if not relcomponent:
            self.log_error("Unable to save this bug due to unknown "
                           "component '{0}'".format(bug_dict["component"]))
            raise FafError("Unable to save this bug due to unknown "
                           "component '{0}'".format(bug_dict["component"]))

        component = relcomponent.component

        reporter = queries.get_bz_user(db, bug_dict["reporter"])
        if not reporter:
            self.log_debug("Creator {0} not found".format(
                bug_dict["reporter"]))

            downloaded = self._download_user(bug_dict["reporter"])
            if not downloaded:
                self.log_error("Unable to download user, skipping.")
                raise FafError("Unable to download user, skipping.")

            reporter = self._save_user(db, downloaded)

        new_bug = BzBug()
        new_bug.id = bug_dict["bug_id"]
        new_bug.summary = bug_dict["summary"]
        new_bug.status = bug_dict["status"]
        new_bug.creation_time = bug_dict["creation_time"]
        new_bug.last_change_time = bug_dict["last_change_time"]
        new_bug.private = bool(bug_dict["groups"])

        if bug_dict["status"] == "CLOSED":
            new_bug.resolution = bug_dict["resolution"]
            if bug_dict["resolution"] == "DUPLICATE":
                if not queries.get_bz_bug(db, bug_dict["dupe_id"]):
                    self.log_debug("Duplicate #{0} not found".format(
                        bug_dict["dupe_id"]))

                    dup = self.download_bug_to_storage(db, bug_dict["dupe_id"])
                    if dup:
                        new_bug.duplicate = dup.id

        new_bug.tracker_id = tracker.id
        new_bug.component_id = component.id
        new_bug.opsysrelease_id = opsysrelease.id
        new_bug.creator_id = reporter.id
        new_bug.whiteboard = bug_dict["status_whiteboard"]

        # the bug itself might be downloaded during duplicate processing
        # exit in this case - it would cause duplicate database entry
        if queries.get_bz_bug(db, bug_dict["bug_id"]):
            self.log_debug("Bug #{0} already exists in storage,"
                           " updating".format(bug_dict["bug_id"]))

            bugdict = {}
            for col in new_bug.__table__._columns: #pylint: disable=protected-access
                bugdict[col.name] = getattr(new_bug, col.name)

            (db.session.query(BzBug)
             .filter(BzBug.id == bug_id).update(bugdict))

            new_bug = queries.get_bz_bug(db, bug_dict["bug_id"])
        else:
            db.session.add(new_bug)

        db.session.flush()

        self._save_ccs(db, bug_dict["cc"], new_bug.id)
        self._save_history(db, bug_dict["history"], new_bug.id)
        if self.save_attachments:
            self._save_attachments(db, bug_dict["attachments"], new_bug.id)
        if self.save_comments:
            self._save_comments(db, bug_dict["comments"], new_bug.id)

        return new_bug
Пример #6
0
def associate_bug(report_id) -> Union[WzResponse, str]:
    result = (db.session.query(Report,
                               OpSysComponent).join(OpSysComponent).filter(
                                   Report.id == report_id).first())

    if result is None:
        abort(404)

    report, component = result

    is_maintainer = is_component_maintainer(db, g.user, component)

    if not is_maintainer:
        flash("You are not the maintainer of this component.", "danger")
        return redirect(url_for("reports.item", report_id=report_id))

    form = AssociateBzForm(request.form)
    if request.method == "POST" and form.validate():
        bug_id = form.bug_id.data

        tracker = bugtrackers[form.bugtracker.data]

        db_report = inspect(Report).relationships[tracker.report_backref_name]
        db_report_class = inspect(db_report.entity).class_

        reportbug = get_bugtracker_report(db, bug_id, report.id,
                                          db_report_class)
        if reportbug:
            flash("Bug already associated.", "danger")
        else:
            bug = get_bz_bug(db, bug_id)
            if not bug:
                tracker = bugtrackers[form.bugtracker.data]

                try:
                    bug = tracker.download_bug_to_storage(db, bug_id)
                except Exception as e:  #pylint: disable=broad-except
                    flash("Failed to fetch bug. {0}".format(str(e)), "danger")
                    return redirect(
                        url_for("reports.associate_bug", report_id=report_id))

            if bug:
                new_report = db_report_class()
                new_report.report = report
                new_report.bug = bug
                db.session.add(new_report)
                db.session.flush()
                db.session.commit()

                flash("Bug successfully associated.", "success")
                return redirect(url_for("reports.item", report_id=report_id))

    bthash_url = url_for("reports.bthash_forward",
                         bthash=report.hashes[0].hash,
                         _external=True)
    new_bug_params = {
        "component":
        component.name,
        "short_desc":
        "[abrt] [faf] {0}: {1}(): {2} killed by {3}".format(
            component.name, report.crash_function,
            ",".join(exe.path for exe in report.executables), report.errname),
        "comment":
        "This bug has been created based on an anonymous crash "
        "report requested by the package maintainer.\n\n"
        "Report URL: {0}".format(bthash_url),
        "bug_file_loc":
        bthash_url
    }

    new_bug_urls = []
    for rosr in report.opsysreleases:
        osr = rosr.opsysrelease
        for bugtracker in bugtrackers:
            try:
                params = new_bug_params.copy()
                if osr.opsys.name.startswith("Red Hat"):
                    params.update(product="{0} {1}".format(
                        osr.opsys.name, osr.version[0]),
                                  version=osr.version)
                else:
                    params.update(product=osr.opsys.name, version=osr.version)
                new_bug_urls.append(
                    ("{0} in {1}".format(str(osr), bugtracker),
                     "{0}?{1}".format(bugtrackers[bugtracker].new_bug_url,
                                      urllib.parse.urlencode(params))))
            except:  # pylint: disable=bare-except
                pass

    return render_template("reports/associate_bug.html",
                           form=form,
                           report=report,
                           new_bug_urls=new_bug_urls)
Пример #7
0
def associate_bug(report_id):
    result = (db.session.query(Report, OpSysComponent)
              .join(OpSysComponent)
              .filter(Report.id == report_id)
              .first())

    if result is None:
        abort(404)

    report, component = result

    is_maintainer = is_component_maintainer(db, g.user, component)

    if not is_maintainer:
        flash("You are not the maintainer of this component.", "danger")
        return redirect(url_for("reports.item", report_id=report_id))

    form = AssociateBzForm(request.form)
    if request.method == "POST" and form.validate():
        bug_id = form.bug_id.data

        reportbug = (db.session.query(ReportBz)
                     .filter(
                         (ReportBz.report_id == report.id) &
                         (ReportBz.bzbug_id == bug_id))
                     .first())

        if reportbug:
            flash("Bug already associated.", "danger")
        else:
            bug = get_bz_bug(db, bug_id)
            if not bug:
                tracker = bugtrackers[form.bugtracker.data]

                try:
                    bug = tracker.download_bug_to_storage_no_retry(db, bug_id)
                except Exception as e: #pylint: disable=broad-except
                    flash("Failed to fetch bug. {0}".format(str(e)), "danger")
                    return redirect(url_for("reports.associate_bug",
                                            report_id=report_id))

            if bug:
                newReportBz = ReportBz()
                newReportBz.report = report
                newReportBz.bzbug = bug
                db.session.add(newReportBz)
                db.session.flush()
                db.session.commit()

                flash("Bug successfully associated.", "success")
                return redirect(url_for("reports.item", report_id=report_id))

    bthash_url = url_for("reports.bthash_forward",
                         bthash=report.hashes[0].hash,
                         _external=True)
    new_bug_params = {
        "component": component.name,
        "short_desc": "[abrt] [faf] {0}: {1}(): {2} killed by {3}"
                      .format(component.name,
                              report.crash_function,
                              ",".join(exe.path for exe in report.executables),
                              report.errname
                             ),
        "comment": "This bug has been created based on an anonymous crash "
                   "report requested by the package maintainer.\n\n"
                   "Report URL: {0}"
                   .format(bthash_url),
        "bug_file_loc": bthash_url
    }

    new_bug_urls = []
    for rosr in report.opsysreleases:
        osr = rosr.opsysrelease
        for bugtracker in bugtrackers:
            try:
                params = new_bug_params.copy()
                if osr.opsys.name.startswith("Red Hat"):
                    params.update(product="{0} {1}".format(osr.opsys.name,
                                                           osr.version[0]),
                                  version=osr.version)
                else:
                    params.update(product=osr.opsys.name, version=osr.version)
                new_bug_urls.append(
                    ("{0} {1} in {2}".format(osr.opsys.name, osr.version,
                                             bugtracker),
                     "{0}?{1}".format(
                         bugtrackers[bugtracker].new_bug_url,
                         urllib.parse.urlencode(params))
                    )
                )
            except: # pylint: disable=bare-except
                pass

    return render_template("reports/associate_bug.html",
                           form=form,
                           report=report,
                           new_bug_urls=new_bug_urls)