OSInside / kiwi

KIWI - Appliance Builder Next Generation
https://osinside.github.io/kiwi
GNU General Public License v3.0
292 stars 148 forks source link

OEM ISO fails to build with systemd-boot #2281

Closed alexandrevicenzi closed 10 months ago

alexandrevicenzi commented 1 year ago

Problem description

It is not possible to build an OEM ISO (self install) if systemd-boot is used as the bootloader.

Expected behavior

OEM ISO builds with systemd-boot.

Steps to reproduce the behavior

Have an OEM image install ISO. Switch the bootloader from grub2 to systemd_boot. Set EFI partition size, as the kernel will be copied to it.

Example:

<preferences profiles="self-install" arch="x86_64,aarch64">
    <version>0.0.3</version>
    <packagemanager>zypper</packagemanager>
    <rpm-excludedocs>true</rpm-excludedocs>
    <locale>en_US</locale>
    <keytable>us</keytable>
    <timezone>Europe/Berlin</timezone>
    <bootloader-theme>openSUSE</bootloader-theme>
    <bootsplash-theme>bgrt</bootsplash-theme>
    <type
        image="oem"
        installiso="true"
        installboot="install"
        install_continue_on_timeout="false"
        initrd_system="dracut"
        filesystem="btrfs"
        fsmountoptions="compress=lzo,autodefrag"
        btrfs_root_is_snapshot="true"
        btrfs_quota_groups="true"
        bootpartition="false"
        firmware="efi"
        efipartsize="200"
        bootkernel="custom"
        devicepersistency="by-uuid"
        bundle_format="%N-VM.%A-%M.%m.%p-%I">
        <bootloader name="systemd_boot" timeout="10"/>
        <systemdisk>
            <volume name="home"/>
            <volume name="root"/>
            <volume name="tmp"/>
            <volume name="opt"/>
            <volume name="srv"/>
            <volume name="boot/efi" mountpoint="boot/efi"/>
            <volume name="usr/local"/>
            <volume name="var" copy_on_write="false"/>
        </systemdisk>
    </type>
</preferences>

Error:

[  115s] [ INFO    ]: 16:28:36 | Creating squashfs embedded disk image
[  115s] [ DEBUG   ]: 16:28:36 | EXEC: [cp -l /usr/src/packages/KIWI-oem/ALP-Automotive.x86_64-0.0.3.raw /usr/src/packages/KIWI-oem/kiwi_install_squashfs.a5v88t6f/ALP-Automotive.raw]
[  115s] [ DEBUG   ]: 16:28:36 | EXEC: [mksquashfs /usr/src/packages/KIWI-oem/kiwi_install_squashfs.a5v88t6f /usr/src/packages/KIWI-oem/ALP-Automotive.raw.squashfs -noappend -b 1M -comp xz -Xbcj x86]
[  185s] [ DEBUG   ]: 16:29:45 | EXEC: [mv /usr/src/packages/KIWI-oem/ALP-Automotive.raw.squashfs /usr/src/packages/KIWI-oem/kiwi_install_media.vsjfobpn]
[  185s] [ INFO    ]: 16:29:45 | Setting up install image bootloader configuration
[  185s] [ DEBUG   ]: 16:29:45 | "grub2-install": in paths "/usr/src/packages/KIWI-oem/build/image-root/sbin:/usr/src/packages/KIWI-oem/build/image-root/usr/sbin:/usr/src/packages/KIWI-oem/build/image-root/usr/local/sbin:/usr/src/packages/KIWI-oem/build/image-root/root/bin:/usr/src/packages/KIWI-oem/build/image-root/usr/local/bin:/usr/src/packages/KIWI-oem/build/image-root/usr/bin:/usr/src/packages/KIWI-oem/build/image-root/bin" exists: "False" mode match: not checked
[  185s] [ INFO    ]: 16:29:45 | Creating grub2 bootloader images
[  185s] [ DEBUG   ]: 16:29:45 | EXEC: [mkdir -p /usr/src/packages/KIWI-oem/kiwi_install_media.vsjfobpn/EFI/BOOT]
[  185s] [ INFO    ]: 16:29:45 | --> Creating identifier file 0x27f114f3
[  185s] [ DEBUG   ]: 16:29:45 | EXEC: [mkdir -p /usr/src/packages/KIWI-oem/kiwi_install_media.vsjfobpn/boot/grub]
[  185s] [ DEBUG   ]: 16:29:45 | Searching grub file: unicode.pf2
[  185s] [ DEBUG   ]: 16:29:45 | --> /usr/src/packages/KIWI-oem/build/image-root/usr/share/grub2/unicode.pf2
[  185s] [ DEBUG   ]: 16:29:45 | --> /usr/src/packages/KIWI-oem/build/image-root/usr/lib/grub2/unicode.pf2
[  185s] [ DEBUG   ]: 16:29:45 | --> /usr/src/packages/KIWI-oem/build/image-root/usr/share/grub/unicode.pf2
[  185s] [ DEBUG   ]: 16:29:45 | --> /usr/src/packages/KIWI-oem/build/image-root/usr/lib/grub/unicode.pf2
[  185s] [ ERROR   ]: 16:29:45 | KiwiBootLoaderGrubFontError: Setting up unicode font failed with grub path unicode.pf2 not found in ['/usr/src/packages/KIWI-oem/build/image-root/usr/share/grub2/unicode.pf2', '/usr/src/packages/KIWI-oem/build/image-root/usr/lib/grub2/unicode.pf2', '/usr/src/packages/KIWI-oem/build/image-root/usr/share/grub/unicode.pf2', '/usr/src/packages/KIWI-oem/build/image-root/usr/lib/grub/unicode.pf2']
[  185s] [ INFO    ]: 16:29:45 | Cleaning up FileSystemSquashFs instance
[  185s] [ INFO    ]: 16:29:45 | Cleaning up BootLoaderConfigGrub2 instance
[  185s] [ INFO    ]: 16:29:45 | Cleaning up BootImageDracut instance
[  185s] [ INFO    ]: 16:29:45 | Cleaning up BootImageDracut instance
[  185s] [ DEBUG   ]: 16:29:45 | EXEC: [mountpoint -q /usr/src/packages/KIWI-oem/build/image-root/dev]
[  185s] [ DEBUG   ]: 16:29:45 | EXEC: [mountpoint -q /usr/src/packages/KIWI-oem/build/image-root/proc]
[  185s] Failed to write wtmp record, ignoring: Read-only file system
[  185s] Failed to write utmp record: Read-only file system
[  185s] Powering off.
[  185s] [  180.826511][T10872] reboot: Power down

