From ab420dd0188b790befad4eacec09c23801042863 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 11 Jun 2013 10:10:41 +0200 Subject: Plugins/PkgVars: new plugin to set various vars per package This plugins allows the setting of varius flags per package. It should be used f.e. to specify pinnings for debian packages or use flags and keywords for gentoo packages (needs to be implemented by future Portage plugin). --- .../Bcfg2/Server/Plugins/Packages/Collection.py | 27 +++++++++++++++++++--- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 5 ++-- src/lib/Bcfg2/Server/Plugins/Packages/__init__.py | 8 +++++-- 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Packages') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py b/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py index 004e27874..ccb526a19 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py @@ -289,7 +289,7 @@ class Collection(list, Debuggable): return any(source.is_virtual_package(self.metadata, package) for source in self) - def get_deps(self, package, recs=None): + def get_deps(self, package, recs=None, pinnings=None): """ Get a list of the dependencies of the given package. The base implementation simply aggregates the results of @@ -297,16 +297,35 @@ class Collection(list, Debuggable): :param package: The name of the symbol, but see :ref:`pkg-objects` :type package: string + :param pinnings: Mapping from package names to source names. + :type pinnings: dict :returns: list of strings, but see :ref:`pkg-objects` """ recommended = None if recs and package in recs: recommended = recs[package] + pin_found = False + pin_source = None + if pinnings and package in pinnings: + pin_source = pinnings[package] + for source in self: + if pin_source and pin_source != source.name: + continue + pin_found = True + if source.is_package(self.metadata, package): return source.get_deps(self.metadata, package, recommended) + if not pin_found: + if pin_source: + self.logger.error("Packages: Source '%s' for package '%s' not found" % + (pin_source, package)) + else: + self.logger.error("Packages: No source found for package '%s'" % + package); + return [] def get_essential(self): @@ -471,12 +490,14 @@ class Collection(list, Debuggable): @track_statistics() def complete(self, packagelist, # pylint: disable=R0912,R0914 - recommended=None): + recommended=None, pinnings=None): """ Build a complete list of all packages and their dependencies. :param packagelist: Set of initial packages computed from the specification. :type packagelist: set of strings, but see :ref:`pkg-objects` + :param pinnings: Mapping from package names to source names. + :type pinnings: dict :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 @@ -535,7 +556,7 @@ class Collection(list, Debuggable): self.debug_log("Packages: handling package requirement %s" % (current,)) packages.add(current) - deps = self.get_deps(current, recommended) + deps = self.get_deps(current, recommended, pinnings) newdeps = set(deps).difference(examined) if newdeps: self.debug_log("Packages: Package %s added requirements %s" diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 846fb89cd..acb11f1ab 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -850,7 +850,7 @@ class YumCollection(Collection): return new @track_statistics() - def complete(self, packagelist, recommended=None): + def complete(self, packagelist, recommended=None, pinnings=None): """ Build a complete list of all packages and their dependencies. When using the Python yum libraries, this defers to the @@ -868,7 +868,8 @@ class YumCollection(Collection): resolved. """ if not self.use_yum: - return Collection.complete(self, packagelist, recommended) + return Collection.complete(self, packagelist, recommended, + pinnings) lock = FileLock(os.path.join(self.cachefile, "lock")) slept = 0 diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py index 23ccd7b8e..59a061868 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py @@ -315,6 +315,10 @@ class Packages(Bcfg2.Server.Plugin.Plugin, groups = [] recommended = dict() + pinned_src = dict() + if hasattr(metadata, 'PkgVars'): + pinned_src = metadata.PkgVars['pin'] + for struct in structures: for pkg in struct.xpath('//Package | //BoundPackage'): if pkg.get("name"): @@ -356,11 +360,11 @@ class Packages(Bcfg2.Server.Plugin.Plugin, base.update(collection.get_essential()) # check for this set of packages in the package cache - pkey = hash(tuple(base)) + pkey = hash((tuple(base), tuple(recommended), tuple(pinned_src))) pcache = Bcfg2.Server.Cache.Cache("Packages", "pkg_sets", collection.cachekey) if pkey not in pcache: - pcache[pkey] = collection.complete(base, recommended) + pcache[pkey] = collection.complete(base, recommended, pinned_src) packages, unknown = pcache[pkey] if unknown: self.logger.info("Packages: Got %d unknown entries" % len(unknown)) -- cgit v1.2.3-1-g7c22