Ejemplo n.º 1
0
    def run(self, cmdline, db):
        build_ids = []
        missing = []

        self.log_info("Executing eu-unstrip")
        child = safe_popen("eu-unstrip", "-n", "--core", cmdline.COREDUMP)
        if child is None:
            self.log_error("Failed to execute eu-unstrip")
            return 1

        for line in child.stdout.splitlines():
            match = Coredump2Packages.UNSTRIP_LINE_PARSER.match(line)
            if not match:
                self.log_warn("Unable to parse line: {0}".format(line))
                continue

            if not all(c in string.printable for c in line):
                self.log_warn("Skipping line with non-printable characters")
                self.log_debug(line)
                continue

            if match.group(2):
                if match.group(3).startswith("/"):
                    build_ids.append((match.group(2), match.group(3)))
                elif (match.group(5) != "-"
                      and not match.group(5).startswith("[")):
                    build_ids.append((match.group(2), match.group(5)))
                else:
                    build_ids.append((match.group(2), None))
            else:
                missing.append(match.group(3))

        self.log_info("Mapping build-ids into debuginfo packages")
        build_id_maps = {}
        debuginfos = {}
        for build_id, soname in build_ids:
            debug_file = self._build_id_to_debug_file(build_id)
            db_packages = get_packages_by_file(db, debug_file)
            db_packages = [p for p in db_packages if p.has_lob("package")]
            if len(db_packages) < 1:
                self.log_warn("No debuginfo found for '{0}' ({1})".format(
                    build_id, soname))
                continue
            else:
                self.log_debug("Found {0} debuginfo packages for '{1}' ({2}): "
                               "{3}".format(len(db_packages), build_id, soname,
                                            [p.nvra() for p in db_packages]))

            if build_id not in build_id_maps:
                build_id_maps[build_id] = set()

            for db_package in db_packages:
                pkgname = db_package.name
                pkgnvra = db_package.nvra()

                build_id_maps[build_id].add(pkgname)

                if pkgname not in debuginfos:
                    debuginfos[pkgname] = {}

                if pkgnvra not in debuginfos[pkgname]:
                    debuginfos[pkgname][pkgnvra] = {
                        "count": 0,
                        "package": db_package
                    }

                debuginfos[pkgname][pkgnvra]["count"] += 1

        for build_id, debug_pkgs in build_id_maps.items():
            if len(debug_pkgs) > 1:
                self.log_warn(
                    "Debuginfo conflict: '{0}' is provided by {1}".format(
                        build_id, debug_pkgs))

            build_id_maps[build_id] = debug_pkgs.pop()

        result = set()
        debuginfo_maps = {}
        debuginfo_packages = []
        for pkgname in sorted(debuginfos):
            best = {"count": -1, "package": None}
            for pkgnvra in debuginfos[pkgname]:
                if debuginfos[pkgname][pkgnvra]["count"] > best["count"]:
                    best = debuginfos[pkgname][pkgnvra]

            if best["package"]:
                basename = best["package"].build.base_package_name
                if basename in Coredump2Packages.SKIP_PACKAGES:
                    self.log_debug("Skipping '{0}'".format(basename))
                    continue

                self.log_debug("Picking '{0}' for '{1}' with {2} build_id "
                               "matches".format(best["package"].nvra(),
                                                best["package"].name,
                                                best["count"]))

                debuginfo_packages.append(best["package"])
                debuginfo_maps[best["package"].name] = best["package"]
                result.add(best["package"])
            else:
                #paranoia - never happens
                self.log_warn(
                    "Unable to determine best version of '{0}'".format(
                        pkgname))

        self.log_info("Getting binary packages from debuginfos")
        archs = {}
        db_build_ids = [dp.build.id for dp in debuginfo_packages]
        postprocess = set()
        for build_id, soname in build_ids:
            if build_id not in build_id_maps:
                continue

            if soname is None:
                if (build_id in build_id_maps and isinstance(
                        build_id_maps[build_id], six.string_types)
                        and build_id_maps[build_id] in debuginfo_maps):
                    nvra = debuginfo_maps[build_id_maps[build_id]].nvra()
                    self.log_info(
                        "No shared object name for '{0}' ({1})".format(
                            build_id, nvra))
                    db_build = debuginfo_maps[build_id_maps[build_id]].build
                    postprocess.add(db_build)
            else:
                debuginfo_name = build_id_maps[build_id]
                if debuginfo_name in Coredump2Packages.SKIP_PACKAGES:
                    self.log_debug("Skipping {0}".format(debuginfo_name))
                    continue

                db_arch = debuginfo_maps[debuginfo_name].arch
                abspath = soname.startswith("/")
                db_packages = get_packages_by_file_builds_arch(db,
                                                               soname,
                                                               db_build_ids,
                                                               db_arch,
                                                               abspath=abspath)

                if abspath and len(db_packages) < 1:
                    new_soname = usrmove(soname)
                    db_packages = get_packages_by_file_builds_arch(
                        db, new_soname, db_build_ids, db_arch)

                if len(db_packages) < 1:
                    self.log_warn("Unable to find binary package for '{0}' "
                                  "({1})".format(build_id, soname))
                    continue

                for db_package in db_packages:
                    result.add(db_package)
                    arch = db_arch.name
                    if arch not in archs:
                        archs[arch] = 0

                    archs[arch] += 1

        if len(postprocess) > 0 and len(archs) > 0:
            self.log_info("Post-processing records without shared object name")
            arch = None
            archmax = 0
            for archname, archcount in archs.items():
                if archcount > archmax:
                    archmax = archcount
                    arch = archname

            self.log_info("Determined architecture: {0}".format(arch))

            for db_build in postprocess:
                basename = db_build.base_package_name
                if basename in Coredump2Packages.SKIP_PACKAGES:
                    self.log_info("Skipping {0}".format(basename))
                    continue

                for db_package in db_build.packages:
                    if db_package.arch.name == arch:
                        self.log_debug("Picking {0} for {1}".format(
                            db_package.nvra(), basename))
                        result.add(db_package)

        link = None
        tmpdir = None
        if cmdline.symlink_dir:
            tmpdir = tempfile.mkdtemp(dir=cmdline.symlink_dir)
            link = os.symlink
        elif cmdline.hardlink_dir:
            tmpdir = tempfile.mkdtemp(dir=cmdline.hardlink_dir)
            link = os.link

        for db_package in result:
            if link is None:
                print(db_package.nvra())
                continue

            path_from = db_package.get_lob_path("package")
            path_to = os.path.join(tmpdir, "{0}.rpm".format(db_package.nvra()))
            try:
                link(path_from, path_to)
            except OSError:
                if cmdline.no_copy:
                    continue

                shutil.copy2(path_from, path_to)

        if tmpdir is not None:
            print(tmpdir)
