diff options
Diffstat (limited to 'src/sbin/bcfg2-yum-helper')
-rwxr-xr-x | src/sbin/bcfg2-yum-helper | 118 |
1 files changed, 79 insertions, 39 deletions
diff --git a/src/sbin/bcfg2-yum-helper b/src/sbin/bcfg2-yum-helper index 94836d748..2da7c6336 100755 --- a/src/sbin/bcfg2-yum-helper +++ b/src/sbin/bcfg2-yum-helper @@ -5,8 +5,6 @@ the right way to get around that in long-running processes it to have a short-lived helper. No, seriously -- check out the yum-updatesd code. It's pure madness. """ -__revision__ = '$Revision$' - import os import sys import yum @@ -19,7 +17,26 @@ try: except ImportError: import simplejson as json -logger = logging.getLogger('bcfg2-yum-helper') +LOGGER = None + +def get_logger(verbose=0): + """ set up logging according to the verbose level given on the + command line """ + global LOGGER + if LOGGER is None: + LOGGER = logging.getLogger(sys.argv[0]) + stderr = logging.StreamHandler() + if verbose: + level = logging.DEBUG + else: + level = logging.WARNING + LOGGER.setLevel(level) + LOGGER.addHandler(stderr) + syslog = logging.handlers.SysLogHandler("/dev/log") + syslog.setFormatter(logging.Formatter("%(name)s: %(message)s")) + LOGGER.addHandler(syslog) + return LOGGER + class DepSolver(object): def __init__(self, cfgfile, verbose=1): @@ -28,8 +45,10 @@ class DepSolver(object): try: self.yumbase.preconf.debuglevel = verbose self.yumbase.preconf.fn = cfgfile + self.yumbase._getConfig() except AttributeError: self.yumbase._getConfig(cfgfile, debuglevel=verbose) + self.logger = get_logger(verbose) def get_groups(self): try: @@ -38,7 +57,7 @@ class DepSolver(object): return ["noarch"] def set_groups(self, groups): - self._groups = set(groups).add("noarch") + self._groups = set(groups).union(["noarch"]) groups = property(get_groups, set_groups) @@ -59,13 +78,13 @@ class DepSolver(object): matches = self.yumbase.pkgSack.returnNewestByName(name=package) except yum.Errors.PackageSackError: if not silent: - logger.warning("Packages: Package '%s' not found" % - self.get_package_name(package)) + self.logger.warning("Package '%s' not found" % + self.get_package_name(package)) matches = [] except yum.Errors.RepoError: err = sys.exc_info()[1] - logger.error("Packages: Temporary failure loading metadata for " - "'%s': %s" % (self.get_package_name(package), err)) + self.logger.error("Temporary failure loading metadata for %s: %s" % + (self.get_package_name(package), err)) matches = [] pkgs = self._filter_arch(matches) @@ -83,8 +102,8 @@ class DepSolver(object): deps.difference_update([dep for dep in deps if pkg.checkPrco('provides', dep)]) else: - logger.error("Packages: No package available: %s" % - self.get_package_name(package)) + self.logger.error("No package available: %s" % + self.get_package_name(package)) return deps def get_provides(self, required, all=False, silent=False): @@ -96,16 +115,15 @@ class DepSolver(object): self.yumbase.whatProvides(*required).returnNewestByNameArch() except yum.Errors.NoMoreMirrorsRepoError: err = sys.exc_info()[1] - logger.error("Packages: Temporary failure loading metadata for " - "'%s': %s" % - (self.get_package_name(required), err)) + self.logger.error("Temporary failure loading metadata for %s: %s" % + (self.get_package_name(required), err)) return [] if prov and not all: prov = self._filter_provides(required, prov) elif not prov and not silent: - logger.error("Packages: No package provides %s" % - self.get_package_name(required)) + self.logger.error("No package provides %s" % + self.get_package_name(required)) return prov def get_group(self, group, ptype="default"): @@ -116,11 +134,11 @@ class DepSolver(object): if self.yumbase.comps.has_group(group): group = self.yumbase.comps.return_group(group) else: - logger.warning("Packages: '%s' is not a valid group" % group) + self.logger.warning("%s is not a valid group" % group) return [] except yum.Errors.GroupsError: err = sys.exc_info()[1] - logger.warning("Packages: %s" % err) + self.logger.warning(err) return [] if ptype == "default": @@ -134,7 +152,7 @@ class DepSolver(object): elif ptype == "optional" or ptype == "all": return group.packages else: - logger.warning("Unknown group package type '%s'" % ptype) + self.logger.warning("Unknown group package type '%s'" % ptype) return [] def _filter_provides(self, package, providers): @@ -156,14 +174,24 @@ class DepSolver(object): # provider of perl(lib). rv = [] for pkg in providers: - if self.get_package_object(pkg.name) == pkg: + found = self.get_package_object(pkg.name) + if found == pkg or found.pkgtup == pkg.pkgtup: rv.append(pkg) + else: + self.logger.debug("Skipping %s, not newest (%s)" % + (pkg, found)) else: rv = providers return [p.name for p in rv] def _filter_arch(self, packages): - matching = [pkg for pkg in packages if pkg.arch in self.groups] + matching = [] + for pkg in packages: + if pkg.arch in self.groups: + matching.append(pkg) + else: + self.logger.debug("%s has non-matching architecture (%s)" % + (pkg, pkg.arch)) if matching: return matching else: @@ -180,10 +208,7 @@ class DepSolver(object): else: return str(package) - def complete(self, packagelist, groups=None): - if groups is None: - groups = [] - + def complete(self, packagelist): packages = set() pkgs = set(packagelist) requires = set() @@ -202,12 +227,17 @@ class DepSolver(object): if not self.is_package(package): # try this package out as a requirement + self.logger.debug("Adding requirement %s" % package) requires.add((package, None, (None, None, None))) continue packages.add(package) reqs = set(self.get_deps(package)).difference(satisfied) if reqs: + self.logger.debug("Adding requirements for %s: %s" % + (package, + ",".join([self.get_package_name(r) + for r in reqs]))) requires.update(reqs) reqs_satisfied = set() @@ -222,8 +252,8 @@ class DepSolver(object): reqs_satisfied.add(req) continue - logger.debug("Packages: Handling requirement '%s'" % - self.get_package_name(req)) + self.logger.debug("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 @@ -237,16 +267,24 @@ class DepSolver(object): if len(best) == 1: providers = best elif not final_pass: - # found no "best" package, so defer + self.logger.debug("%s has multiple providers: %s" % + (self.get_package_name(req), + providers)) + self.logger.debug("No provider is obviously the " + "best; deferring") providers = None - # else: found no "best" package, but it's the - # final pass, so include them all + else: + # found no "best" package, but it's the + # final pass, so include them all + self.logger.debug("Found multiple providers for %s," + "including all" % + self.get_package_name(req)) if providers: - logger.debug("Packages: Requirement '%s' satisfied by %s" % - (self.get_package_name(req), - ",".join([self.get_package_name(p) - for p in providers]))) + self.logger.debug("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: @@ -257,6 +295,8 @@ class DepSolver(object): reqs_satisfied.add(req) elif providers is not None: # nothing provided this requirement at all + self.logger.debug("Nothing provides %s" % + self.get_package_name(req)) unknown.add(req) reqs_satisfied.add(req) # else, defer @@ -283,7 +323,7 @@ class DepSolver(object): # many files were deleted. so useful. thanks, yum. msg = getattr(self.yumbase, "clean%s" % mdtype)()[1][0] if not msg.startswith("0 "): - logger.info("Packages: %s" % msg) + self.logger.info(msg) def main(): @@ -291,15 +331,15 @@ def main(): parser.add_option("-c", "--config", help="Config file") parser.add_option("-v", "--verbose", help="Verbosity level", action="count") (options, args) = parser.parse_args() + logger = get_logger(options.verbose) try: cmd = args[0] except IndexError: - logger.error("bcfg2-yum-helper: No command given") + logger.error("No command given") return 1 if not os.path.exists(options.config): - logger.error("bcfg2-yum-helper: Config file %s not found" % - options.config) + logger.error("Config file %s not found" % options.config) return 1 depsolver = DepSolver(options.config, options.verbose) @@ -308,8 +348,8 @@ def main(): print json.dumps(True) elif cmd == "complete": data = json.loads(sys.stdin.read()) - (packages, unknown) = depsolver.complete(data['packages'], - groups=data['groups']) + depsolver.groups = data['groups'] + (packages, unknown) = depsolver.complete(data['packages']) print json.dumps(dict(packages=list(packages), unknown=list(unknown))) elif cmd == "is_virtual_package": |