mkosi: in UsrOnly=yes mode, generate a mount.usr= kernel cmdline switch
So far, we relied on gpt-auto's logic to automatically find the root fs
on the image. This is not supported for finding the /usr partition
though, hence generate a mount.usr= kernel cmdline option to address
this.
(And it's unlikely we'll add auto-discovery for /usr, since we cannot
realistically decide whether its worth waiting for /usr. After all we
*know* we can't proceed without a rootfs, hence it makes sense to
generically wait for one if we never got one configured one. But a /usr
partition is an optional thing, hence it doesn't make sense to wait for
it if we didn#t get told about it)
mkosi: rework how we pass roothash/usrhash/other metadata to kernel-install
Previously, we'd replace the main kernel-install script with one
generated by mkosi and pass the roothash/usrhash as final argument on
the command line. That's less than ideal though, since it collides with
the documented way kernel-install dropins are called (those arguments
are initrds, not root hashes according to the docs). Moreover, it leaves
no nice way to pass usrhash vs. roothash or pass other information.
Let's fix this all, by changing the script to look for the roothash in
$ROOTHASH and the usrhash in $USRHASH. Then pass these env vars when
invoking the script, and drop any additional arguments.
Also, add the $IMAGE_ID and $IMAGE_VERSION in a similar fashion and then
use those preferably to name the generated kernel images.
With all this in place we are fully "standards-compliant" again,
matching the documented kernel-install drop-in API, the kernel images
are named a lot more nicely, and the usrhash logic starts working too.
mkosi: make sure to mount /root/ from outside if UsrOnly=
When using mkosi in build script mode we copy stuff into /root/, as
that's where we build things in. In UsrOnly= mode that directory is not
persistent though, which makes the excercise pointless. Hence, in
UsrOnly= mode let's mount /root/ from a persistent directory from our
workspace.
This is a recent addition in systemd, required to make cases work where
the initrd creates a root fs on first boot and images are initially
shipped without one.
(See https://github.com/systemd/systemd/pull/19234)
While we are at it, let's order the list of extra initrd files
alphabetically.
mkosi: if we have an image id (any maybe image version) use it to label partitions
This makes a lot of conceptual sense (since labels probably should
better declare what you find *in* a partition instead of just a
description of the type of it, because we already can generate that
automatically from the GPT UUID).
But it's also useful in conjunction with systemd's logic of always
picking the newest version of a root partition to mount in
systemd-nspawn and related commands, i.e.
https://github.com/systemd/systemd/pull/18958
On top of that this is useful in combination with SplitArtifacts=as then
the partitions and the split files will carry the same (except for the
suffix).
mkosi: add "image-id" concept in addition to "image-version"
A previous commit added an image version concept. Let' build on that and
add "image-id" too to match this systemd PR:
https://github.com/systemd/systemd/pull/19093
The image ID is used for naming the enerating artifacts if that's not
explicitly set (instead of the generic "image" as before) and is passed
to th build scripts via an IMAGE_ID env var matching the IMAGE_VERSION
the earlier commit added.
The idea is that the image version and ID passed here is ultimately
written to /etc/os-release by the build script (possibly mangled) and
the mkosi concepts for this hence ultimately propagate into the image
itself in some form even if not 1:1 (depending on the project of
course).
mkosi: add new --auto-bump switch for automatically bumping version after each successful build
Often it make sense to combine "build" and "bump" into one, so that the
a series of builds comes with a linearly increasing series of version
numbers. Add a new switch --auto-bump for that (or -B in short).
mkosi: add "mkosi bump" verb for bumping the image version
This is a simple verb that reads the image version, and increases the
last dot-separated component of it by one and writes it to
mkosi.version. It's supposed to be a very simple call only for linear
version bumps. For anything more complex people should manually edit the
file or override it temporarily via --image-version= or so.
This adds a "image version" concept to mkos. Via the
ImageVersion=/--image-version= settings or the `mkosi.version` file a
version string may be defined. This is used for two things:
1. It is included in the (default) output filename. i.e. instead of
"image.raw" the files will be called "image-0.1.raw" for a version of
"0.1" and so on.
2. It is passed as IMAGE_VERSION to the build script (the script could
use it and patch it into /etc/os-release or so for example)
(In case you wonder why this is called ImageVersion=/--image-version=
instead of just Version=/--version, that's because there's already a
command line switch for the latter that prints mkosi's own version
number)
This fixes two issues with UsrOnly=yes builds that are bootable and have
verity:
1. use the right partition type uuid for the verity partition
2. fix the umount path when we invoke dracut in a /usr-only build, since
"umount --recursive" insists on having a mount point at the specified
path, which we previously didn't necessarily. Let's add a bind mount
on itself there to address this.
Frantisek Sumsal [Tue, 23 Mar 2021 15:55:48 +0000 (16:55 +0100)]
Attempt to retry the SSH connection if the veth/SSH server is not up yet
This commit introduces a new option `--ssh-timeout=` to allow setting
a timeout for which `mkosi` will attempt to retry the SSH connection in
case the link not properly set up yet (e.g. when running `mkosi qemu` and
`mkosi ssh` in a script, the veth may not be configured yet, causing the
ssh connection to fail).
Frantisek Sumsal [Tue, 16 Mar 2021 18:01:46 +0000 (19:01 +0100)]
Allow overriding the SSH key pair
Allow using a pre-defined SSH key pair instead of generating a new one.
This should be useful, for example, in CI environments, where the images
are built and used at different times, and using the same SSH key pair
across multiple images is more convenient.
mkosi: add UsrOnly= setting for generating images with only a /usr/ partition
This adds a new boolean option that changes our image layout slightly:
instead of include the whole root fs in the image, we just pack up the
/usr/ subtree.
This has two usecases:
1. Truly stateless systems that come up pristine on every single boot,
where /etc and /var are populated by tmpfiles/sysusers and related
calls
2. Systems that are shipped without root fs, but where systemd-repart
adds one in, with a locally generated encryption key and so on. (this
doesn't work fully yet, because of some initrd issues, will look at
this later.)
A companion PR on the systemd side is: https://github.com/systemd/systemd/pull/18958
Fixes: #634
(This incorporates many fixes by @behrmann. Thank you!)
Nicolas Trangez [Thu, 11 Mar 2021 13:37:49 +0000 (14:37 +0100)]
Include `systemd.volatile` infrastructure in initrd
For the `systemd.volatile=...` feature to work, the
`systemd-volatile-root` generator and `systemd-volatile-root.service`
service are required to be present. Booting a read-only image generated
by `mkosi` (e.g., `gpt_ext4` built with the `--read-only` flag, or a
`gpt_squashfs` image) with a volatile but mutable overlay is useful, so
we need to provide these files in the `initrd` Dracut generates.
Hence, adding both files to `DRACUT_SYSTEMD_EXTRAS`.
Liam McBirnie [Sun, 28 Feb 2021 20:43:27 +0000 (21:43 +0100)]
Fix generated root partition being too small for encrypted images.
Building encrypted minimized or squashfs images was failing
at the 'dd' command in 'insert_partition' with the
error 'No space left on device'.
Increasing the luks overhead from 2MB to 16MB allows enough space.
16MB was found to be the smallest overhead which wouldn't fail.
Liam McBirnie [Sun, 28 Feb 2021 20:31:00 +0000 (21:31 +0100)]
Fix incorrect arguments given to 'luks_format_root'.
Commit 99453d9c added a 'cached' parameter to the 'luks_format_root'
command but didn't add the paramter to where the command is called
inside 'insert_partition'.
This patch sets 'cached' to False and fixes 'inserting_generated_root'
which should be True.
Liam McBirnie [Sun, 28 Feb 2021 20:24:40 +0000 (21:24 +0100)]
Reread partition table after inserting partition.
Fixes issue where the sfdisk command fails to re-read the partition
table when creating a squashfs image with encrypted data.
This is because the encrypted data partition is mounted so sfdisk gives
the warning 'Device or resource busy'.
This causes the 'dd' command failing because it can't find the newly
created partition.
mkosi: add new simple "serve" verb for serving built images via HTTP
If found this quite useful for testing things with "machinectl pull-tar"
and "machinectl pull-raw": add a tiny HTTP server that can serve the
generated output once it#s done. Love the simplicity of this:
Apparently we have to flush things explicitly after writing it,
otherwise things remain buffered by python IO and the SHA256SUMS file
will remain empty on disk.
Frantisek Sumsal [Mon, 22 Feb 2021 21:42:59 +0000 (22:42 +0100)]
Check if btrfs is available before trying to unlink a subvolume
otherwise the output is full of pointless errors on certain systems
(like CentOS 8, which doesn't support btrfs):
# mkosi --force --debug run --qemu-headless=true build
‣ Removing output files...
+ btrfs subvol show /home/vagrant/mkosi/mkosi.output/fedora.raw
‣ Error: btrfs not found in PATH.
...
‣ Configuring serial tty (ttyS0)...
‣ Cleaning dnf metadata......
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/log/dnf.log
‣ Error: btrfs not found in PATH.
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/cache/dnf
‣ Error: btrfs not found in PATH.
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/log/dnf.librepo.log
‣ Error: btrfs not found in PATH.
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/log/hawkey.log
‣ Error: btrfs not found in PATH.
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/lib/dnf
‣ Error: btrfs not found in PATH.
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/log/dnf.rpm.log
‣ Error: btrfs not found in PATH.
‣ Cleaning rpm metadata......
+ btrfs subvol show /var/tmp/mkosi-polqexiq/root/var/lib/rpm
‣ Error: btrfs not found in PATH.
‣ Resetting machine ID...
...
Frantisek Sumsal [Thu, 25 Feb 2021 15:33:48 +0000 (16:33 +0100)]
Allow overriding # of CPUs and amount of RAM for qemu guests
This commit introduces two options - `--qemu-smp` and `--qemu-mem` - which
can be used to override the default number of CPUs and amount of RAM for
guests started via the `qemu` verb.
This commit extends CommandLineArguments with all necessary fields
from the argument parser, removes the inheritance from argparse.Namespace
and fixes all resulting typing errors.
We try to stick to typing only changes as much as possible to reduce the
chance of breaking something (although there are a few non-typing changes
where doing so made things easier).
Because we use a dataclass now for the CommandLineArguments class, we
up the required python version to 3.7.
After:
sudo mkosi -d centos -r 7 --bootable --force
‣ Error: Sorry, CentOS 7 does not support unified kernel images. You must use --without-unified-kernel-images.
Michal Koutný [Fri, 12 Feb 2021 17:01:45 +0000 (18:01 +0100)]
openSUSE: Fix autologin setup
The distro PAM config resides under /usr/etc and customizations are
supposed to be under /etc. Use the distro file as a template for the
autologin customization.
Daan De Meyer [Wed, 3 Feb 2021 23:12:54 +0000 (23:12 +0000)]
qemu: Add secure boot support
Adds support for booting OVMF firmware blobs with secure boot
support.
We have to point qemu to an OVMF vars file to get this working.
Currently, we point directly at the vars file in /usr/share but
add the readonly flag so we make sure we don't modify it. I'm
hoping this means the UEFI variable changes in the VM will be
ephmeral instead of writes to these variables failing when the
readonly flag is set. If readonly means we can't enroll secure-boot,
we'll need to make a copy of the VARS file and store it somewhere so
we can remove the readonly flag.
Daan De Meyer [Wed, 3 Feb 2021 22:03:15 +0000 (22:03 +0000)]
qemu: Use q35 machine
This is necessary for booting with secure boot enabled in QEMU.
Switching to q35 somehow changed the boot order causing us to drop
into the EFI shell at boot. To fix this, I switched from virtio-blk
to virtio-scsci-pci (which is supposed to be the future anyway)
which allows us to set bootindex to override the boot order.
Joerg Behrmann [Sat, 23 Jan 2021 17:50:36 +0000 (18:50 +0100)]
mkosi: switch to RawConfigParser instead of ConfigParser
To allow for expanding systemd.unit like specifier like %u for user, we have to
disable the basic interpolation that configparser allows, because it too uses %
as its specifier.
Daan De Meyer [Sat, 23 Jan 2021 20:36:40 +0000 (20:36 +0000)]
Add support for passing arguments to the build command
Aside from environment variables, it's also useful to be able to
pass arguments to the build script. For example, in systemd we can
use this to pass the target to build to the build script. Build
scripts determine how the passed arguments are interpreted, mkosi
just passes them on.
Michal Koutný [Thu, 21 Jan 2021 17:52:43 +0000 (18:52 +0100)]
UEFI boot: make sure efivarfs loaded in initrd
The efivarfs is needed in order to GPT root partition discovery work.
Without efivarfs initrd won't be able to switch to the real root.
Add the module regardless of hostonly or distro configuration because
dracut takes into account info from the build host and not the target
distro. Adding a module that's already included in dracut's list makes
no harm.
Daan De Meyer [Thu, 21 Jan 2021 19:23:28 +0000 (19:23 +0000)]
Drop networkd not running to a warning instead of a fatal error
Without networkd, the veth link won't come up properly on the host
but that doesn't prevent mkosi boot or mkosi qemu from working so
let's drop those messages to warnings instead of fatal errors.
Daan De Meyer [Tue, 12 Jan 2021 20:36:16 +0000 (21:36 +0100)]
Remove "complete" steps from output
The next step start message implies the end of the previous step so
there's no real benefit to printing a complete message for every step.
Let's remove the message and only print a "complete" message if the
caller of complete_step() has provided a custom "complete" message.
Daan De Meyer [Sat, 9 Jan 2021 15:52:48 +0000 (16:52 +0100)]
Cache more operations
Let's cache all steps that write data directly from the config file.
This improves consistency overall and reduces noise in the output
when doing incremental builds.
Daan De Meyer [Sat, 9 Jan 2021 14:28:33 +0000 (15:28 +0100)]
Only print step execution messages if we're executing them
Replace some usage of completestep decorator with complete_step
contextmanager so we only print the step message after checking
if we actually need to execute the step.
Daan De Meyer [Fri, 15 Jan 2021 20:04:45 +0000 (21:04 +0100)]
Cache sshd enable step
We can't cache the ssh-keygen step easily because it outputs a
file on the host. However, we can cache the enable sshd step as
it only affects the image and not the host.
Daan De Meyer [Thu, 14 Jan 2021 20:18:03 +0000 (21:18 +0100)]
Don't cache --ssh setup step
Caching the SSH step is non-trivial because it adds an extra file
(the private key file) that has to be taken into account in the
caching logic. For now, let's not cache the step and silence the
stdout of the ssh-keygen command instead.
Daan De Meyer [Wed, 6 Jan 2021 17:17:11 +0000 (18:17 +0100)]
Remove "quiet" and "rhgb" from default kernel cmdline
We seem to be running into boot issues semi-regularly in CI because
of the usage of systemd.volatile=overlay. These issues are hard to
debug because we silence boot output by default. Let's enable boot
output by default so we have an easier time debugging these issues
when they occur. Also, mkosi boot shows the same output on
container startup anyway so this brings qemu more in line with mkosi
boot as well.
Daan De Meyer [Tue, 5 Jan 2021 21:07:50 +0000 (22:07 +0100)]
Search for "mkosi.default.d" relative to working directory
Searching for the mkosi.default.d dir relative to the file passed
via --default makes it almost impossible to share common settings
between multiple configs when using --default as simply specifying
a config file via --default changes the location where common configs
are searched. Instead, let's simply look for mkosi.default.d in the
mkosi working directory regardless of the path passed to --default.
Daan De Meyer [Sun, 27 Dec 2020 17:47:49 +0000 (18:47 +0100)]
Arch: Remove network configuration
Let's pull Arch in line with the other distros and not do any network
configuration. If needed, we can add this back, but let's do it behind
an option that we implement for all distros so we at least have uniformity
between distros.
Daan De Meyer [Fri, 25 Dec 2020 15:49:33 +0000 (16:49 +0100)]
Drop centos from CI (but not centos_epel)
centos_epel should be sufficient testing for centos as well. By
dropping centos, we can test SSH in CI without needing extra logic
to exclude centos from the SSH tests because networkd isn't available
on stock centos without epel.