Ejemplo n.º 2
0
Archivo: c2p.py Proyecto: trams/faf
    def run(self, cmdline, db):
        build_ids = []
        missing = []

        self.log_info("Executing eu-unstrip")
        child = safe_popen("eu-unstrip", "-n", "--core", cmdline.COREDUMP)
        if child is None:
            self.log_error("Failed to execute eu-unstrip")
            return 1

        for line in child.stdout.splitlines():
            match = Coredump2Packages.UNSTRIP_LINE_PARSER.match(line)
            if not match:
                self.log_warn("Unable to parse line: {0}".format(line))
                continue

            if match.group(2):
                if match.group(3).startswith("/"):
                    build_ids.append((match.group(2), match.group(3)))
                elif (match.group(5) != "-" and
                      not match.group(5).startswith("[")):
                    build_ids.append((match.group(2), match.group(5)))
                else:
                    build_ids.append((match.group(2), None))
            else:
                missing.append(match.group(3))

        self.log_info("Mapping build-ids into debuginfo packages")
        build_id_maps = {}
        debuginfos = {}
        for build_id, soname in build_ids:
            debug_file = self._build_id_to_debug_file(build_id)
            db_packages = get_packages_by_file(db, debug_file)
            db_packages = [p for p in db_packages if p.has_lob("package")]
            if len(db_packages) < 1:
                self.log_warn("No debuginfo found for '{0}' ({1})"
                              .format(build_id, soname))
                continue
            else:
                self.log_debug("Found {0} debuginfo packages for '{1}' ({2}): "
                               "{3}".format(len(db_packages), build_id, soname,
                                            [p.nvra() for p in db_packages]))

            if build_id not in build_id_maps:
                build_id_maps[build_id] = set()

            for db_package in db_packages:
                pkgname = db_package.name
                pkgnvra = db_package.nvra()

                build_id_maps[build_id].add(pkgname)

                if pkgname not in debuginfos:
                    debuginfos[pkgname] = {}

                if pkgnvra not in debuginfos[pkgname]:
                    debuginfos[pkgname][pkgnvra] = { "count": 0,
                                                     "package": db_package }

                debuginfos[pkgname][pkgnvra]["count"] += 1

        for build_id, debug_pkgs in build_id_maps.items():
            if len(debug_pkgs) > 1:
                self.log_warn("Debuginfo conflict: '{0}' is provided by {1}"
                              .format(build_id, debug_pkgs))

            build_id_maps[build_id] = debug_pkgs.pop()

        result = set()
        debuginfo_maps = {}
        debuginfo_packages = []
        for pkgname in sorted(debuginfos):
            best = { "count": -1, "package": None }
            for pkgnvra in debuginfos[pkgname]:
                if debuginfos[pkgname][pkgnvra]["count"] > best["count"]:
                    best = debuginfos[pkgname][pkgnvra]

            if best["package"]:
                basename = best["package"].build.base_package_name
                if basename in Coredump2Packages.SKIP_PACKAGES:
                    self.log_debug("Skipping '{0}'".format(basename))
                    continue

                self.log_debug("Picking '{0}' for '{1}' with {2} build_id "
                               "matches".format(best["package"].nvra(),
                                                best["package"].name,
                                                best["count"]))

                debuginfo_packages.append(best["package"])
                debuginfo_maps[best["package"].name] = best["package"]
                result.add(best["package"])
            else:
                #paranoia - never happens
                self.log_warn("Unable to determine best version of '{0}'"
                              .format(pkgname))

        self.log_info("Getting binary packages from debuginfos")
        archs = {}
        db_build_ids = [dp.build.id for dp in debuginfo_packages]
        postprocess = set()
        for build_id, soname in build_ids:
            if build_id not in build_id_maps:
                continue

            if soname is None:
                if (build_id in build_id_maps and
                    isinstance(build_id_maps[build_id], basestring) and
                    build_id_maps[build_id] in debuginfo_maps):
                    nvra = debuginfo_maps[build_id_maps[build_id]].nvra()
                    self.log_info("No shared object name for '{0}' ({1})"
                                  .format(build_id, nvra))
                    db_build = debuginfo_maps[build_id_maps[build_id]].build
                    postprocess.add(db_build)
            else:
                debuginfo_name = build_id_maps[build_id]
                if debuginfo_name in Coredump2Packages.SKIP_PACKAGES:
                    self.log_debug("Skipping {0}".format(debuginfo_name))
                    continue

                db_arch = debuginfo_maps[debuginfo_name].arch
                abspath = soname.startswith("/")
                db_packages = get_packages_by_file_builds_arch(db,
                                                               soname,
                                                               db_build_ids,
                                                               db_arch,
                                                               abspath=abspath)

                if abspath and len(db_packages) < 1:
                    new_soname = usrmove(soname)
                    db_packages = get_packages_by_file_builds_arch(db,
                                                                   new_soname,
                                                                   db_build_ids,
                                                                   db_arch)

                if len(db_packages) < 1:
                    self.log_warn("Unable to find binary package for '{0}' "
                                  "({1})".format(build_id, soname))
                    continue

                for db_package in db_packages:
                    result.add(db_package)
                    arch = db_arch.name
                    if arch not in archs:
                        archs[arch] = 0

                    archs[arch] += 1

        if len(postprocess) > 0 and len(archs) > 0:
            self.log_info("Post-processing records without shared object name")
            arch = None
            archmax = 0
            for archname, archcount in archs.items():
                if archcount > archmax:
                    archmax = archcount
                    arch = archname

            self.log_info("Determined architecture: {0}".format(arch))

            for db_build in postprocess:
                basename = db_build.base_package_name
                if basename in Coredump2Packages.SKIP_PACKAGES:
                    self.log_info("Skipping {0}".format(basename))
                    continue

                for db_package in db_build.packages:
                    if db_package.arch.name == arch:
                        self.log_debug("Picking {0} for {1}"
                                       .format(db_package.nvra(), basename))
                        result.add(db_package)

        link = None
        tmpdir = None
        if cmdline.symlink_dir:
            tmpdir = tempfile.mkdtemp(dir=cmdline.symlink_dir)
            link = os.symlink
        elif cmdline.hardlink_dir:
            tmpdir = tempfile.mkdtemp(dir=cmdline.hardlink_dir)
            link = os.link

        for db_package in result:
            if link is None:
                print(db_package.nvra())
                continue

            path_from = db_package.get_lob_path("package")
            path_to = os.path.join(tmpdir, "{0}.rpm".format(db_package.nvra()))
            try:
                link(path_from, path_to)
            except OSError:
                if cmdline.no_copy:
                    continue

                shutil.copy2(path_from, path_to)

        if tmpdir is not None:
            print tmpdir
