projg2 / installkernel-gentoo

Gentoo fork of installkernel from debianutils
GNU General Public License v2.0
19 stars 7 forks source link

Plugin to update rEFInd configuration #16

Closed JohnTheCoolingFan closed 9 months ago

JohnTheCoolingFan commented 10 months ago

It would be awesome to make rEFInd configuration update automated with installkernel. I am using rEFInd and I would like to automate that.

There are a couple of options I have in mind.

  1. Update refind_linux.conf
  2. Update the refind config itself to add/replace a manual boot stanza with the new values.
Nowa-Ammerlaan commented 10 months ago

Yes! This is something I have been wanting to add, but since I have never used refind myself it is a bit difficult for me to verify proper functionality.

What we would need to do:

JohnTheCoolingFan commented 10 months ago

rEFInd supports the bls layout, as that's probably what I have been using previously. Also, it can autodetect UKIs in ESP, which I am currently using. The problem with this autodetection is that rEFInd doesn't detect the specific distro (gentoo) so it picks the default tux icon. This leads me to using a manual boot stanza, but I can't make it static as with each update the UKI file name changes (version, hash/id at the beginning).

Nowa-Ammerlaan commented 10 months ago

This leads me to using a manual boot stanza, but I can't make it static as with each update the UKI file name changes (version, hash/id at the beginning).

This hash/id at the beginning is the entry_token, it defaults to your machine-id (which should be static, but maybe in your case it somehow is not) . You can specify your own custom entry_token in /etc/kernel/entry-token.

rEFInd supports the bls layout, as that's probably what I have been using previously. Also, it can autodetect UKIs in ESP, which I am currently using. The problem with this autodetection is that rEFInd doesn't detect the specific distro (gentoo) so it picks the default tux icon.

Great! I wonder if it will automatically set the icon correctly if you set the entry_token to gentoo or something like this.

JohnTheCoolingFan commented 10 months ago

This hash/id at the beginning is the entry_token, it defaults to your machine-id (which should be static, but maybe in your case it somehow is not) . You can specify your own custom entry_token in /etc/kernel/entry-token.

Oh, thanks! Yes, that did work when generating the file. Although the man page says that it would also use the ID field in /etc/os-release, but it clearly didn't.

man 8 kernel-install:

       --entry-token=
           Controls how to name and identify boot loader entries for this kernel installation or deletion. Takes one of "auto", "machine-id", "os-id",
           "os-image-id", or an arbitrary string prefixed by "literal:" as argument.

           <...>

           If set to auto (the default), the /etc/kernel/entry-token (or $KERNEL_INSTALL_CONF_ROOT/entry-token) file will be read if it exists, and the
           stored value used. Otherwise if the local machine ID is initialized it is used. Otherwise IMAGE_ID= from os-release will be used, if set.
           Otherwise, ID= from os-release will be used, if set. Otherwise a randomly generated machine ID is used.
Nowa-Ammerlaan commented 10 months ago

I've been reading our wiki page on refind, and from this I understand that we actually don't have to really do anything to have refind find our newly installed kernels. We do have to ensure that the layout we use is compat, grub or uki. If I understand correctly bls is not supported.

We do have to worry about the icon file, because layout=uki installs to EFI/Linux which is not vendored as Gentoo. Plus the ESP may be mounted at /boot in which case refind can't find the associated /etc/os-release

I think the following plugins should do the trick for getting the icon right both for the case where the ESP is mounted at /boot and for the case where we are installing UKIs to EFI/Linux:

For traditional installkernel (/etc/kernel/postinst.d/95-refind-copy-icon.install):

#!/usr/bin/env bash

# Copyright 2020-2024 Gentoo Authors
# this file is installed by sys-kernel/installkernel

ver=${1}
img=${2}

# familiar helpers, we intentionally don't use Gentoo functions.sh
die() {
    echo -e " ${NOCOLOR-\e[1;31m*\e[0m }${*}" >&2
    exit 1
}

main() {
    # re-define for subst to work
    [[ -n ${NOCOLOR+yes} ]] && NOCOLOR=

    [[ ${EUID} -eq 0 ]] || die "Please run this script as root"

        for dir in /boot/EFI /boot/efi /boot /efi; do
                # If this kernel was moved by 90-uki-copy.install
                local uki_path="${dir}/EFI/Linux/gentoo-$(basename ${img#*-})"
        if [[ -f "${uki_path}" ]]; then
            cp "/usr/lib64/refind/refind/icons/os_gentoo.png" "${uki_path%.efi}.png" || die
                        exit 0
        fi
    done

        # If this kernel was not moved by 90-uki-copy.install
        cp "/usr/lib64/refind/refind/icons/os_gentoo.png" "${img}.png" || die "Failed to copy icon file" 
}

