packages_tree: exact match trumps other providers

Ubuntu frequently has multiple providers for the same package name,
e.g. "vim" is provided by "vim", "vim-gnome" etc.

Below is a sample dump of packetary's list of matches for a generic
"vim" package requirement, without a version enforced, based on
current Xenial repos:

vim-gtk3-py2 (2:7.4.1689-3ubuntu1)
vim-gnome (2:7.4.1689-3ubuntu1)
vim-gtk (2:7.4.1689-3ubuntu1)
vim-nox (2:7.4.1689-3ubuntu1)
vim-gtk-py2 (2:7.4.1689-3ubuntu1)
vim-gnome-py2 (2:7.4.1689-3ubuntu1)
vim-nox-py2 (2:7.4.1689-3ubuntu1)
vim (2:7.4.1689-3ubuntu1)
vim-gtk3 (2:7.4.1689-3ubuntu1)
vim-athena (2:7.4.1689-3ubuntu1)
vim-athena-py2 (2:7.4.1689-3ubuntu1)
vim-gtk (2:7.4.1689-3ubuntu1.2)
vim-gnome-py2 (2:7.4.1689-3ubuntu1.2)
vim-gtk-py2 (2:7.4.1689-3ubuntu1.2)
vim-nox (2:7.4.1689-3ubuntu1.2)
vim-nox-py2 (2:7.4.1689-3ubuntu1.2)
vim-gtk3 (2:7.4.1689-3ubuntu1.2)
vim (2:7.4.1689-3ubuntu1.2)
vim-athena (2:7.4.1689-3ubuntu1.2)
vim-athena-py2 (2:7.4.1689-3ubuntu1.2)
vim-gnome (2:7.4.1689-3ubuntu1.2)
vim-gtk3-py2 (2:7.4.1689-3ubuntu1.2)

Currently, packetary solves the "vim" relation by using the last item
in the sorted list, in this case "vim-gtk3-py2"; instead of using the
exact package name match "vim".

This leads to our final mirror clone missing the "vim" package, and
inherintely failing to build bootstrap/target images using only the
partial Ubuntu mirror in OPNFV ISO.

The proposed fix is to first check the list for an exact name match,
which would trump any secondary providers, even if they have a
higher package version.

Closes-bug: 1656888

Change-Id: I7279aa6526ff9133829be2e316932c9b052c7814
Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
This commit is contained in:
Alexandru Avadanii 2017-01-15 00:40:15 +01:00
parent 3021c00156
commit f0395fcd86
1 changed files with 15 additions and 14 deletions

View File

@ -57,8 +57,7 @@ class PackagesTree(object):
"""
candidates = self.find_all(name, version_range)
if len(candidates) > 0:
# we return candidates in sorted order, so let's take the highest
return candidates[-1]
return candidates[0]
return None
def find_all(self, name, version_range):
@ -68,25 +67,27 @@ class PackagesTree(object):
:param version_range: the range of versions.
:return: the list of suitable packages
"""
candidates = set()
candidates = []
if name in self.obsoletes:
candidates.extend(
self._resolve_relation(self.obsoletes[name], version_range)
)
# find package by name
if name in self.packages:
candidates.update(self.packages.find_all(name, version_range))
candidates.extend(sorted(
self.packages.find_all(name, version_range)
))
# find package by provides
# in case of rpm:
# set(candidates) >= set(provides)
if name in self.provides:
candidates.update(self._resolve_relation(
self.provides[name], version_range)
)
if name in self.obsoletes:
candidates.update(self._resolve_relation(
self.obsoletes[name], version_range)
)
return sorted(candidates, key=lambda x: x.version)
candidates.extend(sorted(
self._resolve_relation(self.provides[name], version_range)
))
return candidates
def get_unresolved_dependencies(self):
"""Gets the set of unresolved dependencies.