Daan De Meyer [Tue, 25 Mar 2025 21:13:42 +0000 (22:13 +0100)]
Don't cache the package manager used in the tools tree cache manifest
Doing this causes issues when using mkosi sandbox as have_cache(tools)
will be different inside and outside of the sandbox when building Fedora
and only dnf is available outside the sandbox but dnf5 is available inside
the sandbox. Since we don't need to cache the package manager used anyway
when building the default tools tree because we don't cache the package
manager metadata either, don't cache it to avoid this problem.
Daan De Meyer [Tue, 25 Mar 2025 19:28:51 +0000 (20:28 +0100)]
Implement ToolsTreeSyncScripts=
In systemd, we have prepare scripts for the build image to install
all the build dependencies of the corresponding distribution's systemd
packaging spec. The distribution packaging spec is checked out by a sync
script.
We also need the systemd build dependencies installed in the default tools
tree in systemd, so that we can build all the systemd tools required to build
the image in the tools tree as well to later be used to build the image. Currently
we list the the required dependencies manually as packages since we can't reuse
the prepare script from the build image as the sync scripts run after the default
tools tree has been built which means we can't depend on the packaging specs
being available when building the default tools tree.
Let's fix the issue by introducing ToolsTreeSyncScripts= to define sync scripts
to run before building the default tools tree.
Daan De Meyer [Tue, 25 Mar 2025 15:42:38 +0000 (16:42 +0100)]
Drop logic for using /root/.cache
Let's just have root use the cache in /var/cache/mkosi to avoid accidentally
leaking files into /root/.cache accidentally where it's much less likely that
they'll ever get cleaned up.
Daan De Meyer [Tue, 25 Mar 2025 13:41:26 +0000 (14:41 +0100)]
Make sure tools tree recorded in history doesn't change when in sandbox
Currently, when in the sandbox, the tools tree will always be recorded
as "null" in the history. This causes problems if an image build is done
inside of mkosi sandbox and mkosi is later invoked outside of the sandbox
as the history will say no tools tree was used and so the tools tree won't
be used, even if we're running outside of the sandbox.
To fix the issue, let's make sure we always record the proper tools tree,
but let's not make use of it in the sandbox by moving the sandbox check to
the Config object's tools() method.
We also simplify all the tools tree related checks in run_verb() and add a
check to make sure we don't try to rebuild the default tools tree when in
"mkosi sandbox" as that can't ever work.
Daan De Meyer [Tue, 25 Mar 2025 14:20:12 +0000 (15:20 +0100)]
Store default tools tree outside of output directory
A common workflow is to build the same image multiple times with
slightly different settings, using a different output directory for
each build. By storing the default tools tree inside the configured
output directory, we end up rebuilding the tools tree for every single
one of these builds, even though in almost all cases the tools tree for
each image will be identical.
Let's address this issue by not storing the default tools tree in the
configured output directory but instead storing it in the current working
directory.
Daan De Meyer [Mon, 24 Mar 2025 10:52:39 +0000 (11:52 +0100)]
tools: Add "devel" profile
This profile contains tools required to build C/C++ projects. This is
useful to use mkosi sandbox to quickly build one off projects without
having to list a bunch of basic packages over and over again.
Daan De Meyer [Mon, 24 Mar 2025 09:31:43 +0000 (10:31 +0100)]
Always cache the default tools tree
For the default tools tree, the cached image and the final image
are the same for all intents and purposes, so let's stop storing both
a cached image and a final image for the default tools tree and instead
only store the final image and use it as the cached image by always
writing a cache manifest next to it.
At the same time always use the name mkosi.tools to reduce the chance
of conflicts as "tools" is an incredibly common directory name.
Daan De Meyer [Sat, 22 Mar 2025 12:07:19 +0000 (13:07 +0100)]
run: Bind mount entire /home into relaxed sandbox
Let's simplify things and make the entirety of /home available. The
relaxed sandbox is not about security, and permissions already make sure
only the user's own home can be accessed.
Daan De Meyer [Sat, 22 Mar 2025 11:23:37 +0000 (12:23 +0100)]
Make sync script sandbox more relaxed
Let's simplify and mount in the entirety of /home, /run and the
invoking user's environment to make stuff just work more often than
not and avoid too many implementation details of specific tools leaking
into mkosi itself.
Daan De Meyer [Tue, 18 Mar 2025 14:54:27 +0000 (15:54 +0100)]
Fix KernelModulesExclude= settings
With eecf8b3b5c43e4832a11c8718ae43e559a755829, exclude settings have
started taking priority over include or the new glob settings whereas
they should not. Fix the logic so the globs and include patterns always
take priority over the exclude patterns.
mkosi-initrd: protect existing initrd image against errors
When `copy_tree()` ends up calling `cp`, if it fails because there is not enough
space, it leaves an incomplete initrd image in the output directory. If we are
writing the initrd image directly where a bootloader entry has an initrd
configured, the system will fail to boot. So, instead of copying the initrd
image directly to the output, copy it next to it in the same output directory,
and if the copy is successful, replace it.
Rework firmware-list settings to use globs instead of regexps
This mirrors the change to module-list options. The two FirmwareInclude/FirmwareExclude
options are replaced by one FirmwareFiles option that takes positive and negative
globs. (Firmware name is already taken.)
This creates the following difference:
-usr/lib/modules/6.14.0-0.rc1.15.fc42.x86_64/kernel/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/ch_ipsec.ko.xz
-usr/lib/modules/6.14.0-0.rc1.15.fc42.x86_64/kernel/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/ch_ktls.ko.xz
In the previous syntax, we included those modules accidentally because
'inline_crypto/' matches 'crypto/'.
Rework module-list settings to use globs instead of regexps
"If you have a problem, and use a regexp, now you have two problems."
I don't think this quip applies in all cases, but the existing interface with
regexps was problematic for a few reasons:
- users usually want to match at a word boundary, but regexps apply anywhere in
the string, so to actually match correctly, the regexp has to be carefully
constructed with word boundary assertions.
Even our own config for initrds included some modules by mistake,
e.g. drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/ch_ipsec.ko.xz
was matched by crypto/.
- once the regexps include the word boundary assertions, they became quite
complex and hard to read.
- because of the separate evaluation of include and exlude patterns, we
need to have exclude patterns in the include patterns. The example given
in the review:
^drivers/net/(?!wireless/)
But this means that we can do exclusions in two places, making the whole
scheme very complex.
- the default to include all modules by default goes against the general
design of mkosi, where only things that are explicitly configured are
put in the image. That default is only useful when trying to build a
"maximal" image that matches the current machine. In most uses, the
default of including only requested modules makes more sense (initrd,
addons, any not-host-only images).
A new setting that takes glob patterns is added. There is only one setting
instead of a pair, exclusion patterns are prefixed by '-'. The last matching
glob wins. The details of how those globs are interpreted is crafted to
match our particular use cases.
For a single glob, the rules are:
- 'foo' matches the basename, /some/path/foo.ko
- 'bar/foo' matches the last component of the path, bar/foo.ko
- '/full/path/bar' only matches /full/path/bar.ko.
- crypto/* or crypto/ match all modules any crypto/ directory.
- /crypto/* matches the modules in the top-level directory.
This might seem complicated at first glance, but apart from the special
handling of the suffix, those rules mostly match how 'ls' would handle
a local path argument.
Suffixes are not specified in the globs. '-' and '_' are treated as equivalent,
except when part of special glob syntax with […].
New settings are added:
KernelModules=GLOB
KernelInitrdModules=GLOB
(KernelModulesInitrd=BOOL already exists and specifies whether to create a
separate initrd.)
I think the new syntax is more pleasant to read and write. Backward
compatibility is maintained by keeping the old options in place. The change to
exclude all modules by default is a breaking change, but in most uses both
options were used in combination anyway, so I think this should be fine.
The example given in the review:
KernelModulesInclude=
^drivers/net/(?!wireless/)
becomes
KernelModules=
/drivers/net/
-/drivers/net/wireless/
Daan De Meyer [Thu, 13 Mar 2025 14:35:49 +0000 (15:35 +0100)]
fedora: Change default release to rawhide
Fedora releases new versions quite regularly, sometimes more regularly
than we do mkosi releases. This means that users on the latest official
mkosi release can end up building EOL fedora releases because the default
release will be the latest fedora release at the time of the mkosi release
which might be EOL already. Let's switch to rawhide as the default release
so users are guaranteed to get something recent regardless of how old their
mkosi version is.
This matches what we already do for debian, opensuse, arch and other distros.
Both styles were used by the existing code: ['--foo=bar'] and ['--foo', 'bar'].
Switch to the former exclusively. A single arg like '--foo=bar' is easier to
read and/or select&paste in the log output. Also, we avoid explicit str()
wrappers in a bunch of places.
Daan De Meyer [Tue, 11 Mar 2025 20:12:11 +0000 (21:12 +0100)]
Try to find volatile overlay upperdir directory that's not on overlayfs
Making a directory on overlayfs the upperdir of another overlayfs is
rejected by the kernel. Let's try to find a directory that's not on
overlayfs. The /dev/shm fallback is because on a default podman container
even /tmp is on overlayfs.
Daan De Meyer [Thu, 6 Mar 2025 22:47:33 +0000 (23:47 +0100)]
Rework --run-build-scripts
Instead of (optionally) building the image when this option is enabled,
let's insist that the image has already been built and cached. This allows
us to reuse the history of the previous build if History= is enabled. At
the same time, rename the option to --rerun-build-scripts to indicate more
clearly that the image needs to have been built once already.
This allows the option to be used in systemd's mkosi.clangd script to replace
"-t none" and "--incremental=strict" there.
Daan De Meyer [Wed, 5 Mar 2025 19:32:58 +0000 (20:32 +0100)]
Move package installation and removal to PackageManager interface
There's no need for these to be implemented by the Distribution
interface as they don't need distribution specific knowledge so let's
move them to the PackageManager interface instead.
Daan De Meyer [Wed, 5 Mar 2025 18:59:26 +0000 (19:59 +0100)]
debian: Install policy-rcd-declarative by default
Debian switched to systemd ages ago, but as we know legacy stuff
tends to linger in Debian for quite a while. Let's standardize on
using systemd presets to enable daemons by installing packages for
a deny-all policy for sysv-init style packages instead of messing
with the script ourselves.
Daan De Meyer [Tue, 4 Mar 2025 08:21:25 +0000 (09:21 +0100)]
centos: Handle major/minor releases in derivatives properly
While centos doesn't have major/minor releases, rocky, alma and rhel
do, so let's make sure we handle those cases properly.
Additionally, we also fix EPEL to use the proper major/minor release
when we're doing EPEL 10, as since EPEL 10 there's major/minor releases
for EPEL as well.
Septatrix [Sun, 2 Mar 2025 20:53:09 +0000 (21:53 +0100)]
Parse both mkosi.local.conf and mkosi.local/
This aligns more with what the users expects
and allows working around some limitations of the config system
(esp. regarding the interplay of `Include=` and `Profiles=`).
Enable only the initrd profiles specified with this option, rather than all by
default. This saves space and allows the user to choose only what is needed on
each system.