osdict: Always return the most generic tree

Some OSes, as Fedora, have variants (which we rely to be standardised on
osinfo-db side), which we can use to return the most generic tree
possible, in case no profile is specified, in order to avoid failing to
install a "Workstation" system because a "Server" variant tree was used.

https://bugzilla.redhat.com/show_bug.cgi?id=1749865

Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
This commit is contained in:
Fabiano Fidêncio 2019-09-06 18:06:08 +02:00 committed by Cole Robinson
parent 0eb571f9e1
commit 0f1acc9f8f
2 changed files with 39 additions and 5 deletions

View File

@ -52,11 +52,15 @@ class TestOSDB(unittest.TestCase):
def test_tree_url(self):
f26 = OSDB.lookup_os("fedora26")
f29 = OSDB.lookup_os("fedora29")
winxp = OSDB.lookup_os("winxp")
# Valid tree URL
assert "fedoraproject.org" in f26.get_location("x86_64")
# Most generic tree URL
assert "Everything" in f29.get_location("x86_64")
# Has tree URLs, but none for arch
try:
f26.get_location("ia64")

View File

@ -620,7 +620,36 @@ class _OsVariant(object):
return "inst.repo"
def get_location(self, arch):
def _get_generic_location(self, treelist, arch, profile):
if not hasattr(Libosinfo.Tree, "get_os_variants"):
for tree in treelist:
if tree.get_architecture() == arch:
return tree.get_url()
return None
fallback_tree = None
if not profile:
profile = "Everything"
for tree in treelist:
if tree.get_architecture() != arch:
continue
variant_list = tree.get_os_variants()
if variant_list.get_length() == 0:
return tree.get_url()
fallback_tree = tree
for i in range(variant_list.get_length()):
variant = variant_list.get_nth(i)
if profile in variant.get_name():
return tree.get_url()
if fallback_tree:
return fallback_tree.get_url()
return None
def get_location(self, arch, profile=None):
treelist = []
if self._os:
treelist = list(_OsinfoIter(self._os.get_tree_list()))
@ -632,10 +661,11 @@ class _OsVariant(object):
# Some distros have more than one URL for a specific architecture,
# which is the case for Fedora and different variants (Server,
# Workstation). Later on, we'll have to differentiate that and return
# the right one.
for tree in treelist:
if tree.get_architecture() == arch:
return tree.get_url()
# the right one. However, for now, let's just rely on returning the
# most generic tree possible.
location = self._get_generic_location(treelist, arch, profile)
if location:
return location
raise RuntimeError(
_("OS '%s' does not have a URL location for the %s architecture") %