System extension images may – dynamically at runtime — extend the base system with an overlay containing additional files.
To build system extensions with mkosi, we first have to create a base image on top of which we can build our extension.
To keep things manageable, we’ll use mkosi’s support for building multiple images so that we can build our base image and system extension in one go.
Start by creating a temporary directory with a base configuration file
mkosi.conf
with some shared settings:
[Output]
OutputDirectory=mkosi.output
CacheDirectory=mkosi.cache
From now on we’ll assume all steps are executed inside the temporary directory.
Now let’s continue with the base image definition by writing the
following to mkosi.images/base/mkosi.conf
:
[Output]
Format=directory
[Content]
CleanPackageMetadata=no
Packages=systemd
udev
We use the directory
output format here instead of the disk
output
so that we can build our extension without needing root privileges.
Now that we have our base image, we can define a sysext that builds on
top of it by writing the following to mkosi.images/btrfs/mkosi.conf
:
[Config]
Dependencies=base
[Output]
Format=sysext
Overlay=yes
[Content]
BaseTrees=%O/base
Packages=btrfs-progs
BaseTrees=
points to our base image and Overlay=yes
instructs mkosi
to only package the files added on top of the base tree.
We can’t sign the extension image without a key, so let’s generate one
with mkosi genkey
(or write your own private key and certificate
yourself to mkosi.key
and mkosi.crt
respectively). Note that this
key will need to be loaded into your kernel keyring either at build time
or via MOK for systemd to accept the system extension at runtime as
trusted.
Finally, you can build the base image and the extension by running
mkosi -f
. You’ll find btrfs.raw
in mkosi.output
which is the
extension image. You’ll also find the main image image.raw
there but
it will be almost empty.
What we can do now is package up the base image as the main image, but
in another format, for example an initrd, we can do that by adding the
following to mkosi.conf
:
[Output]
Format=cpio
Output=initrd
[Content]
MakeInitrd=yes
BaseTrees=%O/base
If we now run mkosi -f
again, we’ll find initrd.cpio.zst
in
mkosi.output
with its accompanying extension still in btrfs.raw
.
If you don’t have any need for a main image, you can configure
Format=none
in the Output
section in mkosi.conf
to disable it.