def create_bugzilla_bug(self, privacy=False): #get last report id bztracker = Bugtracker() bztracker.name = "centos-bugzilla" bzuser = BzUser() bzuser.email = "*****@*****.**" bzuser.name = "*****@*****.**" bzuser.real_name = "Test User" bzuser.can_login = True bzbug = BzBug() bzbug.opsysrelease_id = 1 bzbug.summary = "summary" bzbug.status = "NEW" bzbug.creation_time = "2016-02-12 11:44:10" bzbug.last_change_time = "2016-02-12 11:44:10" bzbug.tracker_id = 1 bzbug.component_id = 1 bzbug.whiteboard = 1 bzbug.creator_id = 1 bzbug.private = privacy self.db.session.add(bztracker) self.db.session.add(bzuser) self.db.session.add(bzbug) self.db.session.flush() reports = self.db.session.query(Report).all() for rep in reports: reportbz = ReportBz() reportbz.report_id = str(rep.id) reportbz.bzbug_id = 1 self.db.session.add(reportbz) self.db.session.flush()
def run(self, cmdline, db) -> int: self.log_warn("This is an experimental script and is not guaranteed " "to give any meaningful results. As a side-effect it may " "create a large number of bugs in the selected Bugzilla " "instance so be sure you really know what you are doing.") # in case we're using the web UI: if not hasattr(cmdline, "dry_run"): cmdline.dry_run = False if cmdline.baseurl is not None: self.baseurl = cmdline.baseurl bz = bugtrackers[cmdline.bugtracker] if not isinstance(bz, Bugzilla): self.log_error("The selected bug tracker must be Bugzilla instance") return 1 bz.connect() db_comps = db.session.query(OpSysComponent) skip_components = [c.name for c in db_comps if not c.releases] db_external_reports = db.session.query(ReportExternalFaf).all() for i, db_external_report in enumerate(db_external_reports, start=1): db_instance = db_external_report.faf_instance self.log_info("[{0} / {1}] Processing {2} report #{3}" .format(i, len(db_external_reports), db_instance.name, db_external_report.external_id)) if db_external_report.report.bz_bugs: self.log_debug("Report #%d has already a BZ assigned", db_external_report.report_id) continue now = datetime.datetime.utcnow() two_weeks = datetime.timedelta(days=140) if now - db_external_report.report.last_occurrence >= two_weeks: self.log_debug("Report #%d is older than 14 days, skipping", db_external_report.report_id) continue url = "{0}/reports/{1}".format(db_instance.baseurl, db_external_report.external_id) bugs = self._get_bugs(url, bz) if not bugs: self.log_debug("No bugs found") continue for bug in bugs: self.log_debug("Processing bug #%d", bug.id) if bug.component in skip_components: self.log_debug("Bug #%d is reported against an unsupported component %s", bug.id, bug.component) continue if bug.status == "CLOSED": status = "CLOSED %s" % bug.resolution else: status = bug.status if cmdline.dry_run: self.log_warn("Dry-run enabled, not touching BZ") continue self.log_info("Cloning BZ #{0} ({1})".format(bug.id, status)) reporturl = "{0}/{1}".format(self.baseurl.rstrip("/"), db_external_report.report_id) newbug = bz.clone_bug(bug.id, cmdline.NEW_PRODUCT, cmdline.NEW_VERSION, url=reporturl) self.log_info("Created bug #{0}".format(newbug.id)) db_packages = db_external_report.report.unknown_packages package_list = "\n".join(self._nvra(p) for p in db_packages if p.type.lower() == "crashed") comment = ("The same problem has been detected in {0}. " "The following packages are affected:\n\n{1}" .format(cmdline.NEW_PRODUCT, package_list)) newbug.addcomment(comment) db_bzbug = bz.download_bug_to_storage(db, newbug.id) db_reportbz = ReportBz() db_reportbz.report = db_external_report.report db_reportbz.bzbug = db_bzbug db.session.add(db_reportbz) db.session.flush() return 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")
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)
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")
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)