Rethinking how we make ready-to-use operating system images.

installpkg with version check

Lorax version 36.1 added a new feature to the template’s installpkg command. This was brought about by a change to grub2 where the latest version installs the unicode.pf2 file to a different path than what is expected by the Lorax templates. This ended up causing a bit of a mess because some of the tests depend on building a new boot.iso but the new boot.iso cannot be built until the templates have been fixed to use the new path. The error wasn’t completely obvious, and wouldn’t happen until after running through most of the boot.iso build.

First a bit of background for those not familiar with how Lorax works. Lorax builds the boot.iso by parsing a set of templates that define what packages to install, what files (and packages) to remove, and what to customize to make the iso bootable. These templates use dnf to install the packages, but the only dependency they had was on package names. There was no way to express version requirements in the runtime-install.tmpl template.

Usually you don’t want to include version requirements in Lorax templates, that would just make it more difficult to keep up to date with the package changes. But in the case where you have a template that depends on a specific package version’s behavior – or change in behavior – it would be useful for the boot.iso build to fail early and with a clear error message.

At first I was thinking about adding a whole new command, but that would have required duplicating most of the code in installpkg, and I’d already reluctantly done that for the live-install template support, I wanted something cleaner. What I ended up doing was extending the existing PKGGLOB that is passed to the installpkg command to include a version compare by declaring that no spaces are allowed. I also moved all the common code into a MixIn so that solved the existing code duplication problem.

The documentation for the installpkg command is now:

installpkg [--required|--optional] [--except PKGGLOB [--except PKGGLOB ...]] PKGGLOB [PKGGLOB ...]
Request installation of all packages matching the given globs.
Note that this is just a *request* - nothing is *actually* installed
until the 'run_pkg_transaction' command is given.

The non-except PKGGLOB can contain a version comparison. This should
not be used as a substitute for package dependencies, it should be
used to enforce installation of tools required by the templates. eg.
grub2 changed the font location in 2.06-2 so the current templates
require grub2 to be 2.06-2 or later.

installpkg tmux>=2.8 bash=5.0.0-1

It supports the =,!=,>,>=,<,<= operators. == is an alias for =, and
<> is an alias for !=

There should be no spaces between the package name, the compare
operator, and the version.

NOTE: When testing for equality you must include the version AND
release, otherwise it won't match anything.

--required is now the default. If the PKGGLOB can be missing pass --optional

And in the runtime-install.tmpl there is now a variable for the grub2 version that is used for all of the grub2 related installpkg commands:

installpkg grub2-tools-efi>=${GRUB2VER}

Hopefully this will not be needed very often, but at least now there is a mechanism to express required versions that will fail early. The error message looks similar to this:

17:53:09,697 DEBUG pylorax.ltmpl: template line 10: installpkg grub2-tools-efi>=1:2.99-1
17:53:09,698 ERROR pylorax.ltmpl: installpkg grub2-tools-efi>=1:2.99-1 failed: no package matched: grub2-tools-efi>=1:2.99-1
17:53:09,698 ERROR pylorax.ltmpl: template command error in runtime-install.tmpl:
17:53:09,698 ERROR pylorax.ltmpl:   installpkg grub2-tools-efi>=1:2.99-1
17:53:09,700 ERROR pylorax.ltmpl:   Exception: Required installpkg failed.
17:53:09,700 DEBUG pylorax.ltmpl:   Traceback (most recent call last):
17:53:09,700 DEBUG pylorax.ltmpl:     File "/root/lorax/src/pylorax/ltmpl.py", line 326, in installpkg
17:53:09,700 DEBUG pylorax.ltmpl:       raise Exception("Required installpkg failed.")
17:53:09,700 DEBUG pylorax.ltmpl:   Exception: Required installpkg failed.

It fails after downloading the repo metadata, and before installing packages or making the squashfs of the root filesystem, speeding up debugging and making it easier to determine what is wrong.

Written by Brian Lane on December 10, 2021