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.
Now that we don't have to worry anymore about various operations
conflicting with other sandbox mounts, let's always add /var/tmp
to the sandbox again (we originally stopped doing this to make sure
rmtree() could remove directories in /var/tmp).
When we do something where we need to mount the parent directory
because we're creating or deleting a file or directory, let's operate
under /work in the sandbox. Otherwise there's a good chance we'll
end up interfering with regular mounts in the sandbox e.g /var/tmp
when the workspace directory is in /var/tmp.
/etc/pacman.d/gnupg is already made available by mkosi's internal
logic so we don't need to copy it in. This prevents failures when
running unprivileged as /etc/pacman.d/gnupg can have rather strict
permissions.
mkosi-initrd: Only set --cacheonly=metadata when running as root
If we're not running as root, we don't use the host's package cache,
but we still use the host's repositories. It's very unlikely that the
user's default package cache directory will have an up-to-date repository
metadata snapshot, so let's update the repository metadata if we're not
running as root.