DaanDeMeyer [Wed, 24 Dec 2025 10:53:57 +0000 (11:53 +0100)]
Fix --debug-shell
While we're at it, let's save ourselves from having to reason about
Python's capture rules for nested functions by moving _preexec() out
of spawn() and passing in arguments via functools.partial().
DaanDeMeyer [Wed, 24 Dec 2025 10:35:32 +0000 (11:35 +0100)]
sandbox: Drop --proc
This is trivially replaced with --bind /proc $DST, so let's drop the
separate option. Maybe in the future we'll add --proc back but have it
actually mount a new procfs instance.
DaanDeMeyer [Wed, 24 Dec 2025 08:35:39 +0000 (09:35 +0100)]
run: Remove hack to keep packed file descriptors intact
Now that we execute execvp() in the preexec function and therefore
skip python's close file descriptors logic, we don't need our hack
anymore to tell python the right file descriptors to close so let's
drop it.
DaanDeMeyer [Tue, 23 Dec 2025 16:17:01 +0000 (17:17 +0100)]
run: Call execvpe() from preexec function
Python does its own executable lookup in $PATH before executing the preexec function, and
hence before we have set up the sandbox which influences the lookup results. To get around
that, let's call execvpe() ourselves inside the preexec() function, and not give Python the
chance to do it itself. This ensures we can do the proper executable lookup after setting
up the sandbox. If we can't find the executable, do nothing, and let Python do its own
search logic so it can return a proper error, which we cannot do from the preexec function.
Note that by doing this we also skip Python closing all open file descriptors except the
ones specified by the user in pass_fds, but since Python opens all file descriptors with
O_CLOEXEC anyway, we'll assume we're good and don't need to close open file descriptors
explicitly.
DaanDeMeyer [Mon, 22 Dec 2025 19:33:08 +0000 (20:33 +0100)]
Configure pyright included files
Let's configure the files on which pyright should run to avoid long
startup times where it tries to check every single file in the workspace
directory.
Daan De Meyer [Mon, 22 Dec 2025 13:54:52 +0000 (14:54 +0100)]
qemu: Register with systemd-machined in user session
Now that machine registration works unprivileged
since systemd v259, let's switch to unconditionally
registering machines with the user session
systemd-machined instance.
This breaks compat but the previous implementation
arguably wasn't useful or used, since registration
would only be done when running as root or if the
Register= feature was explicitly enabled. And if
not running as root, you'd have to authenticate
every time when booting the image to register it
which is arguably too annoying that anyone actually
bothered with it.
As vmspawn doesn't yet support registering with the
user machined instance, we stop registering vmspawn
machines for now. https://github.com/systemd/systemd/pull/40185
will add support for user machined regisration to
vmspawn.
For nspawn we stick with system machined registration
for now.
Daan De Meyer [Fri, 19 Dec 2025 20:02:30 +0000 (21:02 +0100)]
Cache hwdb step
Running hwdb takes roughly a second and is
unlikely to ever rely on files added by extra
trees or such, so let's cache the step instead of
re-running it every single time.
distribution: do not default to release=VERSION_ID for openSUSE Tumbleweed
`config_default_release()` calls `detect_distribution()` to get the default
release if it's not set, which picks the value from os-release's `VERSION_ID`.
In openSUSE Tumbleweed this property has the snapshot number. Since
`mkosi-initrd` does not set `Release=` via config, mkosi thinks that it's Leap
and fails:
```
$ mkosi-initrd
‣ Validating certificates and keys
‣ Building main image
‣ Copying in sandbox trees…
‣ Installing openSUSE
Warning: Enforced setting: $releasever=20251217
Loading repository data...
Reading installed packages...
'Leap-release' not found in package names. Trying capabilities.
No provider of 'Leap-release' found.
‣ "zypper --installroot=/buildroot --cache-dir=/var/cache/zypp --non-interactive --no-refresh --releasever=20251217 --no-gpg-checks install --download in-advance --no-recommends --force-resolution filesystem Leap-release" returned non-zero exit code 104.
‣ "mkosi --force --directory= --format=cpio --output=initrd --output-directory=/tmp/tmpcvx9let7 --extra-tree=/usr/lib/modules/6.17.0-2-default:/usr/lib/modules/6.17.0-2-default --extra-tree=/usr/lib/firmware:/usr/lib/firmware '--remove-files=/usr/lib/firmware/*-ucode' --build-sources= --include=mkosi-initrd --kernel-modules=host --extra-tree=/usr/lib/modules/6.17.0-1-default/updates/hdaps.ko:/usr/lib/modules/6.17.0-1-default/updates/hdaps.ko --extra-tree=/usr/lib/modules/6.17.0-1-default/updates/thinkpad_ec.ko:/usr/lib/modules/6.17.0-1-default/updates/thinkpad_ec.ko --extra-tree=/usr/lib/modules/6.17.0-1-default/updates/tp_smapi.ko:/usr/lib/modules/6.17.0-1-default/updates/tp_smapi.ko --package-cache-dir=/var --cache-only=metadata --output-mode=600 --include /usr/lib/mkosi-initrd --include /etc/mkosi-initrd --sandbox-tree=/tmp/tmp0tjr7mwr --extra-tree=/etc/vconsole.conf:/etc/vconsole.conf" returned non-zero exit code 104.
```
Luca Boccassi [Wed, 17 Dec 2025 20:38:46 +0000 (20:38 +0000)]
mkosi-addon: drop Output=addon, addon.py already has a default
addon.py already passes mkosi-local.addon.efi by default if nothing
else is given, so it's not necessary to override it here. And it makes
it impossible to give custom names via Output= in your own config.
Yu Watanabe [Wed, 17 Dec 2025 16:44:42 +0000 (01:44 +0900)]
sandbox: return raw error code from the kernel and friends on failure
When a system error occurs, the libseccomp returns -ECANCELED and
hides the original error code. That makes harder to debug the failure.
Let's make libseccomp propagate the original error code.
Marc Herbert [Tue, 11 Nov 2025 00:12:49 +0000 (16:12 -0800)]
make_image: log systemd-repart *.conf files at the --debug level
As discussed in #3948, systemd-repart *.conf files have default values
which is convenient until this fails with some dreaded "disk full" error
- then it becomes very mysterious. To considerably speed up the
investigation about what exactly is full, show the configuration files
in use when using --debug.
Signed-off-by: Marc Herbert <marc.herbert@intel.com>
(cherry picked from commit 7040a6add12c8f8c1c8393d5e35c747ee2876472) Signed-off-by: Marc Herbert <marc.herbert@intel.com>
Daan De Meyer [Mon, 15 Dec 2025 20:24:15 +0000 (21:24 +0100)]
sandbox: Add better error reporting for overlayfs
Let's do some basic checks up front so we catch
trivial errors ourselves instead of having to
debug obscure errors we get back from the kernel
when calling mount().
Daan De Meyer [Fri, 12 Dec 2025 11:21:21 +0000 (12:21 +0100)]
kmod: Only add fully resolved fw path if it exists
The symlinks in /usr/lib/firmware might be
dangling and we shouldn't try to add the target of
a dangling symlink to the list of firmware as cpio
will error out later because it can't find the
file or directory.
Daan De Meyer [Wed, 10 Dec 2025 18:41:28 +0000 (19:41 +0100)]
Fix SplitArtifacts=repart-definitions for addons
is_extension_or_portable_image() includes addon images, which should
be skipped in copy_repart_definitions(), so list the formats individually
instead.
Daan De Meyer [Tue, 9 Dec 2025 22:11:25 +0000 (23:11 +0100)]
run: Set up sandbox with a preexec function
There's no need to initialize a new python interpreter every single
time we need a sandbox when we can use the one we already have by
setting up the sandbox with a preexec_fn. A preexec_fn executes before
execve(), so we can reuse the same python interpreter we're already
running in instead of having to spawn a new one.
If we're debugging the sandbox or running a setup command, we stick to
the old approach of invoking a separate python interpreter.
Daan De Meyer [Tue, 9 Dec 2025 21:54:03 +0000 (22:54 +0100)]
Move setup argument to run() instead of sandbox_cmd()
It's a bit up in the air whether this belongs in sandbox_cmd() or
spawn() but let's move it to spawn since it shouldn't be impossible
to have a setup command without having sandbox.
Daan De Meyer [Tue, 9 Dec 2025 21:30:04 +0000 (22:30 +0100)]
Use proper constants for ansi colors
I was playing around with mypyc again and it did not like class
attributes like the Style ones. While mypyc ended up not working for
other reasons, let's switch to something it is happy with which is just
regular constants named identically to how they're named in systemd. It's
arguably not uglier than the Style namespace class.
Daan De Meyer [Sun, 7 Dec 2025 19:04:51 +0000 (20:04 +0100)]
action: Use environment variables instead of inputs
Let's simplify and just use environment variables
instead of inputs. While we're at it, use
environment variables for everything since I don't
know which variables are broken in composite
actions and which are not (see linked github
actions bug).
Laurence Kiln [Fri, 5 Dec 2025 09:26:32 +0000 (11:26 +0200)]
Add python3-pefile to fedora tools conf
python3-pefile is a dep of `system-ukify` which `mkosi` depends on,
so it gets installed indirectly by `dnf install $(mkosi dependencies)`
runs. But mkosi depends on it directly, so make it an explicit dependency.
Laurence Kiln [Mon, 1 Dec 2025 23:01:38 +0000 (01:01 +0200)]
Don't discard ordering of include/exclude entries in KernelModules=
Since eecf8b3b5 `KernelModules=` supports both inclusion and exclusion
of kmods. When resolving kmod presets like "default" and "host"
(and perhaps others in the future) it's important to retain the
ordering of entries, so that the user can add a preset and then
subtract only specific modules from the working set.
`filter_kernel_modules` relies on this ordering to do its job.
Laurence Kiln [Sat, 29 Nov 2025 14:28:20 +0000 (16:28 +0200)]
Add zram and nfnetlink to default initrd
zram-generator has been on by default in fedora
since fc33 (2020) and runs during early boot.
If the zram module is missing, users are hit with a nasty
45s systemd timeout.
firewalld.service is also on by default and fails to start
without nfnetlink.
Let's make sure an image built with `KernelModules=default`,
which pulls in the default mkosi-initrd modules, brings up
a fedora system in a non-degraded state
Luca Boccassi [Sat, 29 Nov 2025 01:10:01 +0000 (01:10 +0000)]
verity: copy signing certificate to /usr/lib/verity.d/
If a signing certificate for verity is specified copy it in the image
to /usr/lib/verity.d/ so that it can be used for userspace verification
when not using secure boot