As shown in the error, even if the bootloader is not grub2, Kiwi still attempts to create a grub2 image, and it will fail because grub2 is not installed, nor the fonts.

OS and Software information

schaefi commented 1 year ago

yep ISO boot support through sd boot is not yet implemented as I wrote on the matrix channel.

Thanks for reporting

schaefi commented 1 year ago

As @Conan-Kudo said this might be not so easy to achieve because the sd-boot EFI module will probably not able to read the iso9660 filesystem. In case of grub, grub has support for reading it and so the grub EFI binary can do it. In case of sd-boot an EFI driver will be needed to natively support reading from the ISO. We don't have that and it is also outside of the kiwi scope to provide one.

alexandrevicenzi commented 1 year ago

Is there a way to create an ISO image with ISOLinux to boot, but once the installation happens, it would use sd-boot?

Using the self-install seems to be impossible, the only solution would be a full installer.

schaefi commented 10 months ago

Is there a way to create an ISO image with ISOLinux to boot, but once the installation happens, it would use sd-boot?

our fallback here is grub. Your build failed because no grub is installed. I know why you don't want grub because it's GPL3 but using systemd-boot means you want to boot via EFI (or the uboot that loads an efi binary on arm process). isolinux or syslinux don't boot in EFI mode only in legacy CSM or BIOS mode. Therefore the fallback with firmware="efi" is grub and the fallback with firmware="bios" is isolinux. Also isolinux does not exist on arm it's a pure x86 loader. Overall you would limit yourself with isolinux a lot. I'm sorry we are not changing that loader strategy for ISOs

Conan-Kudo commented 10 months ago

The only fully supported bootloader at this time is GRUB. Please use that.

schaefi commented 10 months ago

During hackweek I worked on trying to make systemd-boot to fly on ISO images but failed for the following reasons:

  1. bootctl install requires a FAT filesystem to put data in /boot/efi. There is afaik no option to say, don't check it. If you add EFI boot to an ISO it works in a way that you add an alternative boot image to xorriso which is a FAT image that contains the EFI layout and binary. With some trickery this might be possible with bootctl too

    qemu-img create fakedisk 20M
    gdisk fakedisk
    ==> create a partition
    ==> set EF00 code
    kpartx -a fakedisk
    mkdosfs -n BOOT /dev/mapper/loop0p1
    mount /dev/mapper/loop0p1 /mnt
    sudo bootctl install --esp-path /mnt/ --no-variables
    
    ---
    Created "/mnt/EFI".
    Created "/mnt/EFI/systemd".
    Created "/mnt/EFI/BOOT".
    Created "/mnt/loader".
    Created "/mnt/loader/entries".
    Created "/mnt/EFI/Linux".
    Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/mnt//EFI/systemd/systemd-bootx64.efi".
    Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/mnt//EFI/BOOT/BOOTX64.EFI".
    Created "/mnt/bc8499a73619491cb692083ffb3c3c24".
    Random seed file /mnt//loader/random-seed successfully written (512 bytes).
    ---
    
    umount /mnt
    dd if=/dev/mapper/loop0p1 of=efifat.img
    kpartx -d /dev/loop0
    losetup -d /dev/loop0
  2. And use this in xorriso as alternative loader, but then the next problem starts. There is no code in systemd-boot that can read from iso9660 natively. So if the alt loader in the ISO loads the embedded efi binary it will not be able to read anything from the ISO, kernel, initrd, config... grub provides support for all these but systemd-boot doesn't at the moment and to my knowledge

At this point I stopped investigating and I also find it very cumbersome to work with systemd-boot regarding ISO boot. I'm sure there will be something in the future that makes this more straight forward.

Conan-Kudo commented 10 months ago

cc: @DaanDeMeyer @davide125

DaanDeMeyer commented 10 months ago

systemd-boot is only ever going to read from FAT which is the only thing that UEFI supports natively. Last time I looked at this, the idea would be to use the appended_partition stuff in xorriso to append a FAT partition to the ISO image and boot from that with El Torito. I don't remember the specifics though.

schaefi commented 10 months ago

systemd-boot is only ever going to read from FAT which is the only thing that UEFI supports natively. Last time I looked at this, the idea would be to use the appended_partition stuff in xorriso to append a FAT partition to the ISO image and boot from that with El Torito. I don't remember the specifics though.

yes this is the way we support in kiwi and which I tried to adapt to the systemd-boot provided EFI binary, see the above snippet. It also works in a way that the produced ISO loads the EFI binary embedded into the fat image. But the systemd-boot provided binary that I used had no support reading from iso9660 filesystem, so the thing does not continue to boot

schaefi commented 10 months ago

But I have another idea and there is also the risk that I made a mistake. I'll give it another try and report back

schaefi commented 10 months ago

I got it to work :) pushed a work branch and need to finalize the code prior pull request