main

For systemd's kernel-install (/usr/lib/kernel/install.d/95-refind-copy-icon.install):

#!/usr/bin/env bash

# Copyright 2023-2024 Gentoo Authors
# this file is installed by sys-kernel/installkernel

COMMAND="${1}"
KERNEL_VERSION="${2}"
BOOT_DIR_ABS="${3}"
KERNEL_IMAGE="${4}"

ICON="/usr/lib64/refind/refind/icons/os_gentoo.png"

if [[ ${KERNEL_INSTALL_LAYOUT} == "compat" || ${KERNEL_INSTALL_LAYOUT} == "grub" ]]; then
    KERNEL_INSTALL_BOOT_ROOT="/boot"
    if [[ ${COMMAND} == add ]]; then
        cp "${ICON}" "${KERNEL_INSTALL_BOOT_ROOT}/kernel-${KERNEL_VERSION}.png" || exit 1
    elif [[ ${COMMAND} == remove ]]; then
        rm -f "${KERNEL_INSTALL_BOOT_ROOT}/kernel-${KERNEL_VERSION}.png" || exit 1
    fi
elif [[ ${KERNEL_INSTALL_LAYOUT} == "uki" ]]; then
    UKI_DIR="${KERNEL_INSTALL_BOOT_ROOT}/EFI/Linux"
    if [[ ${COMMAND} == add ]]; then
        cp "${ICON}" "${UKI_DIR}/${KERNEL_INSTALL_ENTRY_TOKEN}-${KERNEL_VERSION}.png" || exit 1
    elif [[ ${COMMAND} == remove ]]; then
        rm -f "${UKI_DIR}/${KERNEL_INSTALL_ENTRY_TOKEN}-${KERNEL_VERSION}.png" || exit 1
    fi
fi

Would this be sufficient? If so, could you test this (with USE="-systemd -uki -ukify", USE="-systemd -uki ukify", USE="-systemd uki ukify", USE="systemd -uki -ukify", and USE="systemd -uki ukify", USE="systemd uki ukify")

JohnTheCoolingFan commented 10 months ago

Ah, I see, I was confused a bit in the terminology and didn't know what bls actually is. I assumed it was the "traditional" (in my view) layout with separate kernel, initrd, etc files in /boot.

I will try these plugins and configurations after I set up some backing up/snapshotting for the esp as well.

JohnTheCoolingFan commented 10 months ago

Great! I wonder if it will automatically set the icon correctly if you set the entry_token to gentoo or something like this.

Update on that. It still recognizes it as generic linux, with the tux icon.

Nowa-Ammerlaan commented 10 months ago

Great! I wonder if it will automatically set the icon correctly if you set the entry_token to gentoo or something like this.

Update on that. It still recognizes it as generic linux, with the tux icon.

That is unfortunate.

Looks like there has been some upstream discussion on reading the ˋ.osrelˋ section of the UKI to detect which distribution it boots: https://sourceforge.net/p/refind/discussion/general/thread/c3865a4e3a/

That would be the best solution, or lacking that simply reading it from the filename. The filename does include the ENTRY_TOKEN after all, which may be set to the os-id. It may be worth it to poke upstream a bit on the status of improving the os detection logic for UKIs. That way we would not need any plugins to get the icons right.

Nowa-Ammerlaan commented 10 months ago

I opened a PR to test the scripts I posted earlier, CI is green which means it is now correctly installing the logo file as I understand it should be installed. But it still needs testing to verify that refind will actually correctly pick up the icon file we install.

One thing I'm not sure about is if the icon filename should be gentoo-x.y.z-gentoo-dist.png or gentoo-x.y.z-gentoo-dist.efi.png if the accompanying kernel file is named gentoo-x.y.z-gentoo-dist.efi. The wiki mentions "the base name" which suggest that we can ignore the .efi suffix. But it would be great to verify this.

I made some small changes compared to the version I posted as a comment earlier, so when testing please use the version from the linked pull request.

JohnTheCoolingFan commented 9 months ago

Can I set USE="-systemd ..." for only installkernel? My system uses systemd a lot and I think removing that use flag would be a huge change to the system, especially since it's set from my profile.

Nowa-Ammerlaan commented 9 months ago

Can I set USE="-systemd ..." for only installkernel? My system uses systemd a lot and I think removing that use flag would be a huge change to the system, especially since it's set from my profile.

Yes, you don't have to make any global changes. With USE=-systemd installkernel will fallback to the traditional kernel installation script (instead of systemd's version). Toggling the flag on only sys-kernel/installkernel is enough.