Nils Hanke [Mon, 13 Feb 2023 17:59:55 +0000 (18:59 +0100)]
Allow RPM to return total file sizes larger than 4GB
When an RPM has a total content size over 4GB, the --qf parameter
needs to use LONGSIZE instead of SIZE to display the total package
content file size, likely to keep compatibility with code
expecting 32 bit friendly values.
Otherwise, if a package is larger than 4GB, RPM returns (none).
Since this is later given as input to Python's int(),
it will throw an exception due to (none) not being a number.
Daan De Meyer [Thu, 9 Feb 2023 11:53:32 +0000 (12:53 +0100)]
Simplify kernel image and initrd handling
- Let's stop writing files in /etc in favor of passing the
information via other ways
- Let's stop defaulting to "bls" layout which is intended
for type 1 images, we only use UKIs so we don't need the
"bls" layout
- kernel-install now defaults to the "other" layout, which
means it won't create the entry directory in /boot anymore.
We update the initrd find logic to take this into account
- Remove --machine-id as it was only really there for testing
the config parsing which we now deal with by not storing the
machine ID at all
Daan De Meyer [Fri, 10 Feb 2023 09:40:03 +0000 (10:40 +0100)]
Set timezone credential to current timezone by default
We don't configure a default timezone in the images, so let's set
a timezone credential by default to the current timezone to avoid
a prompt during first boot.
Daan De Meyer [Thu, 9 Feb 2023 21:11:53 +0000 (22:11 +0100)]
centos: Do not try to resolve symlink
We don't have chase_symlinks(), resolving the symlink actually
resolves it on the host instead of in the image. Instead, let's
just unconditionally remove the symlink.
Daan De Meyer [Thu, 9 Feb 2023 09:01:07 +0000 (10:01 +0100)]
Drop --include-directory
Let's get rid of one more source of mounts. --include-dir can be replaced
by using --incremental and reading includes from the cached build image
tree. In the future, once build images become regular images, users can
read includes by simply using --directory output and reading includes
from the regular image output tree.
Daan De Meyer [Sun, 22 Jan 2023 17:29:49 +0000 (18:29 +0100)]
Enable unprivileged image builds
To enable this, when doing a build, we unshare a user namespace
with it's own private set of uids/gids obtained using newuidmap
and newgidmap. We also map the current user to the last UID/GID
in the UID/GID range from /etc/subuid and /etc/subgid. Together
with unsharing the mount namespace, this allows us to do
unprivileged bind and overlay mounts.
Next, we replace all usages of systemd-nspawn during the image build
with bubblewrap. systemd-nspawn cannot run as an unprivileged user
yet so we use bubblewrap which can. bubblewrap can also be used to
setup a chroot environment with API VFS filesystems so we make use
of that to setup chroot environments and remove all our homegrown
logic for it. This allows us to significantly reduce the amount of
mounts we do in mkosi itself.
To further reduce the amount of mounts, we modify the invocations
of all package managers to specify the cache directory via the
relevant option instead of mounting the cache directory into the
chroot. For apt, to accomplish this, we switch from using
DPkg::Chroot-Directory to setting the "--root" option for each
invocation of dpkg so that dpkg can access files outside of the
chroot.
Finally, we remove some options which become obsolete with this
commit, --idmap, --chown and --nspawn-keep-unit.
We also remove --source-file-transfer, --source-file-transfer-final
and the corresponding symlink options. Instead, we default to mounting
source files into the build tree. In the future, we'll add virtiofsd
support to allow accessing source files in qemu VMs.
We also move stuff around and create a few new files to store
helpers to avoid circular imports. There's also a little bit of
refactoring and cleanup all around.
Daan De Meyer [Tue, 7 Feb 2023 13:45:02 +0000 (14:45 +0100)]
Run preset-all on the final image
Let's run preset-all on the finalized image so that read-only
images (e.g. initrds) have the preset settings configured in the
image itself at creation time.
Daan De Meyer [Tue, 31 Jan 2023 18:37:28 +0000 (19:37 +0100)]
Remove btrfs subvolume deletion logic
Deleting btrfs subvolumes requires root. Given that we'll be moving
to primarily unprivileged execution soon, let's drop the logic for
deleting btrfs subvolumes. They're still deleted if the corresponding
directory is removed, it's just slightly slower.
Daan De Meyer [Mon, 30 Jan 2023 15:34:04 +0000 (16:34 +0100)]
qemu: Always use usermode networking
With the upcoming support for unprivileged image builds, we can't
use getuid() to check for root anymore as we might be in a user
namespace. Instead of trying to fix the detection, let's just
always use usermode networking when running in qemu.
Daan De Meyer [Fri, 27 Jan 2023 10:22:02 +0000 (11:22 +0100)]
Rework roothash handling
First, we clean up the leftover remnants of our qemu direct linux
boot support from install_unified_kernel(). Then we simplify passing
around data from invoke_repart() to install_unified_kernel() by only
passing around a single argument, the roothash/usrhash argument.
Finally, now that repart has "roothash" set on every verity sibling
partition, we can just read "roothash" off of any of them. We also
change the logic so that if we find a roothash, it always has
precedence over a usrhash.
Daan De Meyer [Tue, 17 Jan 2023 12:48:36 +0000 (13:48 +0100)]
Add check_config_file=False to all dnf repo definitions
By default, dnf will always refresh repository metadata if the timestamp
of the config file has changed. Since we always rewrite the config file,
this will always be the case, so let's make sure we don't refresh the
metadata every time.
Daan De Meyer [Mon, 16 Jan 2023 12:45:55 +0000 (13:45 +0100)]
centos: Modernize repo URLs
Let's use DNF variables where we can. We also modify releasever to
be only the release version without "-stream" and use $stream when
we need the releasever with "-stream". This matches the upstream
usages of these variables.
Daan De Meyer [Fri, 13 Jan 2023 12:06:45 +0000 (13:06 +0100)]
Remove --use-host-repositories
This option is superseded by --repository-directory which can be
used for exactly the same purpose so let's remove this very specific
option in favor of using --repository-directory.
Daan De Meyer [Tue, 10 Jan 2023 14:43:15 +0000 (15:43 +0100)]
Default to the distro preferred filesystem instead of ext4
Note that we don't default to btrfs due to an issue where mounting
COW copies of the same filesystem more than once fails with EBUSY.
Until that is fixed, btrfs is pretty much unusable for building
images as systemd-repart will fail to build btrfs images.
Daan De Meyer [Thu, 12 Jan 2023 13:47:06 +0000 (14:47 +0100)]
centos: Fix rpmdb location
The previous logic was not working correctly. Let's simplify the
logic by only executing it for centos and only working in one
direction, if the rpmdb is written to /usr/lib/sysimage/rpm, let's
move it back to /var/lib/rpm on CentOS.
Daan De Meyer [Tue, 10 Jan 2023 14:58:03 +0000 (15:58 +0100)]
centos: Stop installing systemd-boot on CentOS Stream 9
With CentOS Stream 9 moving to systemd v252, systemd-boot has been
added back to the systemd-udev package, so we don't need to install
it from EPEL anymore.
Daan De Meyer [Tue, 10 Jan 2023 14:33:45 +0000 (15:33 +0100)]
Remove --qemu-boot option
Given that we're standardizing more and more on UEFI and unified
kernel images, let's drop support for qemu direct linux boot, to
drop yet another seldomly exercised codepath.
Joerg Behrmann [Wed, 11 Jan 2023 09:32:33 +0000 (10:32 +0100)]
Remove annotations import from __future__
PEP 563 is a PEP that stringifies type annotations. The feature was made
available as opt in. It is still very much in flux or under consideration
upstream and has fallen so much out of favour that the Python steering council
added the note [1]
PEP 563 Postponed Evaluation of Annotations (the from __future__ import
annotations future statement) that was originally planned for release in
Python 3.10 has been put on hold indefinitely. See this message from the
Steering Council for more information.
in the release notes of CPython 3.11 after punting on accepting the PEP for two
releases. The import does a lot more, but we only use the type
stringification. There is little gain from using this, but with one of the main
features of the import indefinitely on hold, it seems prudent not to use it.
With Python 3.11 the PEP 673 Self type was introduced [2], that will solve this
problem for us, once we move on to 3.11.
packaging.version.parse() would create a Version object for "5.12" and a
LegacyVersion object for versions like "6.0.8-200.fc36.x86_64". This
leads to failed comparison (such as "6.0.8-200.fc36.x86_64 >= 5.12").
Use `systemd-analyze compare-versions` instead, which produce the
expected behaviour. This brings mkosi more in line with systemd
ecosystem when it comes to version strings parsing.
Daan De Meyer [Wed, 21 Dec 2022 15:04:02 +0000 (16:04 +0100)]
Migrate to ukify
Let's start using ukify to generate unified kernel images instead
of implementing the logic ourselves. This also fixes issues with
overlapping PE sections.
when the workspace directory is on another filesystem (i.e. /tmp) mkosi
fails.
replace os.rename with shutil.move when we may cross filesystem
boundaries. Furthermore, chown the resulting files if the flag is set
accordingly.
Daan De Meyer [Mon, 28 Nov 2022 14:45:31 +0000 (15:45 +0100)]
Migrate disk image building to systemd-repart
Let's switch to systemd-repart to build disk images. systemd-repart
allows building disk images declaratively. repart will assemble a
disk image according to a set of partition definition files, which
it will search for in a set of predefined locations or in the locations
provided via the --definitions option. Partition definition files are
defined in the usual systemd ini style and define a single partition
each. Many aspects of the partition can be configured, including its
size, type, and how it should be populated.
Of note should be the CopyFiles= setting that allows providing a set
of files/directories from which the partition should be populated. The
CopyFiles= setting takes a list of path pairs, where the first path in
a pair defines the source location, and the second path the destination
location in the partition. If combined with repart's --root or --image
options, the source path is resolved relative to the given root directory.
Along with switching to systemd-repart, we also rework how we build
images. Previously, we first provisioned the disk image with all its
partitions, then mounted the disk image and finally populated it with
contents. Now, we provision to a regular directory on the host filesystem
first, followed by creating the disk image with systemd-repart. The partition
definition files can be supplied via the --repart-directory option or
in the mkosi.repart/ directory. If not provided, a default configuration
consisting of an automatically sized root partition and an ESP partition of
256M is used.
repart's --root switch is used so that the partition definition files
don't need to encode the full path to the root directory of the image
we're building. For example, to copy the root directory to a root
partition, it's sufficient to specify "CopyFiles=/:/" in the definition
file.
If we're building non-bootable images, any ESP partition definitions
are excluded. To allow building UKIs with an embedded roothash cmdline
parameter, we run repart twice, first to populate all partitions except
the ESP/XBOOTLDR partitions, and again to populate the ESP/XBOOTLDR
partitions including any UKIs with embedded roothash cmdline parameter
(which we determined when running repart the first time).
Because we don't know up-front anymore where the ESP partition will be
mounted, all boot loader files are installed to /boot. So to populate
an ESP partition, you'd use "CopyFiles=/boot:/" in the partition
definition file of the ESP partition.
Also, since we don't know up-front anymore which filesystem we'll be
building for, we stop installing filesystem related packages by default.
Users will be required to add the necessary filesystem packages themselves.
Similarly, we also stop installing cryptsetup and device-mapper by default
since we don't know upfront anymore whether partitions will be verity
protected or encrypted.
By switching to systemd-repart, we also set ourselves up for building
images without needing root privileges or loop devices. systemd-repart
is fully capable (from v253 onwards) of building disk images without
needing root privileges or loop devices. After we switch to
systemd-repart, we'll only need root privileges to be able to run
systemd-nspawn (which should not be necessary in the future anymore).
This PR also removes all the option related to disk image building that
can now be specified in repart definition files instead. This includes:
- Format=gpt_xxx options are replaced with a single "disk" options.
Filesystem can now be specified with repart's Format= option
- Format=plain_squashfs (Can be reproduced by a single repart squashfs
root partition combined with SplitArtifacts=yes)
- Verity= (Replaced by repart's Verity= options)
- Encrypt= (Replaced by repart's Encrypt= option)
- RootSize=, HomeSize=, VarSize=, TmpSize=, ESPSize=, SwapSize=, SrvSize=
(Replaced by repart's size options)
- UsrOnly= (replaced with `CopyFiles=/:/usr` in a usr partition definition)
- OutputSplitRoot=, OutputSplitVerity=, (Replaced by repart's SplitName= option)
- OutputSplitKernel= (UKI is now always written to its own output file)
- GPTFirstLBA (Removed, no equivalent in repart)
- ReadOnly= (Replaced by repart's ReadOnly= option per partition)
- Minimize= (Replaced by repart's Minimize= option per partition)
- CompressFs= (No equivalent in repart, can be replicated by replacing mkfs.<fs>
in $PATH with a script that adds the necessary command line option)
- MkSquashfs= (Can be replaced with a script in $PATH that invokes
the correct binary)
We also remove the WithoutUnifiedKernelImages= switch as building unified
kernel images is trivial and fast these days.
Daan De Meyer [Mon, 28 Nov 2022 14:42:13 +0000 (15:42 +0100)]
ci: Rework integration tests
The current approach where we build the image as part of the integration
test is the wrong approach. Instead, we'll move to integration tests that
are integrated with a build system where building images and using them
in integration tests are separate steps. Building an image for use in an
integration test will be a regular target (custom_target()) in a build
system. Building an image that's not intended to be used in any other test
will be a regular test.
Because this model is going to be substantially different from what we have
now, let's get rid of the integration test machinery we added and temporarily
switch to the basic approach that's also used in the systemd repo for integration
tests.
Daan De Meyer [Fri, 18 Nov 2022 10:07:27 +0000 (11:07 +0100)]
Drop HostonlyInitrd
Adding this option was a mistake (mea culpa), we should limit host
impact on image builds as much as possible so let's drop this option
that makes the initrd generated by dracut host specific. This will
slow down initrd generation but once we switch to generating initrds
with mkosi we'll have a proper fix for that.
By default, mkosi would bind mount directories with nspawn's rootidmap
option to provide consistent files ownership. If the system doesn't
support ID mapping, mkosi would fail.
Add --idmap option, default to True, to allow users to disabled UID
mapping (--idmap=no).