Example #1
0
    def complete(self, packagelist):
        if not self.use_yum:
            return Collection.complete(self, packagelist)

        packages = set()
        unknown = set(packagelist)

        if unknown:
            result = self.call_helper("complete", dict(packages=list(unknown), groups=list(self.get_relevant_groups())))
            if result and "packages" in result and "unknown" in result:
                # we stringify every package because it gets returned
                # in unicode; set.update() doesn't work if some
                # elements are unicode and other are strings.  (I.e.,
                # u'foo' and 'foo' get treated as unique elements.)
                packages.update([str(p) for p in result["packages"]])
                unknown = set([str(p) for p in result["unknown"]])

            self.filter_unknown(unknown)

        return packages, unknown
Example #2
0
    def complete(self, packagelist):
        if not self.use_yum:
            return Collection.complete(self, packagelist)

        if packagelist:
            result = self.call_helper(
                "complete", dict(packages=list(packagelist), groups=list(self.get_relevant_groups()))
            )
            if not result:
                # some sort of error, reported by call_helper()
                return set(), packagelist
            # json doesn't understand sets or tuples, so we get back a
            # lists of lists (packages) and a list of unicode strings
            # (unknown).  turn those into a set of tuples and a set of
            # strings, respectively.
            unknown = set([str(u) for u in result["unknown"]])
            packages = set([tuple(p) for p in result["packages"]])
            self.filter_unknown(unknown)
            return packages, unknown
        else:
            return set(), set()
Example #3
0
    def complete(self, packagelist):
        """ Build a complete list of all packages and their dependencies.

        When using the Python yum libraries, this defers to the
        :ref:`bcfg2-yum-helper`; when using the builtin yum parser,
        this defers to
        :func:`Bcfg2.Server.Plugins.Packages.Collection.Collection.complete`.

        :param packagelist: Set of initial packages computed from the
                            specification.
        :type packagelist: set of strings, but see :ref:`pkg-objects`
        :returns: tuple of sets - The first element contains a set of
                  strings (but see :ref:`pkg-objects`) describing the
                  complete package list, and the second element is a
                  set of symbols whose dependencies could not be
                  resolved.
        """
        if not self.use_yum:
            return Collection.complete(self, packagelist)

        if packagelist:
            result = \
                self.call_helper("complete",
                                 dict(packages=list(packagelist),
                                      groups=list(self.get_relevant_groups())))
            if not result:
                # some sort of error, reported by call_helper()
                return set(), packagelist
            # json doesn't understand sets or tuples, so we get back a
            # lists of lists (packages) and a list of unicode strings
            # (unknown).  turn those into a set of tuples and a set of
            # strings, respectively.
            unknown = set([str(u) for u in result['unknown']])
            packages = set([tuple(p) for p in result['packages']])
            self.filter_unknown(unknown)
            return packages, unknown
        else:
            return set(), set()
Example #4
0
File: Yum.py Project: zenazn/bcfg2
    def complete(self, packagelist):
        """ Build a complete list of all packages and their dependencies.

        When using the Python yum libraries, this defers to the
        :ref:`bcfg2-yum-helper`; when using the builtin yum parser,
        this defers to
        :func:`Bcfg2.Server.Plugins.Packages.Collection.Collection.complete`.

        :param packagelist: Set of initial packages computed from the
                            specification.
        :type packagelist: set of strings, but see :ref:`pkg-objects`
        :returns: tuple of sets - The first element contains a set of
                  strings (but see :ref:`pkg-objects`) describing the
                  complete package list, and the second element is a
                  set of symbols whose dependencies could not be
                  resolved.
        """
        if not self.use_yum:
            return Collection.complete(self, packagelist)

        if packagelist:
            result = \
                self.call_helper("complete",
                                 dict(packages=list(packagelist),
                                      groups=list(self.get_relevant_groups())))
            if not result:
                # some sort of error, reported by call_helper()
                return set(), packagelist
            # json doesn't understand sets or tuples, so we get back a
            # lists of lists (packages) and a list of unicode strings
            # (unknown).  turn those into a set of tuples and a set of
            # strings, respectively.
            unknown = set([str(u) for u in result['unknown']])
            packages = set([tuple(p) for p in result['packages']])
            self.filter_unknown(unknown)
            return packages, unknown
        else:
            return set(), set()
