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
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:
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