Ejemplo n.º 3
0
Archivo: c2p.py Proyecto: mkutlak/faf
    def run(self, cmdline, db) -> int:
        build_ids, _ = self._unstrip(cmdline)

        self.log_info("Mapping build-ids into debuginfo packages")
        build_id_maps = {}
        debuginfos = {}
        for build_id, soname in build_ids:
            files = self._build_id_to_debug_files(build_id)
            db_packages = get_packages_by_file(db, files)
            db_packages = [p for p in db_packages if p.has_lob("package")]
            if not db_packages:
                self.log_warn("No debuginfo found for '{0}' ({1})".format(
                    build_id, soname))
                continue
            self.log_debug("Found %d debuginfo packages for '%s' (%s): %s",
                           len(db_packages), build_id, soname,
                           [p.nvra() for p in db_packages])

            if build_id not in build_id_maps:
                build_id_maps[build_id] = set()

            for db_package in db_packages:
                pkgname = db_package.name
                pkgnvra = db_package.nvra()

                build_id_maps[build_id].add(pkgname)

                if pkgname not in debuginfos:
                    debuginfos[pkgname] = {}

                if pkgnvra not in debuginfos[pkgname]:
                    debuginfos[pkgname][pkgnvra] = {
                        "count": 0,
                        "package": db_package
                    }

                debuginfos[pkgname][pkgnvra]["count"] += 1

        for build_id, debug_pkgs in build_id_maps.items():
            if len(debug_pkgs) > 1:
                self.log_warn(
                    "Debuginfo conflict: '{0}' is provided by {1}".format(
                        build_id, debug_pkgs))

            build_id_maps[build_id] = debug_pkgs.pop()

        result = set()
        debuginfo_maps = {}
        debuginfo_packages = []
        for pkgname in sorted(debuginfos):
            best = {"count": -1, "package": None}
            for pkgnvra in debuginfos[pkgname]:
                if debuginfos[pkgname][pkgnvra]["count"] > best["count"]:
                    best = debuginfos[pkgname][pkgnvra]

            if best["package"]:
                basename = best["package"].build.base_package_name
                if basename in Coredump2Packages.SKIP_PACKAGES:
                    self.log_debug("Skipping '%s'", basename)
                    continue

                self.log_debug(
                    "Picking '%s' for '%s' with %d build_id matches",
                    best["package"].nvra(), best["package"].name,
                    best["count"])

                debuginfo_packages.append(best["package"])
                debuginfo_maps[best["package"].name] = best["package"]
                result.add(best["package"])
            else:
                #paranoia - never happens
                self.log_warn(
                    "Unable to determine best version of '{0}'".format(
                        pkgname))

        self.log_info("Getting binary packages from debuginfos")
        archs = {}
        db_build_ids = [dp.build.id for dp in debuginfo_packages]
        postprocess = set()
        for build_id, soname in build_ids:
            if build_id not in build_id_maps:
                continue

            if soname is None:
                if (build_id in build_id_maps
                        and isinstance(build_id_maps[build_id], str)
                        and build_id_maps[build_id] in debuginfo_maps):
                    nvra = debuginfo_maps[build_id_maps[build_id]].nvra()
                    self.log_info(
                        "No shared object name for '{0}' ({1})".format(
                            build_id, nvra))
                    db_build = debuginfo_maps[build_id_maps[build_id]].build
                    postprocess.add(db_build)
            else:
                debuginfo_name = build_id_maps[build_id]
                if debuginfo_name in Coredump2Packages.SKIP_PACKAGES:
                    self.log_debug("Skipping %s", debuginfo_name)
                    continue

                db_arch = debuginfo_maps[debuginfo_name].arch
                abspath = soname.startswith("/")
                db_packages = get_packages_by_file_builds_arch(db,
                                                               soname,
                                                               db_build_ids,
                                                               db_arch,
                                                               abspath=abspath)

                if abspath and not db_packages:
                    new_soname = usrmove(soname)
                    db_packages = get_packages_by_file_builds_arch(
                        db, new_soname, db_build_ids, db_arch)

                if not db_packages:
                    self.log_warn("Unable to find binary package for '{0}' "
                                  "({1})".format(build_id, soname))
                    continue

                for db_package in db_packages:
                    result.add(db_package)
                    arch = db_arch.name
                    if arch not in archs:
                        archs[arch] = 0

                    archs[arch] += 1

        if postprocess and archs:
            self.log_info("Post-processing records without shared object name")
            arch = None
            archmax = 0
            for archname, archcount in archs.items():
                if archcount > archmax:
                    archmax = archcount
                    arch = archname

            self.log_info("Determined architecture: {0}".format(arch))

            for db_build in postprocess:
                basename = db_build.base_package_name
                if basename in Coredump2Packages.SKIP_PACKAGES:
                    self.log_info("Skipping {0}".format(basename))
                    continue

                for db_package in db_build.packages:
                    if db_package.arch.name == arch:
                        self.log_debug("Picking %s for %s", db_package.nvra(),
                                       basename)
                        result.add(db_package)

        link = None
        tmpdir = None
        if cmdline.symlink_dir:
            tmpdir = tempfile.mkdtemp(dir=cmdline.symlink_dir)
            link = os.symlink
        elif cmdline.hardlink_dir:
            tmpdir = tempfile.mkdtemp(dir=cmdline.hardlink_dir)
            link = os.link

        for db_package in result:
            if link is None:
                print(db_package.nvra())
                continue

            path_from = db_package.get_lob_path("package")
            path_to = os.path.join(tmpdir, "{0}.rpm".format(db_package.nvra()))
            try:
                link(path_from, path_to)
            except OSError:
                if cmdline.no_copy:
                    continue

                shutil.copy2(path_from, path_to)

        if tmpdir is not None:
            print(tmpdir)
        return 0