Esempio n. 1
0
    def packages(self):
        cachekey = "%s%s" % ("repopackages", self.id)
        pkgs = cache.get(cachekey)

        if not pkgs is None:
            return pkgs

        pkgs = {}
        ARCHS = [str(x) for x in Arch.objects.all()]
        PLATS = set(repo.platform.name for repo in self.comps)
        PLATS.add(self.platform.name)
        repo_pkg_meta = self.pkg_meta
        #sackpkgs = self.yumsack.returnPackages()
        #sackpkgs.sort(cmp=lambda x,y: x.verCMP(y), reverse=True)
        for pkg in self.yumsack.returnPackages():
            if not pkg.arch in ARCHS:
                continue

            # have we seen a binary from the same base package before ?
            if pkg.base_package_name in pkgs:
                # yes, check where it lives
                if pkg.repoid in pkgs[pkg.base_package_name]:
                    # same repo
                    if pkg.ver == pkgs[pkg.base_package_name][
                            pkg.repoid]["version"]:
                        # same version, append to binaries list
                        pkgs[pkg.base_package_name][
                            pkg.repoid]['binaries'].add(pkg)
                        pkgs[pkg.base_package_name][
                            pkg.repoid]['binary_names'].add(pkg.name)
                        if not pkg.name.endswith(
                                "debuginfo") and not pkg.name.endswith(
                                    "debugsource") and not pkg.name.endswith(
                                        "-doc") and not pkg.name.endswith(
                                            "-tests"
                                        ) and not pkg.name.endswith("-devel"):
                            pkgs[pkg.base_package_name][pkg.repoid].update({
                                "description":
                                pkg.description,
                                "summary":
                                pkg.summary
                            })
                    else:
                        # oh no different version!
                        pkgs[pkg.base_package_name][
                            pkg.repoid]["messages"].append(
                                "Warning: %s exists in the same repo with different version %s!"
                                % (pkg.name, pkg.ver))
                    # no need to look further
                    continue
            else:
                pkgs[pkg.base_package_name] = {}

            pkg_meta = _get_pkg_meta(pkg.base_package_name, PLATS,
                                     repo_pkg_meta)
            pkgs[pkg.base_package_name][pkg.repoid] = {
                "version": pkg.ver,
                "release": pkg.rel,
                "changelog": _fmt_chlog(pkg.changelog),
                "license": pkg.license,
                "binaries": set([pkg]),
                "binary_names": set([pkg.name]),
                "meta": pkg_meta,
                "messages": [],
            }
            if not pkg.name.endswith("debuginfo") and not pkg.name.endswith(
                    "debugsource") and not pkg.name.endswith(
                        "-doc") and not pkg.name.endswith(
                            "-tests") and not pkg.name.endswith("-devel"):
                pkgs[pkg.base_package_name][pkg.repoid].update({
                    "description":
                    pkg.description,
                    "summary":
                    pkg.summary
                })

        cachelife = (60 * 5) if self.is_live else (60 * 60 * 24)
        cache.set(cachekey, pkgs, cachelife)

        return pkgs