Example #5
0
    def complete(self, packagelist):
        if not self.use_yum:
            return Collection.complete(self, packagelist)

        packages = set()
        unknown = set(packagelist)

        if unknown:
            result = \
                self.call_helper("complete",
                                 dict(packages=list(unknown),
                                      groups=list(self.get_relevant_groups())))
            if result and "packages" in result and "unknown" in result:
                # we stringify every package because it gets returned
                # in unicode; set.update() doesn't work if some
                # elements are unicode and other are strings.  (I.e.,
                # u'foo' and 'foo' get treated as unique elements.)
                packages.update([str(p) for p in result['packages']])
                unknown = set([str(p) for p in result['unknown']])

            self.filter_unknown(unknown)

        return packages, unknown
Example #6
0
    def complete(self, packagelist):
        if not self.use_yum:
            return Collection.complete(self, packagelist)

        cachekey = cPickle.dumps(sorted(packagelist))
        try:
            packages = self.pkgset_cache[cachekey]
        except KeyError:
            packages = set()

        pkgs = set(packagelist).difference(packages)    
        requires = set()
        satisfied = set()
        unknown = set()
        final_pass = False

        while requires or pkgs:
            # infinite loop protection
            start_reqs = len(requires)
            
            while pkgs:
                package = pkgs.pop()
                if package in packages:
                    continue
                
                if not self.is_package(package):
                    # try this package out as a requirement
                    requires.add((package, None, (None, None, None)))
                    continue

                packages.add(package)
                reqs = set(self.get_deps(package)).difference(satisfied)
                if reqs:
                    requires.update(reqs)

            reqs_satisfied = set()
            for req in requires:
                if req in satisfied:
                    reqs_satisfied.add(req)
                    continue

                if req[1] is None and self.is_package(req[0]):
                    if req[0] not in packages:
                        pkgs.add(req[0])
                    reqs_satisfied.add(req)
                    continue
                    
                self.logger.debug("Packages: Handling requirement '%s'" %
                                  self.get_package_name(req))
                providers = list(set(self.get_provides(req)))
                if len(providers) > 1:
                    # hopefully one of the providing packages is already
                    # included
                    best = [p for p in providers if p in packages]
                    if best:
                        providers = best
                    else:
                        # pick a provider whose name matches the requirement
                        best = [p for p in providers if p == req[0]]
                        if len(best) == 1:
                            providers = best
                        elif not final_pass:
                            # found no "best" package, so defer
                            providers = None
                        # else: found no "best" package, but it's the
                        # final pass, so include them all
                
                if providers:
                    self.logger.debug("Packages: Requirement '%s' satisfied "
                                      "by %s" %
                                     (self.get_package_name(req),
                                      ",".join([self.get_package_name(p)
                                                for p in providers])))
                    newpkgs = set(providers).difference(packages)
                    if newpkgs:
                        for package in newpkgs:
                            if self.is_package(package):
                                pkgs.add(package)
                            else:
                                unknown.add(package)
                    reqs_satisfied.add(req)
                elif providers is not None:
                    # nothing provided this requirement at all
                    unknown.add(req)
                    reqs_satisfied.add(req)
                # else, defer
            requires.difference_update(reqs_satisfied)

            # infinite loop protection
            if len(requires) == start_reqs and len(pkgs) == 0:
                final_pass = True

            if final_pass and requires:
                unknown.update(requires)
                requires = set()

        self.filter_unknown(unknown)
        unknown = [self.get_package_name(p) for p in unknown]

        # we do not cache unknown packages, since those are likely to
        # be fixed
        self.pkgset_cache[cachekey] = packages

        return packages, unknown