def match_get_problem(problem_match, allow_multiple=False, auth=False): ''' Return problem matching `problem_match` pattern or exit if there are no such problems or pattern results in multiple problems (unless `allow_multiple` is set to True). ''' prob = None if problem_match == 'last': probs = sort_problems(problem.list(auth=auth)) if not probs: print(_('No problems')) sys.exit(0) prob = probs[0] else: probs = match_lookup(problem_match, auth=auth) if not probs: print(_('No problem(s) matched')) sys.exit(1) elif len(probs) > 1: if allow_multiple: return probs match_collision(probs) sys.exit(1) else: prob = probs[0] return prob
def backtrace(args): prob = match_get_problem(args.MATCH, auth=args.auth) if hasattr(prob, 'backtrace'): print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) else: print(_('Problem has no backtrace')) if isinstance(prob, problem.Ccpp): ret = ask_yes_no(_('Start retracing process?')) if ret: retrace(args) print(fmt_problems(prob, fmt=config.BACKTRACE_FMT))
def remove(args): prob = match_get_problem(args.MATCH, auth=args.auth) print(fmt_problems(prob, fmt=config.FULL_FMT)) ret = True if not args.f and (args.i or args.MATCH == 'last'): # force prompt for last problem to avoid accidents ret = ask_yes_no(_('Are you sure you want to delete this problem?')) if ret: prob.delete() print(_('Removed'))
def main(): l18n.init() parser = ArghParser() parser.add_argument('-a', '--auth', action='store_true', help=_('Authenticate and show all problems' ' on this machine')) parser.add_argument('-v', '--version', action='version', version=config.VERSION) parser.add_commands([ backtrace, di_install, gdb, info, list_problems, remove, report, retrace, status, ]) argcomplete.autocomplete(parser) try: parser.dispatch() except KeyboardInterrupt: sys.exit(1) sys.exit(0)
def gdb(args): prob = match_get_problem(args.MATCH, auth=args.auth) if not isinstance(prob, problem.Ccpp): which = 'This' if args.MATCH == 'last': which = 'Last' print('{} problem is not of a C/C++ type. Can\'t run gdb' .format(which)) sys.exit(1) prob.chown() if args.debuginfo_install: di_install(args) cmd = config.GDB_CMD.format(di_path=config.DEBUGINFO_PATH) with remember_cwd(): try: os.chdir(prob.path) except OSError: print(_('Permission denied: \'{}\'\n' 'If this is a system problem' ' try running this command as root') .format(prob.path)) sys.exit(1) subprocess.call(cmd, shell=True)
def list_problems(args): probs = sort_problems(problem.list(auth=args.auth)) if args.since: probs = filter_since_timestamp(probs, args.since) if args.until: probs = filter_until_timestamp(probs, args.until) if args.not_reported: probs = filter_not_reported(probs) if not args.fmt: fmt = config.MEDIUM_FMT else: fmt = args.fmt if args.pretty != 'medium': fmt = getattr(config, '{}_FMT'.format(args.pretty.upper())) out = fmt_problems(probs, fmt=fmt) if out: print(out) else: print(_('No problems'))
def match_collision(probs): ''' Handle matches that result in multiple problems by telling user to be more specific ''' print(_('Ambiguous match specified resulting in multiple problems:')) for prob in probs: field, val = get_human_identifier(prob) print('- {}@{} ({})'.format(val, prob.short_id, prob.time))
def di_install(args): prob = match_get_problem(args.MATCH, auth=args.auth) if not isinstance(prob, problem.Ccpp): which = _("This") if args.MATCH == "last": which = _("Last") print(_("{} problem is not of a C/C++ type. Can't install debuginfo").format(which)) sys.exit(1) prob.chown() with remember_cwd(): try: os.chdir(prob.path) except OSError: print( _("Permission denied: '{}'\n" "If this is a system problem" " try running this command as root").format( prob.path ) ) sys.exit(1) subprocess.call(config.DEBUGINFO_INSTALL_CMD, shell=True)
def status(args): probs = problem.list(auth=args.auth) since_append = "" if args.since: probs = filter_since_timestamp(probs, args.since) since_append = " --since {}".format(args.since) if args.not_reported: probs = filter_not_reported(probs) if args.bare: print(len(probs)) return print(_("ABRT has detected {} problem(s). For more info run: abrt list{}").format(len(probs), since_append))
def status(args): probs = problem.list(auth=args.auth) since_append = '' if args.since: probs = filter_since_timestamp(probs, args.since) since_append = ' --since {}'.format(args.since) if args.not_reported: probs = filter_not_reported(probs) if args.bare: print(len(probs)) return print(_('ABRT has detected {} problem(s). For more info run: abrt list{}') .format(len(probs), since_append))
def report(args): prob = match_get_problem(args.MATCH, auth=args.auth) if prob.not_reportable and not args.unsafe: if reportclient.verbose > 0: print(prob.not_reportable_reason) print(_('Problem \'{0}\' cannot be reported').format(prob.short_id)) sys.exit(1) flags = libreport.LIBREPORT_WAIT | libreport.LIBREPORT_RUN_CLI if args.unsafe: flags |= libreport.LIBREPORT_IGNORE_NOT_REPORTABLE prob.chown() libreport.report_problem_in_dir(prob.path, flags)
def retrace(args): # we might not get these var if called from backtrace local, remote, auth = False, False, False if hasattr(args, "local"): local = args.local if hasattr(args, "remote"): remote = args.remote if hasattr(args, "force"): force = args.force prob = match_get_problem(args.MATCH, auth=args.auth) if hasattr(prob, "backtrace") and not force: print(_("Problem already has a backtrace")) print(_("Run abrt retrace with -f/--force to retrace again")) ret = ask_yes_no(_("Show backtrace?")) if ret: print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) elif not isinstance(prob, problem.Ccpp): print(_("No retracing possible for this problem type")) else: if not (local or remote): # ask.. ret = ask_yes_no( _( "Upload core dump and perform remote" " retracing? (It may contain sensitive data)." " If your answer is 'No', a stack trace will" " be generated locally. Local retracing" " requires downloading potentially large amount" " of debuginfo data" ) ) if ret: remote = True else: local = True prob.chown() if remote: print(_("Remote retracing")) run_event("analyze_RetraceServer", prob) else: print(_("Local retracing")) run_event("analyze_LocalGDB", prob)
def arg_verbose(func): """ This is a decorator that adds --verbose command line argument to a command. If the command supports the argument, the command must correctly initialize reportclient, because we want to propagate the verbosity to called functions. """ @functools.wraps(func) def abrt_wrapper(args): if 'verbose' in args: reportclient.verbose += args.verbose set_verbosity(reportclient.verbose) return func(args) argh_wrapper = arg('-v', '--verbose', action='count', default=0, help=_('Print verbose information')) return argh_wrapper(abrt_wrapper)
def main(): l18n.init() parser = ArghParser() parser.add_argument( "-a", "--auth", action="store_true", help=_("Authenticate and show all problems" " on this machine") ) parser.add_argument("-v", "--version", action="version", version=config.VERSION) parser.add_commands([backtrace, di_install, gdb, info, list_problems, remove, report, retrace, status]) argcomplete.autocomplete(parser) try: parser.dispatch() except KeyboardInterrupt: sys.exit(1) sys.exit(0)
def retrace(args): # we might not get these var if called from backtrace local, remote, auth = False, False, False if hasattr(args, 'local'): local = args.local if hasattr(args, 'remote'): remote = args.remote if hasattr(args, 'force'): force = args.force prob = match_get_problem(args.MATCH, auth=args.auth) if hasattr(prob, 'backtrace') and not force: print(_('Problem already has a backtrace')) print(_('Run abrt retrace with -f/--force to retrace again')) ret = ask_yes_no(_('Show backtrace?')) if ret: print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) elif not isinstance(prob, problem.Ccpp): print(_('No retracing possible for this problem type')) else: if not (local or remote): # ask.. ret = ask_yes_no( _('Upload core dump and perform remote' ' retracing? (It may contain sensitive data).' ' If your answer is \'No\', a stack trace will' ' be generated locally. Local retracing' ' requires downloading potentially large amount' ' of debuginfo data')) if ret: remote = True else: local = True prob.chown() if remote: print(_('Remote retracing')) run_event('analyze_RetraceServer', prob) else: print(_('Local retracing')) run_event('analyze_LocalGDB', prob)
def fmt_problems(probs, fmt=MEDIUM_FMT): ''' Return preformatted problem data of `prob` according to `fmt` ''' if probs is None: return '' if not isinstance(probs, list): probs = [probs] fmt = fmt.replace('|', '\n') tabular = '#table' in fmt oneline = '\n' not in fmt out = '' for prob in probs: what_field, what = get_human_identifier(prob) context_vars = { 'what': what, 'what_field': what_field, } uid = get_problem_field(prob, 'uid') if uid: username = get_problem_field(prob, 'username') if username: uid_username = ('{0} ({1})' .format(uid, username)) else: uid_username = str(uid) context_vars['uid_username'] = uid_username if prob.not_reportable: context_vars['not_reportable'] = _('Not reportable') reason = prob.not_reportable_reason.rstrip() if tabular: reason = reason.replace('\n', '\n,') context_vars['not_reportable_reason'] = reason if hasattr(prob, 'reported_to'): r_out = '' rtl = prob.reported_to.splitlines() # each reported to line item as separate row # except for BTHASH for rline in rtl: if 'BTHASH' in rline: continue if 'URL=' in rline: rep_to, url = rline.split('URL=', 1) if ': ' in rep_to: rep_to, rest = rep_to.split(': ') if tabular: r_out += '\n{},{}'.format(rep_to, url) if r_out: context_vars['reported_to'] = r_out if hasattr(prob, 'backtrace'): if not oneline: context_vars['backtrace'] = '\n' + prob.backtrace if not hasattr(prob, 'count'): context_vars['count'] = 1 sfmt = fmt.splitlines() for line in sfmt: if not line.rstrip(): if tabular: out += ',\n' elif not oneline: out += '\n' continue if line[0] == '#': # output mode selector or comment continue template_vars = braces_re.findall(line) missing_var = False for var in template_vars: # try looking up missing context var in problem items if var not in context_vars: val = get_problem_field(prob, var) if val: context_vars[var] = val else: missing_var = True context_vars[var] = '' if not missing_var or oneline: fmtline = line.format(**context_vars) if not oneline: fmtline = upcase_first_letter(fmtline) out += fmtline + '\n' # separator if tabular: out += ',\n' elif not oneline: out += '\n' if tabular: rows = out.splitlines() rows = map(lambda x: x.split(',', 1), rows) out = as_table(list(rows)[:-1]) else: out = out.replace('\n\n', '\n') return out.rstrip()
@expects_obj @arg("MATCH", nargs="?", default="last", completer=match_completer) def backtrace(args): prob = match_get_problem(args.MATCH, auth=args.auth) if hasattr(prob, "backtrace"): print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) else: print(_("Problem has no backtrace")) if isinstance(prob, problem.Ccpp): ret = ask_yes_no(_("Start retracing process?")) if ret: retrace(args) print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) backtrace.__doc__ = _("Show backtrace of a problem") @named("debuginfo-install") @aliases("di") @expects_obj @arg("MATCH", nargs="?", default="last", completer=match_completer) def di_install(args): prob = match_get_problem(args.MATCH, auth=args.auth) if not isinstance(prob, problem.Ccpp): which = _("This") if args.MATCH == "last": which = _("Last") print(_("{} problem is not of a C/C++ type. Can't install debuginfo").format(which)) sys.exit(1)
@expects_obj @arg('MATCH', nargs='?', default='last', completer=match_completer) @arg_verbose def backtrace(args): prob = match_get_problem(args.MATCH, auth=args.auth) if hasattr(prob, 'backtrace'): print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) else: print(_('Problem has no backtrace')) if isinstance(prob, problem.Ccpp): ret = ask_yes_no(_('Start retracing process?')) if ret: retrace(args) print(fmt_problems(prob, fmt=config.BACKTRACE_FMT)) backtrace.__doc__ = _('Show backtrace of a problem') @named('debuginfo-install') @aliases('di') @expects_obj @arg('MATCH', nargs='?', default='last', completer=match_completer) @arg_verbose def di_install(args): prob = match_get_problem(args.MATCH, auth=args.auth) if not isinstance(prob, problem.Ccpp): which = _('This') if args.MATCH == 'last': which = _('Last') print(_('{} problem is not of a C/C++ type. Can\'t install debuginfo')