ZFSBootMenu Build Containers#
Introduction#
Official ZFSBootMenu release assets are built within OCI containers based on the
zbm-builder image. The image is built atop
Void Linux and provides a predictable environment without the need to install ZFSBootMenu or
its dependencies on the host system. While ZFSBootMenu is officially packaged for Void Linux and is guaranteed to work
well with the tools provided therein, the experience is not always as smooth for users of other distributions. System
packages for ZFSBootMenu or its requirements may be missing entirely. Tooling may be outdated and missing features that
ZFSBootMenu uses to provide an enhanced user experience. (Where possible, ZFSBootMenu will test for features and work
around their absence.) The zbm-builder
container image provides a means to work around the limitations of particular
distributions and provides all users with first-class ZFSBootMenu support.
The zbm-builder.sh
script provides a front-end for integrating custom ZFSBootMenu configurations into the build
container without the complexity of directly controlling the container runtime.
Users wishing to build custom ZFSBootMenu images should be familiar with the core concepts of ZFSBootMenu as outlined in
the project README. For those interested, the container README
provides more details on the operation of the ZFSBootMenu build container. However, the zbm-builder.sh
build helper provides a front-end for integrating custom ZFSBootMenu configurations into the
build container and abstracts away many of the complex details discussed in that document.
Dependencies#
To build ZFSBootMenu images from a build container, either podman or
docker is required. The development team prefers podman
, but docker
may generally be
substituted without consequence.
If a custom build container is desired, buildah and podman
are generally required. A
Dockerfile is provided for convenience, but feature parity with the buildah
script is not guaranteed. The container README provides more information about the
process of creating a custom build image.
Podman#
Install podman
and buildah
(if desired) using the package manager in your distribution:
On Void,
xbps-install podman buildah
On Arch or its derivatives,
pacman -S podman buildah
On Debian or its derivatives,
apt-get install podman buildah
It is possible to configure podman
for rootless container deployment. Consult the
tutorial for details.
Docker#
Install docker
using the package manager in your distribution:
On Void,
xbps-install docker
On Arch or its derivatives,
pacman -S docker
On Debian or its derivatives,
apt-get install docker
Non-root users that should be permitted to work with Docker images and containers should belong to the docker
groups. For example:
usermod -a -G docker zbmuser
will add zbmuser
to the docker
group on systems that provide the usermod
program.
The Build Container and Its Helper#
The zbm-builder
container is based on a Void Linux image that uses an LTS kernel and a relatively recent version of
ZFS. When run, the container entrypoint will:
Fetch a specified or default version of the ZFSBootMenu source repository (or use a local copy that is bind-mounted into the container);
Perform an "installation" of this repository into the container instance to ensure that ZFSBootMenu is usable within;
Optionally run some scripts to customize the container instance;
Merge default and build-specific ZFSBootMenu configurations; and
Produce a ZFSBootMenu image.
To facilitate interaction with the host, the container should be run with a build directory (along with an output directory, if it is not already a child of the build directory) bind-mounted into the container.
Note
Advanced users may wish to build images from a local copy of the ZFSBootMenu source tree. To make this possible,
either fetch and unpack a source tarball or clone the git repository locally. The local repository should be
bind-mounted to the /zbm
directory within the container.
The zbm-builder.sh
helper script requires nothing more than functional installations of bash
and one of
podman
or docker
. Simply download a copy of the script to a convenient directory. The helper coordinates volume
mounts necessary to read configurations from and write output to the host and ensures that the system's hostid file is
passed through. The script also supports a simple configuration file that allows options to be recorded for repeated
use.
Building a ZFSBootMenu Image#
To build a default image, invoke zbm-builder.sh
with no arguments. For example, from the directory that contains the
script, run ./zbm-builder.sh
to produce a default kernel/initramfs pair in the ./build
subdirectory.
The default behavior of zbm-builder.sh
will:
Pull the default builder image,
ghcr.io/zbm-dev/zbm-builder:latest
.If
./hostid
does not exist, copy/etc/hostid
(if it exists) to./hostid
.Spawn an ephemeral container from the builder image and run its build process:
Bind-mount the working directory into the container to expose local configurations to the builder
If
./config.yaml
exists, inform the builder to use that custom configuration instead of the defaultRun the internal build script to produce output in the
./build
subdirectory
Note
Building on hosts with SELinux enabled may require that volumes mounted by the build container be properly labeled.
This can be accomplished by specifying the argument -M z
to zbm-builder.sh
. This will persistently relabel the
build directory and, if specified, the ZFSBootMenu source directory. As an alternative to conf, it may be possible to
disable SELinux entirely by invoking zbm-builder.sh
with the argument -O --security-opt=label=disable
.
When Dracut is used to build an image under the constraints of SELinux, zbm-builder.sh
should additionally be
invoked with the argument -O --env=DRACUT_NO_XATTR=1
to prevent Dracut from setting extended attributes on
temporary files it creates within the container. Without this option, Dracut may try, but fail, to set the
security.selinux
attribute on files.
Custom ZFSBootMenu Hooks#
ZFSBootMenu supports custom hooks in several stages. When zbm-builder.sh
runs, it will
configure the subdirectory hooks
of the build directory, if it exists, as the value of zfsbootmenu_hook_root
to
allow custom hooks to be included in ZFSBootMenu images.
Fully Customizing Images#
The entrypoint for the ZFSBootMenu implements a
tiered configuration approach
that allows default configurations to be augmented or replaced with local configurations in the build directory. A
custom config.yaml
may be provided in the working directory to override the default ZFSBootMenu configuration;
configuration snippets for dracut
or mkinitcpio
can be placed in the dracut.conf.d
and mkinitcpio.conf.d
subdirectories, respectively. For mkinitcpio
configurations, a complete mkinitcpio.conf
can be placed in the
working directory to override the standard configuration.
Note
The mkinitcpio
configuration prepared by zbm-builder.sh
may include custom snippets installed in a
mkinitcpio.d
subdirectory of the build directory. The
default mkinitcpio configuration includes a loop to source these snippets.
Should you prefer to overide the default mkinitcpio.conf
in your build, any files in the mkinitcpio.d
subdirectory will need to be sourced within your custom configuration. In general, it is better to leave the default
mkinitcpio.conf
and store all custom configurations in the mkinitcpio.d
subdirectory.
The build container runs its build script from the working directory on the host. In general, relative paths in custom
configuration files are generally acceptable and refer to locations relative to the build directory. If absolute paths
are preferred or required for some configurations, note that the build directory will be mounted as /build
in the
container.
The internal build script always overrides the output paths for ZFSBootMenu components and UEFI executables to
ensure that the images will reside in a specified output directory (or, by default, a build
subdirectory of build
directory) upon completion. Relative paths are primarily useful for specifying local dracut
or mkinitcpio
configuration paths.
More advanced users may wish to alter the build process itself. Some control over the build process is exposed through
command-line options that are described in the output of zbm-builder.sh -h
.
Before adjusting these command-line options, seek a thorough understanding of the
image build process and the command sequence of zbm-builder.sh
itself.