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