????
Current Path : /usr/bin/ |
Current File : //usr/bin/abrt-action-install-debuginfo |
#! /usr/bin/python -u # -*- coding: utf-8 -*- # WARNING: python -u means unbuffered I/O without it the messages are # passed to the parent asynchronously which looks bad in clients. PROGNAME = "abrt-action-install-debuginfo" import sys import os import errno import getopt import reportclient from subprocess import Popen, PIPE from reportclient import _, verbose, log, log1, log2, set_verbosity, error_msg_and_die, error_msg import time from reportclient.debuginfo import DebugInfoDownload, filter_installed_debuginfos, build_ids_to_path, clean_up import problem # everything was ok RETURN_OK = 0 # serious problem, should be logged somewhere RETURN_FAILURE = 2 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 sigterm_handler(signum, frame): clean_up() exit(RETURN_OK) def sigint_handler(signum, frame): clean_up() print "\n", _("Exiting on user command") sys.stdout.flush() # ??! without "sys.", I am getting segv! sys.exit(RETURN_OK) import signal if __name__ == "__main__": # abrt-server can send SIGTERM to abort the download signal.signal(signal.SIGTERM, sigterm_handler) # ctrl-c signal.signal(signal.SIGINT, sigint_handler) fbuild_ids = "build_ids" cachedirs = [] size_mb = 4096 tmpdir = None keeprpms = False noninteractive = False b_ids = [] exact_fls = False missing = None # localization init_gettext() ABRT_VERBOSE = os.getenv("ABRT_VERBOSE") if (ABRT_VERBOSE): try: verbose = int(ABRT_VERBOSE) except: pass PROGNAME = os.path.basename(sys.argv[0]) # ____________________________________________________________________________________ 7 # ______01234567890123456789012345678901234567890123456789012345678901234567890123456789 help_text = _( "Usage: %s [-vy] [--ids=BUILD_IDS_FILE]\n" " [--tmpdir=TMPDIR] [--cache=CACHEDIR[:DEBUGINFODIR1:DEBUGINFODIR2...]] [--size_mb=SIZE]\n" " [-e, --exact=PATH]\n" "\n" "Installs debuginfos for all build-ids listed in BUILD_IDS_FILE\n" "to CACHEDIR, using TMPDIR as temporary staging area.\n" "Old files in CACHEDIR are deleted until it is smaller than SIZE.\n" "\n" " -v Be verbose\n" " -y Noninteractive, assume 'Yes' to all questions\n" " --ids Default: build_ids\n" " --tmpdir Default: /tmp/abrt-tmp-debuginfo-RANDOM_SUFFIX\n" " --cache Default: /var/cache/abrt-di\n" " --size_mb Default: 4096\n" " -e,--exact Download only specified files\n" # --keeprpms is not documented yet because it's a NOP so far ) % PROGNAME try: opts, args = getopt.getopt(sys.argv[1:], "vyhe", ["help", "ids=", "cache=", "size_mb=", "tmpdir=", "keeprpms", "exact="]) except getopt.GetoptError, err: print str(err) # prints something like "option -a not recognized" exit(RETURN_FAILURE) for opt, arg in opts: if opt in ("-h", "--help"): print help_text exit(0) elif opt == "-v": verbose += 1 elif opt == "-y": noninteractive = True elif opt == "--ids": fbuild_ids = arg elif opt == "--cache": cachedirs = arg.split(':') elif opt == "--size_mb": try: size_mb = int(arg) except: pass elif opt == "--tmpdir": tmpdir = arg elif opt == "--keeprpms": keeprpms = True # --exact takes precendece over --ids elif opt in ("-e", "--exact"): missing=arg.split(':') exact_fls = True if not cachedirs: try: conf = problem.load_plugin_conf_file("CCpp.conf") except OSError as ex: print str(ex) else: cachedirs = conf.get("DebuginfoLocation", None) if not cachedirs: cachedirs = ["/var/cache/abrt-di"] if not tmpdir: # security people prefer temp subdirs in app's private dir, like /var/run/abrt # for now, we use /tmp... tmpdir = "/tmp/abrt-tmp-debuginfo-%s.%u" % (time.strftime("%Y-%m-%d-%H:%M:%S"), os.getpid()) if missing == None: fin = sys.stdin if fbuild_ids != "-": try: fin = open(fbuild_ids, "r") except IOError, ex: error_msg_and_die(_("Can't open {0}: {1}").format(fbuild_ids, ex)) for line in fin.readlines(): b_ids.append(line.strip('\n')) if not b_ids: exit(RETURN_FAILURE) # Delete oldest/biggest files from cachedir. # (Note that we need to do it before we check for missing debuginfos) # # We can do it as a separate step in report_event.conf, but this # would require setuid'ing abrt-action-trim-files to abrt:abrt. # Since we (via abrt-action-install-debuginfo-to-abrt-cache) # are already running setuid, # it makes sense to NOT setuid abrt-action-trim-files too, # but instead run it as our child: sys.stdout.flush() try: pid = os.fork() if pid == 0: argv = ["abrt-action-trim-files", "-f", "%um:%s" % (size_mb, cachedirs[0]), "--"] argv.extend(build_ids_to_path(cachedirs[0], b_ids)) log2("abrt-action-trim-files %s", argv); os.execvp("abrt-action-trim-files", argv); if pid > 0: os.waitpid(pid, 0); except Exception, e: error_msg("Can't execute abrt-action-trim-files: %s", e); missing = filter_installed_debuginfos(b_ids, cachedirs) if missing: log2("%s", missing) print _("Coredump references {0} debuginfo files, {1} of them are not installed").format(len(b_ids), len(missing)) # TODO: should we pass keep_rpms=keeprpms to DebugInfoDownload here?? downloader = DebugInfoDownload(cache=cachedirs[0], tmp=tmpdir) try: result = downloader.download(missing, download_exact_files=exact_fls) except Exception, ex: error_msg_and_die("Can't download debuginfos: %s", ex) missing = filter_installed_debuginfos(b_ids, cachedirs) for bid in missing: print _("Missing debuginfo file: {0}").format(bid) if not missing: print _("All debuginfo files are available") exit(RETURN_OK)