Blob Blame History Raw
From b41f086d40bd0703f1776589dd4ea5579d0fd520 Mon Sep 17 00:00:00 2001
Message-Id: <b41f086d40bd0703f1776589dd4ea5579d0fd520@dist-git>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 6 Sep 2019 18:06:08 +0200
Subject: [PATCH] osdict: Always return the most generic tree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

From: Fabiano FidĂȘncio <fidencio@redhat.com>

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>
(cherry picked from commit 0f1acc9f8f392eaf5edd30ce239728afd1f924cf)
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
 tests/osdict.py    |  4 ++++
 virtinst/osdict.py | 39 ++++++++++++++++++++++++++++++++++-----
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/tests/osdict.py b/tests/osdict.py
index eb0d4f86..9fb477bd 100644
--- a/tests/osdict.py
+++ b/tests/osdict.py
@@ -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")
diff --git a/virtinst/osdict.py b/virtinst/osdict.py
index 64d8bdb8..a53e4249 100644
--- a/virtinst/osdict.py
+++ b/virtinst/osdict.py
@@ -592,8 +592,36 @@ class _OsVariant(object):
 
         return "inst.repo"
 
+    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):
+    def get_location(self, arch, profile=None):
         treelist = []
         if self._os:
             treelist = list(_OsinfoIter(self._os.get_tree_list()))
@@ -605,10 +633,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") %
-- 
2.23.0