Esempio n. 2
0
def _diff_sacks(newrepo, oldrepo, progress_cb):

    is_livediff = newrepo.is_live and oldrepo.is_live
    newprjsack = newrepo.prjsack
    oldprjsack = oldrepo.prjsack

    repo_pkg_meta = newrepo.pkg_meta
    platforms = set(repo.platform.name for repo in newrepo.comps)
    platforms.add(newrepo.platform.name)

    # key_tuple = ( repo id, repo string, pkg base name )
    # { key_tuple : { binaries : set[] , chlog : [] } }
    added = defaultdict(dict)
    # { key_tuple : set[] }
    removed = defaultdict(set)
    # { key_tuple : { ovr : old version , oa : old arch , nvr : new version , na : new arch , chlo : changelog diff } }
    modified = {}

    obsoleted = {}
    obsoletes = {}

    ARCHS = set([str(x) for x in Arch.objects.all()])
    ARCHS.add("src")
    #toskip = set([ "debuginfo", "debugsource", "devel", "tests" ])
    toskip = set(["debuginfo", "debugsource"])

    # first go through the new repo collection
    repoids = {}
    if is_livediff and newrepo.comps:
        for repo in newrepo.comps:
            repoids[repo.yumrepoid] = repo
    else:
        repoids[newrepo.yumrepoid] = newrepo

    repo_count = len(repoids.keys()) * 2
    done_count = 0
    for repoid, repo in repoids.items():
        done_count += 1
        progress_cb(math.ceil((float(done_count) / repo_count) * 100))
        repo_str = str(repo)
        prjsack = list(repo.prjsack)
        project = None
        if repo.is_live and len(prjsack) == 1:
            project = prjsack[0].request_target
            if not project or not project in oldprjsack:
                try:
                    project = prjsack[0].request_source.get()
                except ObjectDoesNotExist:
                    project = None

            if project and project in oldprjsack:
                project = str(project.name)
            else:
                project = None

        old_comparable = _find_comparable_component(repo,
                                                    oldrepo,
                                                    project=project)

        if old_comparable:
            old_comparable = old_comparable.yumsack
        else:
            old_comparable = oldrepo.yumsack

        pkgs = []
        if is_livediff:
            pkgs = repo.yumsack.returnPackages()
        else:
            pkgs = repo.yumsack.returnNewestByName()

        for pkg in pkgs:
            # skip archs we don't care about
            if not pkg.arch in ARCHS:
                continue

            # skip debuginfo and debugsource rpms
            suffix = pkg.name.split("-")[-1]
            if suffix in toskip:
                continue

            key_tuple = (repo.id, repo_str, pkg.base_package_name)
            nvr = "%s - %s-%s" % (pkg.name, pkg.ver, pkg.rel)

            oldpkgs = list(old_comparable.searchNames(pkg.name))
            oldpkgs.sort(cmp=lambda x, y: x.verCMP(y), reverse=True)
            oldpkgs = oldpkgs[:1]

            for oldpkg in oldpkgs:
                #if not oldpkg.arch in ARCHS:
                #    continue
                #if not pkg.arch == oldpkg.arch and ( not pkg.arch == "noarch" or not oldpkg.arch == "noarch" ):
                #    continue

                if not key_tuple in modified:
                    # check for a change in version or release number
                    if not pkg.ver == oldpkg.ver or not pkg.rel == oldpkg.rel:
                        # get new changelog entries
                        chlog = _diff_chlog(oldpkg.changelog, pkg.changelog)
                        # a version change is reported even without changelog
                        # while a release change is ignored in that case
                        if len(chlog) or not pkg.ver == oldpkg.ver:
                            if not len(chlog):
                                chlog.append("No new changelog entries!")
                            modified.update({
                                key_tuple: {
                                    "sense":
                                    "Updated"
                                    if pkg.verCMP(oldpkg) == 1 else "Reverted",
                                    "ovr":
                                    "%s-%s" % (oldpkg.ver, oldpkg.rel),
                                    "oa":
                                    oldpkg.arch,
                                    "nvr":
                                    "%s-%s" % (pkg.ver, pkg.rel),
                                    "na":
                                    pkg.arch,
                                    "ba":
                                    set(),
                                    "br":
                                    set(),
                                    "chlo":
                                    chlog,
                                    "meta":
                                    _get_pkg_meta(pkg.base_package_name,
                                                  platforms, repo_pkg_meta),
                                    "unmet_reqs":
                                    set()
                                }
                            })

                #if key_tuple in modified:
                #    modified[key_tuple]["unmet_reqs"].update(_find_unmet_reqs(pkg, newsack, oldsack = oldsack))

                # we don't need to look further
                break

            if not len(oldpkgs):
                if not key_tuple in added:
                    added[key_tuple]["binaries"] = set()
                    added[key_tuple]["chlog"] = _fmt_chlog(pkg.changelog)
                    added[key_tuple]["meta"] = _get_pkg_meta(
                        pkg.base_package_name, platforms, repo_pkg_meta)
                    added[key_tuple]["unmet_reqs"] = set()
                added[key_tuple]["binaries"].add(nvr)
                #added[key_tuple]["unmet_reqs"].update(_find_unmet_reqs(pkg, newsack, oldsack = oldsack))

                if pkg.obsoletes:
                    obsoletes[nvr] = pkg.obsoletes

    oldpkgs_by_repoid = defaultdict(list)
    # now go through the old repo collection
    repoids = {}
    if is_livediff and oldrepo.comps:
        for repo in oldrepo.comps:
            repoids[repo.yumrepoid] = repo
    else:
        repoids[oldrepo.yumrepoid] = oldrepo
    repo_count = len(repoids.keys())
    done_count = 0

    for repoid, repo in repoids.items():
        done_count += 1
        progress_cb(
            math.ceil((((float(done_count) / repo_count) * 100) / 2) + 50))
        pkgs = repo.yumsack.returnPackages()
        repo_str = str(repo)

        # cache the specific comparable component in the older repo
        prjsack = list(repo.prjsack)
        project = None
        if repo.is_live and len(prjsack) == 1:
            try:
                project = prjsack[0].request_source.get()
            except ObjectDoesNotExist:
                project = prjsack[0].request_target

            if project and project in newprjsack:
                project = str(project.name)
            else:
                project = None

        new_comparable = _find_comparable_component(repo,
                                                    newrepo,
                                                    project=project)

        if new_comparable:
            new_comparable_id = new_comparable.id
            new_comparable_str = str(new_comparable)
            new_comparable = new_comparable.yumsack
        else:
            new_comparable_id = newrepo.id
            new_comparable_str = str(newrepo)
            new_comparable = newrepo.yumsack

        for pkg in pkgs:
            if not pkg.arch in ARCHS:
                continue

            # skip debuginfo and debugsource rpms
            suffix = pkg.name.split("-")[-1]
            if suffix in toskip:
                continue

            # look for removed packages
            if not list(new_comparable.searchNames(pkg.name)):
                key_tuple = (new_comparable_id, new_comparable_str,
                             pkg.base_package_name)
                if key_tuple in modified:
                    modified[key_tuple]['br'].add(pkg.name)
                else:
                    oldpkgs_by_repoid[pkg.repoid].append(pkg)

    for repoid, pkgs in oldpkgs_by_repoid.items():
        repo = repoids.get(repoid, oldrepo)
        repo_str = str(repo)

        for pkg in pkgs:
            nvr = "%s - %s-%s" % (pkg.name, pkg.ver, pkg.rel)
            removed[(repo.id, repo_str, pkg.base_package_name)].add(nvr)

            for obsby, obss in obsoletes.items():
                for obs in obss:
                    if pkg.inPrcoRange('provides', obs):
                        obsoleted.update({nvr: obsby})

    # merge added binaries to corresponding entries in modified
    # leftover packages are really new or have been completely removed
    toremove = set()
    for key_tuple in modified:
        repoid, repostr, pkg = key_tuple
        if key_tuple in added:
            modified[key_tuple]["ba"] = added[key_tuple]['binaries']
            del (added[key_tuple])

    diff = {
        "added": dict(added),
        "removed": dict(removed),
        "modified": modified,
        "obsoleted": obsoleted
    }

    progress_cb(100)
    return diff