OpenSUSE's rpm is not built with the sqlite db backend so let's make
sure the rpm DB can be read inside the image by OpenSUSE's rpm by
forcing the ndb backend to be used.
/var will always be writable in the sandbox so no need to precreate
the sandbox. This also saves us from using an overlayfs mount from
/var in the sandbox as it will be completely empty now.
Unprivileged overlayfs isn't available everywhere (see #3054). So
let's try to accomodate this a little by not using overlayfs for /etc
and /opt from the sandbox tree and instead mounting them read-only
into the sandbox. If required, scripts can still mount an overlayfs
onto these if needed, we just don't do it by default anymore.
This does mean we need to set up /etc with mountpoints and symlinks
beforehand in install_sandbox_trees(), but this shouldn't be a huge
problem.
Don't explicitly bind mount in keyrings from host into sandbox
These are automatically mounted in as part of the tools tree. This
change means they'll always be picked up from the tools tree and won't
take ToolsTreeCertificates= into account anymore, but then keyrings weren't
exactly certificates in the first place, and can still be picked up from
the host by using SandboxTrees=.
This allows users to provide their own keyrings using sandbox trees. Currently
we just overmount the user provided ones with the ones from the host.
We need to make sure /run/pcscd/pcscd.comm is available to make
signing work so let's mount /run/pcscd into the sandbox every time
we're going to sign something if it exists.
The generated root partition needs to be resized on first boot for
the A/B update setup so we have to make sure it's the last one and
give it the same size requirements as the B partition in the image
so it's grown to the same size.
Similarly, we make sure to leave sufficient space for verity hash
data updates. Because this is not the last partition, we can't grow
it on first boot so we leave sufficient room inside the image itself
when building it.
While we're at it we also reorder the settings a bit so things are
more consistent.
Separate the PROFILES variables with spaces instead of commas
Space-separated strings strings are the shell programmers array and therefore
easier to consume. Since profile names are supposed to be space-free, this is a
safe change and for languages with smaller footgun potential it does not make a
difference.
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.