Skip to content

Allow bootctl and kernel-install to be called without /etc/machine-id present - #16687

Merged
keszybz merged 2 commits into
systemd:masterfrom
daandemeyer:bootloader-machine-id
Aug 18, 2020
Merged

keszybz merged 2 commits into
systemd:masterfrom
daandemeyer:bootloader-machine-id

Conversation

@daandemeyer

@daandemeyer daandemeyer commented Aug 6, 2020 •

Copy link
Copy Markdown
Collaborator

The machine-id is used to create a few directories and setup a default
loader entry in loader.conf. Having bootctl create the directories
itself is not particularly useful as it does not put anything in them
and bootctl install is not guaranteed to be called before an initramfs
tool like kernel-install so other programs will always need to have
logic to create the directories themselves if they happen to be called
before bootctl install is called.

On top of this, when using unified kernel images, these are installed to
$BOOT/EFI/Linux which removes the need to have the directories created
by bootctl at all. This further indicates that these directories should
be created by the program that puts something in them rather than by
bootctl.

Removing the machine-id dependency allows bootctl install to be called
even when there's no machine-id in the image. This is useful for image
builders such as mkosi which don't have a machine-id when
installing systemd-boot (via bootctl) because it should only be
generated by systemd when the final image is booted.

The default entry in loader.conf based on the machine-id in loader.conf
is also removed which shouldn't be a massive loss in usability overall.

Fixes #16658.

