Arch Linux Meta Packages

Posted on Mar 15, 2020

Meta packages can help to automate installation and configuration tasks. They are created like normal packages, but their main purpose is to depend on other packages to facilitate the installation of these dependencies. In this post we describe in detail how they can be used.

What Meta Packages Can Be Used For

The Arch Linux wiki1 and this blog post2 describe the usage of meta packages very well, in this post we focus on some additional aspects.

With respect to installation automation, meta packages can be used for different purposes. These are in particular …

  1. Installation of packages
  2. Configuration of packages
  3. Enablement of services

Since meta packages are also packages, they support the same functionality that normal packages offer. In particular, they can execute logic/commands during installation, upgrade and removal. These capabilities can be utilized for tasks that go beyond mere installation of dependencies.

Installation of Packages

As already mentioned, the main purpose of meta packages is to depend on other packages. The installation of a meta package triggers the installation of these dependencies. You could create a meta package that depends on all the software packages that you would like to have installed in an Arch Linux system, for example. pacman -Syu <name-of-meta-package> would then trigger the installation of all the software packages that the meta package depends on.

Meta packages can depend on other meta packages. Thus, one could create a hierarchy of meta packages like in the example below:

base-meta-pkg
  |
  |- desktop-meta-pkg
  |
  |- laptop-meta-pkg
  |
  ...

In this example, there’s a meta package for each of the different machine types that Arch Linux is intended to be installed upon (desktop, laptop etc.). They all depend on a base meta package. That package in turn depends on the software packages that all machines need. The specialized meta packages for desktop, laptop etc. only depend on (besides the base meta package) software packages that are specific for the installation on a desktop or laptop.

Configuration of Packages

In addition to their installation, packages often require configuration. This can be automated with meta packages as well.

Creating New Configuration files

For some type of packages, their configuration files need to be stored in a certain directory, and it’s not necessary to overwrite or change existing (default) files. An example is sudo, where configuration files can be dropped into the directory /etc/sudoers.d. A proper approach for these packages is to make the corresponding configuration files part of the meta package and add an install line to the PKGBUILD file, see an example in Archi3 Linux.

Changing Existing Configuration Files

If existing (default) configuration files need to be changed or overwritten, the configuration management tool holo3 can do the job. It uses alpm hooks to manage configuration files. In a nutshell, the following steps are necessary to change or overwrite an existing configuration files with holo:

  1. The meta package must depend on the holo AUR package. That means the holo AUR package must be installed - see the specific approach for meta packages depending on AUR packages later in this post.

  2. If an existing configuration file shall be overwritten, the PKGBUILD file of the corresponding meta package must contain a statement to copy the new file to the directory

    "${pkgdir}"/usr/share/holo/files/<some-custom-identifier>/<name-of-config-file>

    If for example the ntp configuration /etc/ntp.conf shall be overwritten, the statement

    install -Dm0644 mipi-base.ntp.conf "${pkgdir}"/usr/share/holo/files/20-ntp/etc/ntp.conf

    does the job.

  3. If an existing configuration file shall be adjusted or changed, create a script with the name <name-of-config-file>.holoscript and copy it to the directory

    "${pkgdir}"/usr/share/holo/files/<some-custom-identifier>/<name-of-config-file>

    If for example the ntp configuration /etc/ntp.conf shall be changed, the statement

    install -Dm0750 mipi-base.ntp.conf.holoscript "${pkgdir}"/usr/share/holo/files/20-ntp/etc/ntp.conf.holoscript

    does the job.

  4. holo apply must be executed in the post_install(), post_upgrade() and post_remove() hooks of PKGBUILD.

holo then makes the required changes (either file overwrite or change) during the installation of the meta package (see the holo documentation).

Enablement of Services

Another task that must be performed often when software packages have been installed is the enablement of services.

Arch Linux by default disables all services of a package when it’s installed. Therefore, the required services need to be enabled explicitly. It is an obvious idea, to put a statement like

systemctl enable <name-of-service>

in one of the hooks of PKGBUILD and let the package installation process execute the enablement of the service. But this does not work as the process stops with an error:

System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down

See the discussion in the Arch Linux forum.

Luckily, there is a nice feature in systemd that allows to preset service enablements (see the man pages of systemd). In a nutshell, to enable a specific service, an enablement statement needs to be put into a certain configuration file of systemd during installation time (e.g. via some logic in a PKGBUILD hook). This configuration is interpreted, and during the next boot, the corresponding service enablements are done. That’s exactly what is needed here. See an example in Archi3 Linux:

  1. The file systemd.preset contains the presets for the meta package.

  2. It is copied to the system-preset directory of systemd by a statement in the PKGBUILD file:

    install -Dm0644 systemd.preset "$pkgdir"/usr/lib/systemd/system-preset/10-archi3-base.preset

  3. The statement systemctl preset-all is put into the post_install() and the post_upgrade() hook. It triggers the interpretation on the preset configuration. If systemctl preset-all is not executed, the new preset configuration is not read, that means the services will not be enabled.

Custom Repositories

Meta packages need to be stored in and provided by a repository. We suggest to create a custom local repository for this purpos.

The following describes how to create such a repository using an FTP server:

  1. Set up an FTP server in your local network and allow anonymous access to it
  2. To store the new repository, create a new folder (e.g. my-repo and a sub folder for the architecture, e.g. x86_64)
  3. Enable SSH access to these folders. It is recommended to enable authentification via public key since this is more convenient for updating the repository later.

To make the new repository known to pacman, add the following to your /etc/pacman.conf:

[<repo name>]
SigLevel = Optional TrustAll
Server = ftp://my-repo

repman4, the Repository Manager, can helps to manage such a custom repository.

Building Meta Packages

For the management of a meta package we suggest to create a dedicated directory that contains

  • The PKGBUILD file
  • Other relevant files such as configuration files and scripts

repman can be used to build the meta package(s).

AUR Packages

The installation of AUR packages need some more attention.

In contrast to packages that are provided by the official Arch Linux repositories, it is not sufficient to only let a meta package depend on an AUR package to trigger its installation. The pacstrap command, which is executed during the Arch Linux installation process, would throw an error:

could not resolve dependencies

See the discussion in the Arch Linux Forum.

A solution approach is to add the AUR package to the custom repository. Then, the meta package can depend on it without getting an error during the installation process. Also here, repman can help. As a side effect, you can install, remove or update AUR packages from your custom repository with the pacman command.

References

comments powered by Disqus
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License