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).
Joerg Behrmann [Thu, 24 Nov 2022 11:54:34 +0000 (12:54 +0100)]
Move Fedora to DistributionInstaller
This doubles basically all rpm/dnf functions with copies in
mkosi.distributions.fedora, but this let's us keep the split bisectable without
having to do a big refactor of what these functions look like.
Joerg Behrmann [Tue, 4 Oct 2022 15:51:30 +0000 (17:51 +0200)]
Add remove_packages method to DistributionInstaller
This should probably live in PackageType, but there is a strong dependence
between package type and distribution and I haven't figured out a good way to do
this without cyclical imports.
Some are moved to backend for lack of a better place for now, most mount-related
functions are moved to a new mounts module, though some are left in __init__ for
later, when the dust settles and cyclic imports may become easier to avoid.
Command list and syntax is the most interesting part of the output.
But because of how argparse works, we were showing this part very
briefly and buried in other options. Instead of relying on the autogenerated
description, let's reuse the list from the man page.
Because a literal text is added, the lines for verbs and --help
and --version are suppressed.
I changed "Distribution" to "Distribution options" and so on for each
option group. The additional word connects the synopsis (which says
"[options…]" with the list below.
mkosi: drop ArgumentParserMkosi.fromfile_prefix_chars
mkosi is not usable as a library (all APIs are internal). So there is no need
to use a global variable for this. If we ever want to change it (and it's unlikely
that we ever would), we can just replace the character in the few places. The
code is much more readable without the indirection.
Add missing documentation about cmdlines for various verbs
The error message is changed to be more direct. If somebody doesn't know that
the parameters are passed to the command, "additional" would be unclear.
In the man page the verbs are listed by the order one would normally use them,
i.e. summary, then build, then qmeu/shell/boot/…, then clean, and the less
frequently used verbs last.
Descriptions are added to the commands which take parameters that they do that
and how those parameters are interpreted. In paricular, for 'boot' we accept
kernel commandline options, and for 'qemu' we only take qemu options. (Which is
understandable, given that we don't do a direct kernel boot, but not obvious.)
Georges Discry [Tue, 15 Nov 2022 10:19:42 +0000 (11:19 +0100)]
debian/ubuntu: Configure apt chroot with APT_CONFIG
When invoking apt switched from running inside the container to running
on the host, apt stopped reading the configuration files present in the
container. Because of this, it is not possible anymore to configure apt
by dropping a file in `mkosi.skeleton/etc/apt/apt.conf.d/`.
apt first loads its configuration files and then parse the command-line
options (so that they can override the options set in the files). While
setting `-o Dir=<container-root>` on the command-line has some impact on
the configuration of apt, it will not read the files in
`<container-root>/etc/apt/apt.conf.d/`, as apt has already read its
configuration files from the host with the configuration `Dir "/"`.
Rather than using the command-line, the APT_CONFIG environment variable
should be used to point to a file with the chroot configuration. When
set, that file is processed before anything else. By setting `Dir` this
way, apt will read the configuration files from the container and not
from the host.
As the host configuration is not read anymore, there is no more need to
mask `/etc/apt` on the host by bind-mounting an empty directory over it.
Georges Discry [Tue, 15 Nov 2022 11:22:31 +0000 (12:22 +0100)]
Use the right python when mkosi is a symlink
When the `mkosi` on the `PATH` is a symlink to the script installed
inside a virtualenv, the script fails to find the python executable
inside the virtualenv and falls back to the main python3. This is
notably the case when installing mkosi with pipx.
By first following the symlink inside the virtualenv, the script can
find the corresponding python executable.
Daan De Meyer [Mon, 14 Nov 2022 15:18:39 +0000 (16:18 +0100)]
Look in both the config file and the cwd for dropin files
A project might have multiple config files in subdirectories that
they use with --default but have shared configuration in the root
of the repository. When loading such a config file with --default,
we should still load shared dropins from the shared location.
Daan De Meyer [Mon, 14 Nov 2022 15:10:25 +0000 (16:10 +0100)]
Fix passing extra options to systemd-nspawn
systemd-nspawn ignores all options after the first argument so when
we're passing kernel command line arguments, we need to make sure
we pass the nspawn options first, otherwise they'll get ignored.
Joerg Behrmann [Tue, 8 Nov 2022 12:46:04 +0000 (13:46 +0100)]
Pass KERNEL_INSTALL_BYPASS through to the places where it is used
The idea of using KERNEL_INSTALL_BYPASS is to not run kernel-install twice
unnecessarily, since we run it later anyway, but a user reported a regression of
kernel-install not being run at all, although it apparently was in
earlier. Passing the environment variable through will at most run
kernel-install twice, this might be a workaround.