Luca Boccassi [Wed, 7 Aug 2024 22:39:06 +0000 (23:39 +0100)]
distributions: drop Debian workaround for lack of VERSION_CODENAME
It has been present since Debian 9, so we can rely on it now.
It is wrong on sid, but that's a separate issue that this old
workaround doesn't solve anyway.
Daan De Meyer [Thu, 8 Aug 2024 11:09:46 +0000 (13:09 +0200)]
debian: Fix up os-release for unstable/sid builds
The version codename for unstable/sid builds is indistinguishable from
testing. Let's make sure we fix that up ourselves so that unstable image
builds can be properly distinguished from testing builds.
Daan De Meyer [Tue, 6 Aug 2024 07:57:46 +0000 (09:57 +0200)]
Don't pass down empty lists to subimages unless explicitly configured
This makes sure that subimages use default values for list based
settings unless they were explicitly configured in configuration or
on the command line or have a non-empty default value in the main
image.
Daan De Meyer [Fri, 2 Aug 2024 08:13:20 +0000 (10:13 +0200)]
Use debian as the default tools tree again on Ubuntu
Debian has distribution-gpg-keys which Ubuntu doesn't. As we'll likely
keep running into similar scenarios in the future, let's just stick with
Debian as Ubuntu's default tools tree.
Daan De Meyer [Fri, 2 Aug 2024 11:16:17 +0000 (13:16 +0200)]
Exit early if output format is none and there are no build scripts
In systemd, the build script is part of a subimage so the build is
done as part of the subimage and there's nothing to do for the main
image. To speed things up a bit, exit early if there are no build
scripts and the output format is none.
Daan De Meyer [Thu, 1 Aug 2024 10:37:50 +0000 (12:37 +0200)]
Introduce RepositoryKeyFetch=
This setting controls whether we'll fetch GPG keys remotely or not.
We disable it by default so that we only rely on locally available GPG
keys for checking package and repository metadata signatures.
This new setting only affects dnf/zypper based distributions as apt
and pacman do not support retrieving GPG keys remotely in the first
place.
zypper does not trust GPG keys listed in gpgkey= by default so we import
local GPG keys manually with rpm to work around that.
Daan De Meyer [Thu, 1 Aug 2024 14:35:36 +0000 (16:35 +0200)]
Only use unshare to become root if we're actually going to use a scope
If the relevant environment variables are not set, scope_cmd() will
return an empty list and we won't use a scope after all. In that case
we don't need to use unshare either to become root and can rely on our
own become_root() function so check whether we're actually going to use
a scope or not.
Daan De Meyer [Thu, 1 Aug 2024 13:26:32 +0000 (15:26 +0200)]
tests: Simplify initrd tests
Let's get rid of the fixtures and just rely on the default initrd
built as part of the image itself. This also means any settings
picked up from mkosi.local.conf are applied to the initrd build.
Let's require users to set these automatically if they want to
have autologin without enabling the Autologin= setting. This gives
more flexibility after https://github.com/systemd/systemd/pull/33873
is merged in systemd as users can choose to enable the settings
globally or per tty depending on what they need.
Set up proper environment variables for kernel-install
If we're not explicitly disabling kernel-install during package
manager invocations, let's set up the environment to make it do the
right thing instead.
Look for $USER for the username before reading /etc/passwd
Let's take $USER into account if set before reading /etc/passwd
for the username. This gives a way out for environments where the
uid of the user does not have an entry in /etc/passwd.
Handle failure to detect the distribution in test_parse_config()
If /usr/lib/os-release isn't available, we can't detect the current
distribution, so let's make sure we handle that scenario as well by
checking for Distribution.custom instead of None.
Template the options definitions directly into the completion function, since
for some weird scoping reasons even though the script is read fine and when
running a shell with set -x one can see e.g. _mkosi_options being assigned the
proper values, the completion function still uses '' for
"${_mkosi_options[*]}".
This wasn't caught during development because the script works fine when
sourced.
Look up qemu and virt-fw-vars in extra search paths
Because qemu uses OVMF firmware descriptions from /usr, we look
those up in the same root that we'll be invoking qemu from. Because
virt-fw-vars operates on the same files, we also invoke it in the
same root that we find qemu in.
There could potentially be a huge amount of modules and firmware
which makes these log messages very noisy. Let's drop them to make
debug logs less annoying to parse.
Assign return code before calling sys.excepthook()
It seems sys.excepthook() can raise its own exception? I'm not entirely
sure what's going on, but as a safety measure, let's assign the correct
return code before we invoke sys.excepthook() so that we always exit with
the right returncode.
There's various crypto directories all across the kernel modules
tree. Let's make sure we include all of them so that everything
required to do crypto is always available from the initrd.
Don't copy /var/lib/pacman/local when copying repository metadata
/var/lib/pacman/local contains the local database of installed packages.
When using "--package-cache-dir /var", we'd end up copying the local
database of the host which means pacman thinks packages are already
installed in the image even though they aren't.
If the image is nocow, make the ephemeral copy nocow as well
On btrfs, VM images are generally recommended to be made nocow as
cow (copy-on-write) and random writes don't play well together. Let's
take this into account in copy_ephemeral() and make the ephemeral
copy nocow as well if the source is nocow.
This does not work as we call have_cache() to determine whether
we need to clean the tools tree or not and when running as root to
boot after building an image the UID/GID will differ and the tools
tree will incorrectly be considered out of date.
Let's move the UID/GID check out of have_cache() and into reuse_cache()
instead. reuse_cache() always runs after we've already potentially
unshared the user namespace and become root, so checking the owner of
the cache directory against the current UID should be a valid check
there.
bubblewrap uses pivot_root() which doesn't work in the initramfs as
pivot_root() requires / to be a mountpoint which is not the case in
the initramfs. So, to make sure mkosi works from within the initramfs,
let's make / a mountpoint by recursively bind-mounting / (the directory)
to another location and then switching root into the bind mount directory.
We can't check the current uid in sandbox_cmd() as it might still
change, for example in start_virtiofsd() where before we run bwrap
we might run become_root_cmd() to become root.
Make make_cpio() take a list of files relative to the root directory
We operate on absolute paths all the time in kmod.py only for them to
be made relative to the root directory just before they are passed to
cpio. Let's save on the amount of allocations by always operating on
paths relative to the root directory.
Because rglob() doesn't support returning paths relative to the given
directory, we chdir() into the root directory before globbing instead.
Sadly, shellcheck does not support zsh [1], and it's not even possible
to evaluate the script with zsh because it fails with:
_arguments:comparguments:327: can only be called from completion function
So the zsh script shall not be checked.
readarray is used to create arrays. The one clear advantage is that we don't need to
override $IFS. Together with the change to not assign an unused variable, this
removes shellcheck warnings.
Nevertheless, shellcheck would still warn about the file because it doesn't
know about the variables that are in the part that is generated dynamically.
Also, move more content to the static resource file. The order of declarations
doesn't matter, so it's fine if the variables are defined below the functions.
Also, adjust the formatting in the bash resource to follow the usual style
with 'if something; then' on one line.