From 7e0a288f5b50e8a1944830a04e72bd226c0d39e5 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 11 Oct 2018 11:10:33 -0700 Subject: [PATCH] Update depsolving with suggestions from dnf (#1636239) The previous method worked, but wasn't exactly idiomatic. This is more correct, and appears to work the same (templates depsolve, version globs work, multiple repos work). Note that this does use a private dnf attribute ._goal, but the word is that this is going to become a public api soon, so yes it is there on purpose. --- src/pylorax/api/projects.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pylorax/api/projects.py b/src/pylorax/api/projects.py index 2072be41..98bbe642 100644 --- a/src/pylorax/api/projects.py +++ b/src/pylorax/api/projects.py @@ -207,23 +207,25 @@ def _depsolve(dbo, projects, groups): install_errors.append(("Group %s" % (name), str(e))) for name, version in projects: - try: - if not version: - version = "*" - # Find the best package matching the name + version glob - # dnf can return multiple packages if it is in more than 1 repository, so use max() to select one of them - pkg = max([pkg for pkg in dnf.subject.Subject(name).get_best_query(dbo.sack).filter(version__glob=version, latest=True)] or [None]) - if not pkg: - install_errors.append(("%s-%s" % (name, version), "No match")) - continue - dbo.package_install(pkg) - except dnf.exceptions.MarkingError as e: - install_errors.append(("%s-%s" % (name, version), str(e))) + # Find the best package matching the name + version glob + # dnf can return multiple packages if it is in more than 1 repository + query = dbo.sack.query().filterm(provides__glob=name) + if version: + query.filterm(version__glob=version) + + query.filterm(latest=1) + if not query: + install_errors.append(("%s-%s" % (name, version), "No match")) + continue + sltr = dnf.selector.Selector(dbo.sack).set(pkg=query) + + # NOTE: dnf says in near future there will be a "goal" attribute of Base class + # so yes, we're using a 'private' attribute here on purpose and with permission. + dbo._goal.install(select=sltr, optional=False) if install_errors: raise ProjectsError("The following package(s) had problems: %s" % ",".join(["%s (%s)" % (pattern, err) for pattern, err in install_errors])) - def projects_depsolve(dbo, projects, groups): """Return the dependencies for a list of projects