(I went on a little different route with this after thinking about it some more, I don't think bootctl should create these directories at all since there's no guarantee that bootctl install will be called before dracut/kernel-install/mkinitcpio/... so there's no point in creating the directories as all those other tools need logic to do that themselves in case they are called before bootctl install is called)

Comment thread src/kernel-install/kernel-install Outdated
@daandemeyer
daandemeyer force-pushed the bootloader-machine-id branch from 052840f to 96129f7 Compare August 7, 2020 17:11
Comment thread man/kernel-install.xml Outdated
Comment thread man/kernel-install.xml Outdated
@daandemeyer
daandemeyer force-pushed the bootloader-machine-id branch from 96129f7 to e522eda Compare August 7, 2020 17:26
@poettering

Copy link
Copy Markdown
Member

This reverts 341890d, which is fine by me. @keszybz

@daandemeyer can you mention in the commit msg, that the first commit is pretty much a revert of that commit?

Comment thread man/kernel-install.xml Outdated
Comment thread src/kernel-install/kernel-install Outdated
@poettering poettering added sd-boot/sd-stub/bootctl reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels Aug 10, 2020
The machine-id is used to create a few directories and setup a default
loader entry in loader.conf. Having bootctl create the directories
itself is not particularly useful as it does not put anything in them
and bootctl install is not guaranteed to be called before an initramfs
tool like kernel-install so other programs will always need to have
logic to create the directories themselves if they happen to be called
before bootctl install is called.

On top of this, when using unified kernel images, these are installed to
$BOOT/EFI/Linux which removes the need to have the directories created
by bootctl at all. This further indicates that these directories should
be created by the program that puts something in them rather than by
bootctl.

Removing the machine-id dependency allows bootctl install to be called
even when there's no machine-id in the image. This is useful for image
builders such as mkosi which don't have a machine-id when
installing systemd-boot (via bootctl) because it should only be
generated by systemd when the final image is booted.

The default entry in loader.conf based on the machine-id in loader.conf
is also removed which shouldn't be a massive loss in usability overall.

This commit reverts commit 341890d.
This allows kernel-install to be used by image builders such as mkosi
which don't have a machine-id available when they call kernel-install.
@daandemeyer
daandemeyer force-pushed the bootloader-machine-id branch from e522eda to 6f77906 Compare August 10, 2020 18:56
@johannbg

Copy link
Copy Markdown
Contributor

@daandemeyer if the presumption is that the Linux will always exist on the efi partition why not stop using machined-id altogether ( as opposed to fallback on it )? If the presumption is that the Linux directory does not exist in all cases then you are down the same spiral path as machined ID is, The UUID/PartUUID of the efi partion will always exist regardless of any content or directory structure that may reside efi partition thus the only thing that should be relied upon and used ( and probably would be better for some form of "rescue environment" ) and does not required multiple check for kernel-install to create if it does not exist.

@poettering you mentioned something about some convenience in your comment on #16658 convenience for what exactly? what is it improving or making more convenient?

@poettering

poettering commented Aug 11, 2020 •

Copy link
Copy Markdown
Member

@daandemeyer if the presumption is that the Linux will always exist on the efi partition why not stop using machined-id altogether ( as opposed to fallback on it )?

The machine ID is a good thing because it allows multiple Linux installations to conflict-freely use the same ESP/boot partition, because each is dropping their stuff into a private dir, named after the identifier that sets each installation apart: the machine ID. In some context where multi-boot scenarios are not relevant the machine ID doesn't make sense for this though, and my presumption is @daandemeyer is in such a situation, i.e. where images are built that only consist of one OS and one OS only. Hence, machine ID is preferable in most contexts, except when it is not available.

@poettering

Copy link
Copy Markdown
Member

PR looks good to me, but @keszybz should acknowledge this

@poettering
poettering requested a review from keszybz August 11, 2020 06:25
@daandemeyer

daandemeyer commented Aug 11, 2020 •

Copy link
Copy Markdown
Collaborator Author

@poettering Maybe something to consider is that I've read in a few places that you'd like to support A/B style partitioning setups with repart and I assume with mkosi as well in the future. Maybe that is a good argument to use the partition UUID instead of a fixed fallback since it keeps the bootloader/initramfs stuff of both partitions separate as well without requiring a machine-id to be available (assuming you'd want those to use different kernels and initrds in each partition which doesn't seem an unreasonable use case to me).

@poettering

Copy link
Copy Markdown
Member

@poettering Maybe something to consider is that I've read in a few places that you'd like to support A/B style partitioning setups with repart and I assume with mkosi as well in the future. Maybe that is a good argument to use the partition UUID instead of a fixed fallback since it keeps the bootloader/initramfs stuff of both partitions separate as well without requiring a machine-id to be available (assuming you'd want those to use different kernels and initrds in each partition which doesn't seem an unreasonable use case to me).

The model I am going for would use boot loader spec type #2 kernels only for A/B style setups. I think type #2 kernels are a lot nicer if you care about robustness, since you can drop them in and remove them atomically, because they are just one file. My thinking is that if you want A/B you want robustness and immutability, and hence also type #2 kernels.

Type #2 kernels already are placed in a single, fixed directory, without any machine ID logic. so the whole problem goes away there.

The way I see type #1 vs. type #2 boot entries is that type #1 means: hacker stuff, locally generated drop-ins, support for locally changed cmdlines, pet not cattle, multiboot supported, local identity. And type #2 means: cattle not pet, robustness, same systems everywhere, limited multiboot at best, immutability, generic identity.

And thus in type #1 we need the machine ID because things are locally generated/configured, and we need some key to discern local installations. But in type #2 we don't really need that, since there's no local config for any of this, every system gets the same immutable, robust stuff, and thus keying by local identity, i.e. local machine ID is not necessary.

Or to say this differently: in a general purpose distro like classic Fedora, you take a pre-compiled fedora kernel, attach a locally built initrd to it, a locally configured kernel cmdline and bind it all together under the local machine ID. But for the A/B capable systems I have in mind none of that happens locally. instead the vendor builds a unified kernel that boots exactly one verity root disk, and there's no local configuration any of that, and no local generation, it's the same, robust, simple thing everywhere.

Now the lines are blurry between the two cases, and I am sure there are people who want to mix things differently, and that's OK, but I just want to give some background where I want to go with the A/B stuff. And for that I don't want any local IDs at all basically...

@TriMoon

TriMoon commented Aug 13, 2020 •

Copy link
Copy Markdown

I know this is kind-of off-topic but related to the work being done, and didn't want to create a separate issue for it needlessly.

May i add an extra suggestion to this wip?
Moved my suggestion into #16759

@daandemeyer

Copy link
Copy Markdown
Collaborator Author

I just realized that even if we add the fallback logic to kernel-install, installation will work but subsequent removal when upgrading the kernel will break since by then there will be a machine id so kernel-install won't look in the correct location anymore when removing a kernel.

I still wonder if we shouldn't just replace the machine id usage in kernel-install with the PARTUUID of the root partition. That should be unique inside an image/block device and doesn't change before and after an image is booted.

@TriMoon

TriMoon commented Aug 18, 2020 •

Copy link
Copy Markdown

I still wonder if we shouldn't just replace the machine id usage in kernel-install with the PARTUUID of the root partition. That should be unique inside an image/block device and doesn't change before and after an image is booted.

Why not just replace the machine id with a GUID specially created for the loader-entry config? (each loader-entry config it's own GUID)
That way the loader-entry config and the kernel/initrd will be bound to each-other without any possibility of pollution, it will also be easy to remove that directory because the same GUID will be used by the loader-entry config using it.

Now that i think about it a bit more, maybe you should use separate GUID's per kernel and initrd files, because most of the time only the initrd is changed and the kernel can be re-used...
That would allow to make use of entries using the previous initrd ala "old kernel" distros used, but this time we get "current", "old" and now "previous" (see here) 😉

@keszybz keszybz removed the reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks label Aug 18, 2020

@keszybz keszybz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The big question is whether kernel-install will do the right thing now with grub2 installed. But I think it will. We'll need to triple-test this before the release.

I still wonder if we shouldn't just replace the machine id usage in kernel-install with the PARTUUID of the root partition. That should be unique inside an image/block device and doesn't change before and after an image is booted.

Yep, I think this might be a better choice than machine-id. But I think we can merge this PR, and consider changing that part later.

Comment thread man/kernel-install.xml
<para>The content of the file specifies the machine identification <replaceable>MACHINE-ID</replaceable>.</para>
<para>The content of this file specifies the machine identification
<replaceable>MACHINE-ID</replaceable>. If it cannot read <filename>/etc/machine-id</filename>,
kernel-install will use "Linux" as the machine ID instead.</para>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With "golden" installation images, the image will be initially created with /Linux/ in the path, and then on upgrades in the live machine, a path with /<machine-id>/ will be used. It isn't too bad, because we just get two directories in parallel. I guess that's OK.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is that noone will remove the files in that dir anymore if you go from an identity-less to an identity-full system...

@keszybz
keszybz merged commit f9536e6 into systemd:master Aug 18, 2020
@poettering

Copy link
Copy Markdown
Member

I still wonder if we shouldn't just replace the machine id usage in kernel-install with the PARTUUID of the root partition. That should be unique inside an image/block device and doesn't change before and after an image is booted.

Note that one thing systemd-repart does besides creating new partitions and growing them is "give partitions an identity". And that means you can ship a disk image with the partition uuid set to all zeroes, and repart will then fill them in for you with something better.

We used to have a TODO list item somewhere that was about initializing /etc/machine-id from the fs uuid of the root fs by default if /etc/machine-id is missing. I removed that TODO item eventually, realizing that on environments where the rootfs is an immutable image this made little sense, since in that case you want that each invocation of the same immutable image should get its own uuid...

@poettering

Copy link
Copy Markdown
Member

hmm, maybe a tweak to this should be that if $ESP/Linux exists we only use that dir, and not the machine id.

That basically would mean if you have it once we use it forever. And means that in setups where you have no machine ID initialized then you don#t get multiboot, ever. but that should be ok

@johannbg

Copy link
Copy Markdown
Contributor

We used to have a TODO list item somewhere that was about initializing /etc/machine-id from the fs uuid of the root fs by default if /etc/machine-id is missing. I removed that TODO item eventually, realizing that on environments where the rootfs is an immutable image this made little sense, since in that case you want that each invocation of the same immutable image should get its own uuid...

@poettering kernel-install needs to be able to repair itself which requires the tool to be able to recreate identical functional bootable setup based on the environment it resides in which one of the reason the PARTUUID is an better engineer choice and arguably should be used and even be the string that exists and is used in /etc/machine-id instead of the generated one. ( then it wont matter if /etc/machine-id exist or not )

@daandemeyer
daandemeyer deleted the bootloader-machine-id branch August 25, 2020 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

RFE: Option to use UUID instead of machine-id in bootctl, kernel-install

6 participants