For many use cases it's useful to be able to configure more than one
profile, an example is selecting a generic desktop profile and a more
specific kde profile as well.
Currently profiles can't depend on any of the configuration set in
mkosi.conf.d as they are parsed before mkosi.conf.d is parsed. Let's
parse the profile related configuration last instead so it can match
on all the configuration set in mkosi.conf.d.
To set the distribution and release and such based on the profile,
a dropin in mkosi.conf.d can match on the configured profile instead.
This change reformats mkosi using the ruff formatter with the default settings,
except for a line width of 119 columns.
Deviating from the default ruff formatting "fmt: skip" comments were added for
were it semantically makes sense, mainly:
- lists representing cmdlines, where options and their arguments should not be
split
- when alignment improves readability (by easing comparisons with lines above
and below)
Deviations from the above two guidelines are
- alignment was discarded for semantically empty statements (enum.auto())
- when all positional arguments where on the same line and options where on
different lines, the positional arguments where put on separate lines as
well, to minimize difference from vanilla ruff.
In collections that fit on a single line, trailing commas were removed, since
they force ruff to use multi-line formatting.
Traditionally, initrds stored in /boot must have their access mode set to 600.
Nowadays, this is useless for initrds stored on the vfat-formatted ESP, but it
doesn't hurt to support the old use case.
cli: add back mkosi-initrd and mkosi-tools to mkosi.resources
Otherwise these resources are not packaged and cannot be included.
E.g., `mkosi-initrd` fails because it adds `--include=mkosi-initrd`:
```
$ mkosi-initrd
Traceback (most recent call last):
File "/usr/lib/python3.11/site-packages/mkosi/run.py", line 64, in uncaught_exception_handler
yield
File "/usr/lib64/python3.11/contextlib.py", line 81, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/mkosi/__main__.py", line 30, in main
args, images = parse_config(sys.argv[1:], resources=resources)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/mkosi/config.py", line 3907, in parse_config
context.parse_new_includes()
File "/usr/lib/python3.11/site-packages/mkosi/config.py", line 3575, in parse_new_includes
st = path.stat()
^^^^^^^^^^^
File "/usr/lib64/python3.11/pathlib.py", line 1013, in stat
return os.stat(self, follow_symlinks=follow_symlinks)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpyqqy4ttp/resources/mkosi-initrd'
```
Let's move to a denylist instead of an allowlist so that we also
cover all kinds of non-standard locations which might be referenced
when running qemu, nspawn, ....
Let's log about errors from qemu itself, since those are generally
unexpected and with qemu we have a way to figure out whether the error
came from qemu itself or from within the virtual machine since the errors
from within the virtual machine are communicated via vsock.
To build an image with a dm-verity protected root partition that has
a persistent machine ID, the machine ID has to be embedded in the image,
so let's add back the MachineId= setting to support this use case.
Fix relative path calculation in filter_kernel_modules()
I'm not sure what possessed me when I last touched this, but to get
the path relative to the kernel/ directory we have to strip of the
first 5 parts, not just 1.
Make sure /var/tmp is not an overlayfs unless required
If we put an overlayfs on /var because the user provided files in
/var via their sandbox tree, make sure /var/tmp is not an overlayfs
unless really required so tools like systemd-repart can make full
use of the underlying filesystem features which are disabled if
/var/tmp is on an overlayfs.
Move /var/log creation from sandbox tree to sandbox_cmd()
We now always put an overlayfs on top of the sandbox tree so writes
done from within the sandbox aren't persisted, so there's no point
anymore in creating /var/log in the sandbox tree anymore. Instead,
make sure it exists within sandbox_cmd() so we can still access logs
when using --debug-shell.
In https://github.com/systemd/mkosi/pull/2973, we stopped putting
a repository snapshot into the image. However, this also means that
when rebuilding a cached image, we don't operate on the same repository
metadata snapshot anymore if the shared cache was resynced in the
meantime.
Let's fix this by adding a new cache directory for the top level image
which stores a repository metadata snapshot. Then, if incremental mode
is enabled and using the snapshot is not explicitly disabled, if we have
just a single cached image that we'll be reusing, reuse the repository
metadata snapshot as well. Otherwise, optionally sync and then copy the
repository metadata from the shared cache.
At the same time, we merge run_sync() and sync_repository_metadata() as
they don't make much sense as separate functions anymore.
Make code to deal with overlayfs "work" directory more robust
The work directory can be populated if files are deleted in the
upperdir. In that case we need to acquire privileges to be able to
delete the directory so add a fallback for that scenario.
virtiofsd might be executed as root within a newuidmap user namespace.
This means mkosi-sandbox will run as root within the newuidmap user
namespace and any directories created by mkosi-sandbox will be owned by
root in the newuidmap user namespace. If these directories are created
in a directory that's persisted (for example /var/tmp) and later cleaned
up by mkosi, this could fail with a permission error.
By using workdir(), the directories are guaranteed to be created within
a tmpfs which is automatically cleaned up when the sandbox is destroyed
with no chance for permission errors.
The issue hasn't occurred since we enabled this so let's disable
it again. If the issue starts happening again, we'll need to do
more targeted enabling of debug output.
.dir-locals specifies "fill-column" as 99 for .py files.
This seems resonable, because then the comments mostly match the
general width of the surrounding code.
dissect: do not attempt to load verity for just-built images
Verity is useful to establish trust at runtime in production
environments where we don't know if a payload is trusted in advance,
but we can implicitly trust the image we just built ourselves, so set
the env vars to disable loading images using verity when building
sub-images
Currently, to boot an image with mkosi qemu after building it with
mkosi build, various settings have to be identical to when mkosi build
was invoked to make sure that mkosi can find the outputs of the previous
build. Because this is rather error prone and annoying, let's introduce
a History= setting to allow mkosi to remember the configuration of the
last build which can then be read again when running a verb that operates
on a built image.
Another case where this is extremely useful is when some part of the
configuration changes every single time, for example if mkosi.version
is an executable script that outputs the current time, which is then
encoded in the output name, we have to remember the previous config,
otherwise mkosi wouldn't be able to find the outputs of the previous
build.
Note that while we load the configuration of the previous build, we
ignore all settings from the [Host] section which we read again from
the configuration files, as the user should be able to change these
without rebuilding the image.
Make JSON loading methods more robust against changes in Config and Args
We don't want failures to load JSON every time we add a new field, so let's
consider every JSON object we read as potentially partial and merge it with
a default instance of Config/Args. Also, sometimes we drop or rename fields
so let's show a proper error in the case that happens.
Let's not rely on tools not writing logs or errors to /dev/stdout
and instead use workdir() as well to mount the required parent
directory into the expected location so the output can be written
there.
Use more directories of sandbox trees in the sandbox
Previously, we only picked up /usr and /etc from the sandbox trees.
Let's make this more generic and pick up a bunch of extra directories
as well. To avoid any changes persisting outside of the sandbox, let's
use overlayfs with a temporary writable directory as the upperdir of the
overlayfs (and make sure we use a tmpfs as the upperdir for /tmp and /run).
Stop using sandbox tree to shovel out list of essential packages
We don't want to persist changes to the sandbox tree so in preparation
for that let's stop using the sandbox tree as a channel to shovel out
the list of essential packages when building debian images.