#!/usr/bin/python -u # WARNING: python -u means unbuffered I/O. Without it the messages are # passed to the parent asynchronously which looks bad in clients. # # This script wraps reporter-ureport client and keeps number of sent # uReports to a server consistent with number of problem ocurrences. import sys import os import getopt import augeas from report import dd_opendir, DD_FAIL_QUIETLY_ENOENT from reportclient import set_verbosity, error_msg_and_die, error_msg, log1, log GETTEXT_PROGNAME = "abrt" import locale import gettext _ = lambda x: gettext.lgettext(x) def init_gettext(): try: locale.setlocale(locale.LC_ALL, "") except locale.Error: os.environ['LC_ALL'] = 'C' locale.setlocale(locale.LC_ALL, "") # Defeat "AttributeError: 'module' object has no attribute 'nl_langinfo'" try: gettext.bind_textdomain_codeset(GETTEXT_PROGNAME, locale.nl_langinfo(locale.CODESET)) except AttributeError: pass gettext.bindtextdomain(GETTEXT_PROGNAME, '/usr/share/locale') gettext.textdomain(GETTEXT_PROGNAME) def get_augeas(module, file_path): """ A function for efficient configuration of Augeas. Augeas modules are placed in /usr/share/augeas/lenses/dist """ aug_obj = augeas.Augeas(flags=augeas.Augeas.NO_MODL_AUTOLOAD) aug_obj.set("/augeas/load/{0}/lens".format(module), "{0}.lns".format(module)) aug_obj.set("/augeas/load/{0}/incl".format(module), file_path) aug_obj.load() return aug_obj def spawn_and_wait(prog, args=None): if args is None: args = [prog] else: args.insert(0, prog) try: return os.spawnvpe(os.P_WAIT, prog, args, os.environ) except OSError as err: error_msg(_("Unable to start '%s', error message was: '%s'"), " ".join(args), err) return -1 def try_parse_number(dd, filename): try: n = dd.load_text(filename, DD_FAIL_QUIETLY_ENOENT) if n == "": return 0 return int(n) except: error_msg(_("Not a number in file '%s'"), filename) return 0 if __name__ == "__main__": # localization init_gettext() verbose = 0 ABRT_VERBOSE = os.getenv("ABRT_VERBOSE") if ABRT_VERBOSE: try: verbose = int(ABRT_VERBOSE) except: pass progname = os.path.basename(sys.argv[0]) help_text = _("Usage: %s [-v]") % progname try: opts, args = getopt.getopt(sys.argv[1:], "vh", ["help"]) except getopt.GetoptError, err: error_msg(err) # prints something like "option -a not recognized" error_msg_and_die(help_text) for opt, arg in opts: if opt in ("-h", "--help"): print help_text sys.exit(0) if opt == "-v": verbose += 1 set_verbosity(verbose) os.environ["ABRT_VERBOSE"] = str(verbose) # getcwd might fail if cwd was deleted try: dirname = os.getcwd() except OSError as err: error_msg_and_die(_("Unable to get current working directory as" " it was probably deleted")) dd = dd_opendir(dirname, 0) if not dd: sys.exit(1) report_type = dd.load_text("type", DD_FAIL_QUIETLY_ENOENT) # because of backward compatibility if not report_type: report_type = dd.load_text("analyzer", 0) core_backtrace_exists = dd.exist("core_backtrace") packaged = dd.exist("package") reported_to = dd.load_text("reported_to", DD_FAIL_QUIETLY_ENOENT) ureports_counter = try_parse_number(dd, "ureports_counter") count = try_parse_number(dd, "count") dd.close() # Send only if the problem is not yet reported # if the count file is corrupted or # if the number of ureports is lower then the number of occurrences if ureports_counter != 0 and count != 0 and ureports_counter >= count: log1("uReport has been already sent: '%s'", dirname) if reported_to and reported_to != "": bugs = set() for line in reported_to.split("\n"): if line.startswith("Bugzilla:"): bugs.add(line) if bugs: log(_("A bug was already filed about this problem:")) bugs = sorted(bugs) for bug in bugs: print bug sys.exit(70) # EXIT_STOP_EVENT_RUN log1("Bug for '%s' not yet filed. Continuing.", dirname) sys.exit(0) else: log1("'%s/reported_to' doesn't exist", dirname) log(_("uReport was already sent, not sending it again")) sys.exit(0) if report_type == "CCpp" and not core_backtrace_exists: exitcode = spawn_and_wait("abrt-action-generate-core-backtrace") if exitcode != 0: log1("uReport can't be sent without core_backtrace. Exiting.") sys.exit(1) if not packaged: log(_("Problem comes from unpackaged executable. Unable to create uReport.")) sys.exit(1) exitcode = spawn_and_wait("reporter-ureport") if exitcode == 0 or exitcode == 70: dd = dd_opendir(dirname, 0) if not dd: sys.exit(1) dd.save_text("ureports_counter", str(ureports_counter + 1)) dd.close() email = os.getenv("uReport_ContactEmail") if not email: augeas = get_augeas("libreport", "/etc/libreport/plugins/ureport.conf") email = augeas.get("/files/etc/libreport/plugins/ureport.conf/ContactEmail") if email: log1("Attaching ContactEmail: " + email) spawn_and_wait("reporter-ureport", ["-A", "-E"]) sys.exit(exitcode) else: error_msg_and_die(_("reporter-ureport failed with exit code %d" % exitcode))