From 980e628835f86563ab79840bf829cf1b667e175a Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Mon, 3 May 2021 11:18:12 -0700 Subject: [PATCH] treebuilder: Add branding package to template variables The branding package name doesn't always match the product name. This saves the branding package names as discovered in the enabled repos and exposes it to the templates as branding.release and branding.logos -- which could potentially be None so the template needs to take that into account. Related: rhbz#1956205 --- src/pylorax/creator.py | 2 +- src/pylorax/treebuilder.py | 45 +++++++++++++++++------------ tests/pylorax/test_treebuilder.py | 47 ++++++++++++++++--------------- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/pylorax/creator.py b/src/pylorax/creator.py index 9ed3d4b5..73f5f1ba 100644 --- a/src/pylorax/creator.py +++ b/src/pylorax/creator.py @@ -218,7 +218,7 @@ def make_runtime(opts, mount_dir, work_dir, size=None): product = DataHolder(name=opts.project, version=opts.releasever, release="", variant="", bugurl="", isfinal=False) - rb = RuntimeBuilder(product, arch, fake_dbo) + rb = RuntimeBuilder(product, arch, fake_dbo, skip_branding=True) compression, compressargs = squashfs_args(opts) if opts.squashfs_only: diff --git a/src/pylorax/treebuilder.py b/src/pylorax/treebuilder.py index 42c598d6..d57370d3 100644 --- a/src/pylorax/treebuilder.py +++ b/src/pylorax/treebuilder.py @@ -74,11 +74,6 @@ class RuntimeBuilder(object): add_template_vars=None, skip_branding=False): root = dbo.conf.installroot - # use a copy of product so we can modify it locally - product = product.copy() - product.name = product.name.lower() - self.vars = DataHolder(arch=arch, product=product, dbo=dbo, root=root, - basearch=arch.basearch, libdir=arch.libdir) self.dbo = dbo self._runner = LoraxTemplateRunner(inroot=root, outroot=root, dbo=dbo, templatedir=templatedir) @@ -86,20 +81,29 @@ class RuntimeBuilder(object): self.add_template_vars = add_template_vars or {} self._installpkgs = installpkgs or [] self._excludepkgs = excludepkgs or [] - self._runner.defaults = self.vars self.dbo.reset() - self._skip_branding = skip_branding - def _install_branding(self): + # use a copy of product so we can modify it locally + product = product.copy() + product.name = product.name.lower() + self._branding = self.get_branding(skip_branding, product) + self.vars = DataHolder(arch=arch, product=product, dbo=dbo, root=root, + basearch=arch.basearch, libdir=arch.libdir, + branding=self._branding) + self._runner.defaults = self.vars + + def get_branding(self, skip, product): """Select the branding from the available 'system-release' packages The *best* way to control this is to have a single package in the repo provide 'system-release' When there are more than 1 package it will: - Make a list of the available packages - If variant is set look for a package ending with lower(variant) and use that - If there are one or more non-generic packages, use the first one after sorting + + Returns the package names of the system-release and release logos package """ - if self._skip_branding: - return + if skip: + return DataHolder(release=None, logos=None) release = None q = self.dbo.sack.query() @@ -108,11 +112,11 @@ class RuntimeBuilder(object): if not p.name.startswith("generic")]) if not pkgs: logger.error("No system-release packages found, could not get the release") - return + return DataHolder(release=None, logos=None) logger.debug("system-release packages: %s", pkgs) - if self.vars.product.variant: - variant = [p for p in pkgs if p.endswith("-"+self.vars.product.variant.lower())] + if product.variant: + variant = [p for p in pkgs if p.endswith("-"+product.variant.lower())] if variant: release = variant[0] if not release: @@ -120,20 +124,25 @@ class RuntimeBuilder(object): # release logger.info('got release: %s', release) - self._runner.installpkg(release) - # logos - release, _suffix = release.split('-', 1) - self._runner.installpkg('%s-logos' % release) + # logos uses the basename from release (fedora, redhat, centos, ...) + logos, _suffix = release.split('-', 1) + return DataHolder(release=release, logos=logos+"-logos") def install(self): '''Install packages and do initial setup with runtime-install.tmpl''' - self._install_branding() + if self._branding.release: + self._runner.installpkg(self._branding.release) + if self._branding.logos: + self._runner.installpkg(self._branding.logos) + if len(self._installpkgs) > 0: self._runner.installpkg(*self._installpkgs) if len(self._excludepkgs) > 0: self._runner.removepkg(*self._excludepkgs) + self._runner.run("runtime-install.tmpl") + for tmpl in self.add_templates: self._runner.run(tmpl, **self.add_template_vars) diff --git a/tests/pylorax/test_treebuilder.py b/tests/pylorax/test_treebuilder.py index 710773df..833fcbfb 100644 --- a/tests/pylorax/test_treebuilder.py +++ b/tests/pylorax/test_treebuilder.py @@ -63,7 +63,7 @@ def makeFakeRPM(repo_dir, name, epoch, version, release, files=None, provides=No class InstallBrandingTestCase(unittest.TestCase): def install_branding(self, repo_dir, variant=None, skip_branding=False): - """Run the _install_branding and return the names of the installed packages""" + """Run the get_branding function in a test repo""" with tempfile.TemporaryDirectory(prefix="lorax.test.") as root_dir: dbo = get_dnf_base_object(root_dir, ["file://"+repo_dir], enablerepos=[], disablerepos=[]) self.assertTrue(dbo is not None) @@ -72,11 +72,7 @@ class InstallBrandingTestCase(unittest.TestCase): variant=variant, bugurl="http://none", isfinal=True) arch = ArchData(os.uname().machine) rb = RuntimeBuilder(product, arch, dbo, skip_branding=skip_branding) - rb._install_branding() - dbo.resolve() - self.assertTrue(dbo.transaction is not None) - - return sorted(p.name for p in dbo.transaction.install_set) + return rb._branding def test_no_pkgs(self): """Test with a repo with no system-release packages""" @@ -85,8 +81,9 @@ class InstallBrandingTestCase(unittest.TestCase): makeFakeRPM(repo_dir, "fake-milhouse", 0, "1.0.0", "1") os.system("createrepo_c " + repo_dir) - pkgs = self.install_branding(repo_dir) - self.assertEqual(pkgs, []) + branding = self.install_branding(repo_dir) + self.assertEqual(branding.release, None) + self.assertEqual(branding.logos, None) def test_generic_pkg(self): """Test with a repo with only a generic-release package""" @@ -95,8 +92,9 @@ class InstallBrandingTestCase(unittest.TestCase): makeFakeRPM(repo_dir, "generic-release", 0, "33", "1", ["/etc/system-release"], ["system-release"]) os.system("createrepo_c " + repo_dir) - pkgs = self.install_branding(repo_dir) - self.assertEqual(pkgs, []) + branding = self.install_branding(repo_dir) + self.assertEqual(branding.release, None) + self.assertEqual(branding.logos, None) def test_two_pkgs(self): """Test with a repo with generic-release, and a fedora-release package""" @@ -107,12 +105,14 @@ class InstallBrandingTestCase(unittest.TestCase): makeFakeRPM(repo_dir, "fedora-logos", 0, "33", "1") os.system("createrepo_c " + repo_dir) - pkgs = self.install_branding(repo_dir) - self.assertEqual(pkgs, ["fedora-logos", "fedora-release"]) + branding = self.install_branding(repo_dir) + self.assertEqual(branding.release, "fedora-release") + self.assertEqual(branding.logos, "fedora-logos") # Test with a variant set, but not available - pkgs = self.install_branding(repo_dir, variant="workstation") - self.assertEqual(pkgs, ["fedora-logos", "fedora-release"]) + branding = self.install_branding(repo_dir, variant="workstation") + self.assertEqual(branding.release, "fedora-release") + self.assertEqual(branding.logos, "fedora-logos") def test_three_pkgs(self): """Test with a repo with generic-release, fedora-release, fedora-release-workstation package""" @@ -124,16 +124,18 @@ class InstallBrandingTestCase(unittest.TestCase): makeFakeRPM(repo_dir, "fedora-release-workstation", 0, "33", "1", ["/etc/system-release"], ["system-release"]) os.system("createrepo_c " + repo_dir) - pkgs = self.install_branding(repo_dir) - self.assertEqual(pkgs, ["fedora-logos", "fedora-release"]) + branding = self.install_branding(repo_dir) + self.assertEqual(branding.release, "fedora-release") + self.assertEqual(branding.logos, "fedora-logos") # Test with a variant set - pkgs = self.install_branding(repo_dir, variant="workstation") - self.assertEqual(pkgs, ["fedora-logos", "fedora-release-workstation"]) + branding = self.install_branding(repo_dir, variant="workstation") + self.assertEqual(branding.release, "fedora-release-workstation") + self.assertEqual(branding.logos, "fedora-logos") # Test with a variant set, but not available - pkgs = self.install_branding(repo_dir, variant="server") - self.assertEqual(pkgs, ["fedora-logos", "fedora-release"]) + branding = self.install_branding(repo_dir, variant="server") + self.assertEqual(branding.release, "fedora-release") def test_skip_branding(self): """Test disabled branding""" @@ -142,5 +144,6 @@ class InstallBrandingTestCase(unittest.TestCase): makeFakeRPM(repo_dir, "fedora-logos", 0, "33", "1") os.system("createrepo_c " + repo_dir) - pkgs = self.install_branding(repo_dir, skip_branding=True) - self.assertEqual(pkgs, []) + branding = self.install_branding(repo_dir, skip_branding=True) + self.assertEqual(branding.release, None) + self.assertEqual(branding.logos, None)