From 6e57bfe11d2d790d1187ce655337c46af72ed1b6 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 25 Oct 2018 11:15:03 -0700 Subject: [PATCH] lorax: Fix dnf problems with selecting highest NEVRA from multiple repos When using package name globs and multiple repos dnf doesn't choose the highest NEVRA as you would expect, work around this by applying max() to the duplicate package names in installpkg. Resolves: rhbz#1548586 --- src/pylorax/ltmpl.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/pylorax/ltmpl.py b/src/pylorax/ltmpl.py index 71d4b2cb..44e345d8 100644 --- a/src/pylorax/ltmpl.py +++ b/src/pylorax/ltmpl.py @@ -534,7 +534,7 @@ class LoraxTemplateRunner(object): pkgs = pkgs[:idx] + pkgs[idx+2:] errors = False - for p in pkgs: + for pkg in pkgs: try: # Start by using Subject to generate a package query, which will # give us a query object similar to what dbo.install would select, @@ -547,20 +547,27 @@ class LoraxTemplateRunner(object): # dnf queries don't have a concept of negative globs which is why # the filtering is done the hard way. - pkgnames = [pkg for pkg in dnf.subject.Subject(p).get_best_query(self.dbo.sack).filter(latest=True)] + pkgnames = [p for p in dnf.subject.Subject(pkg).get_best_query(self.dbo.sack).filter(latest=True)] if not pkgnames: - raise dnf.exceptions.PackageNotFoundError("no package matched", p) + raise dnf.exceptions.PackageNotFoundError("no package matched", pkg) # Apply excludes to the name only for exclude in excludes: - pkgnames = [pkg for pkg in pkgnames if not fnmatch.fnmatch(pkg.name, exclude)] + pkgnames = [p for p in pkgnames if not fnmatch.fnmatch(p.name, exclude)] + + # dnf doesn't handle globs and multiple repos correctly, we need to find the highest nvr for each unique + # package name and install those. Except that we also support version pinning but in that case it + # won't be a glob so this should work. + d = {} + for p in pkgnames: + d[p.name] = max(p, d.get(p.name, p)) # Convert to a sorted NVR list for installation - pkgnvrs = sorted(["{}-{}-{}".format(pkg.name, pkg.version, pkg.release) for pkg in pkgnames]) + pkgnvrs = sorted(["{}-{}-{}".format(p.name, p.version, p.release) for p in d.values()]) # If the request is a glob, expand it in the log - if any(g for g in ['*','?','.'] if g in p): - logger.info("installpkg: %s expands to %s", p, ",".join(pkgnvrs)) + if any(g for g in ['*','?','.'] if g in pkg): + logger.info("installpkg: %s expands to %s", pkg, ",".join(pkgnvrs)) for pkgnvr in pkgnvrs: try: @@ -571,7 +578,7 @@ class LoraxTemplateRunner(object): # Not required, log it and continue processing pkgs logger.error("installpkg %s failed: %s", pkgnvr, str(e)) except Exception as e: # pylint: disable=broad-except - logger.error("installpkg %s failed: %s", p, str(e)) + logger.error("installpkg %s failed: %s", pkg, str(e)) errors = True if errors and required: