Skip to content

Bootloader EFI discovery fails on RHEL 10.2 due to multiline string output #3003

@philptk

Description

@philptk

Description:
When building a RHEL 10.2 image, the build fails during the bootloader configuration step with an [Errno 22] Invalid argument error when Kiwi attempts to create the EFI vendor directory.

To Reproduce:
Build a RHEL 10.2 image using grub2 as the bootloader.
The build crashes during the bootloader setup phase.

Expected behavior:
The EFI vendor directory should be correctly identified and created without throwing a path error.

Error Log:
[ ERROR ]: 13:36:38 | KiwiFileAccessError: Cannot create directory: /var/tmp/kiwi_mount_manager.5s3bx8fw/boot/efi/EFI/Linux
/EFI/redhat: [Errno 22] Invalid argument: '/var/tmp/kiwi_mount_manager.5s3bx8fw/boot/efi/EFI/Linux\n'

Root Cause Analysis:
In RHEL 10.2, the compiled grubx64.efi binary contains multiple EFI paths (e.g., EFI/Linux for UKI/systemd-boot and EFI/redhat for classic grub).

In kiwi/bootloader/config/grub2.py, within the _copy_grub_config_to_efi_path method, Kiwi uses the strings command and grep EFI/ to dynamically find the vendor path. Because the binary contains multiple matches, the command returns a multiline string:
EFI/Linux\nEFI/redhat

The current code applies .strip(), but this only removes leading/trailing whitespaces, leaving the newline character \n in the middle of the string. When os.path.normpath tries to construct the path, it results in an invalid directory path.

Workaround / Proposed Fix:
I successfully bypassed this issue locally by implementing a workaround that splits the multiline string and grabs the last element before joining the path. In grub2.py (_copy_grub_config_to_efi_path), I applied the following:

                efi_boot_path = Command.run(
                    ['bash', '-c', ' '.join(bash_command)],
                    raise_on_error=False, raise_on_command_not_found=True
                ).output
                if efi_boot_path:
                    # Extract the final EFI path if multiple lines are returned
                    if '\n' in efi_boot_path:
                        efi_boot_path = efi_boot_path.strip().split('\n')[-1]

                    efi_boot_path = os.path.normpath(
                        os.sep.join([root_path, efi_boot_path.strip()])
                    )

This workaround successfully resolved the build error for me. However, I am not entirely sure if this is the cleanest or most robust way to solve this upstream, so I would appreciate your input on how to properly handle this scenario in the codebase.

Environment:
Host OS: Red Hat Enterprise Linux 10.2 (Coughlan)
Target OS: RHEL 10.2
KIWI version: 10.3.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions