From 449c67b4a24603afb74f21a85a0e81738a28b32b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Jan 2026 10:58:00 -0500 Subject: [PATCH] tmt: Add bootc-image-builder integration test for issue #1907 Add a TMT test that exercises the mount point check fix from PR #1904. The test builds a container image with an embedded disk.yaml that creates a partition layout WITHOUT a separate /boot partition - just root (/) with /boot/efi as a separate mount point. This partition layout triggers the bug from issue #1907 where bootc's empty rootfs verification would fail with: "Found entry in boot: efi" The issue was that when /boot is a directory on the root filesystem (not a separate partition), but /boot/efi IS a mount point on a different device, the old code incorrectly saw "efi" as a regular directory entry rather than recognizing it was a mount point boundary. Verified that temporarily reverting the fix from PR #1904 causes this test to fail with the expected error message. This was already fixed by https://github.com/bootc-dev/bootc/pull/1904/changes/ab65078675f4a3875d3063f5ea43f1a89eeb52d4 but we didn't realize at the time the scope. Closes: https://github.com/bootc-dev/bootc/issues/1907 Signed-off-by: Colin Walters --- tmt/plans/integration.fmf | 7 ++ tmt/tests/booted/test-bib-build.nu | 120 +++++++++++++++++++++++++++++ tmt/tests/tests.fmf | 7 ++ 3 files changed, 134 insertions(+) create mode 100644 tmt/tests/booted/test-bib-build.nu diff --git a/tmt/plans/integration.fmf b/tmt/plans/integration.fmf index 365e6618c..40ca2135e 100644 --- a/tmt/plans/integration.fmf +++ b/tmt/plans/integration.fmf @@ -159,4 +159,11 @@ execute: how: fmf test: - /tmt/tests/tests/test-32-install-to-filesystem-var-mount + +/plan-33-bib-build: + summary: Test building a qcow2 disk image with bootc-image-builder + discover: + how: fmf + test: + - /tmt/tests/tests/test-33-bib-build # END GENERATED PLANS diff --git a/tmt/tests/booted/test-bib-build.nu b/tmt/tests/booted/test-bib-build.nu new file mode 100644 index 000000000..7aa1871db --- /dev/null +++ b/tmt/tests/booted/test-bib-build.nu @@ -0,0 +1,120 @@ +# number: 33 +# tmt: +# summary: Test building a qcow2 disk image with bootc-image-builder +# duration: 45m +# require: +# - qemu-img +# +# This test validates that bootc-image-builder (bib) can successfully +# create disk images from the current booted image. This is a critical +# integration test to catch regressions like: +# https://github.com/bootc-dev/bootc/issues/1907 +# +# The key scenario tested here is a partition layout where /boot is a +# directory on the root filesystem (NOT a separate partition), but +# /boot/efi IS a separate mount point. The bug was that when bootc +# checked /boot, it found "efi" as a directory entry and failed to +# recognize it was actually a mount point on a different device. +# +use std assert +use tap.nu + +const BIB_IMAGE = "quay.io/centos-bootc/bootc-image-builder:latest" + +def main [] { + tap begin "bootc-image-builder qcow2 build test" + + let td = mktemp -d + cd $td + + # Copy the currently booted image to podman storage + print "=== Copying booted image to containers-storage ===" + bootc image copy-to-storage + + # Verify the image is in storage + let images = podman images --format json | from json + let bootc_img = $images | where Names != null | where { |img| + $img.Names | any { |t| $t == "localhost/bootc:latest" } + } + assert (($bootc_img | length) > 0) "Expected localhost/bootc image in podman storage" + + # Build a derived image that: + # 1. Removes bound images (bib runs isolated) + # 2. Embeds a disk.yaml that creates a layout WITHOUT a separate /boot partition + # This triggers the bug from issue #1907 where /boot is a directory on root + # and /boot/efi is a mount point + print "=== Building derived image with no-/boot-partition layout ===" + 'FROM localhost/bootc +RUN rm -rf /usr/lib/bootc/bound-images.d/* +RUN mkdir -p /usr/lib/bootc-image-builder && cat > /usr/lib/bootc-image-builder/disk.yaml << "DISKEOF" +# Partition layout without a separate /boot partition. +# This mimics the CentOS Automotive ukiboot layout and triggers issue #1907. +# The key is that /boot is a directory on root, but /boot/efi is a mount point. +.common: + partitioning: + guids: + - &bios_boot_partition_guid "21686148-6449-6E6F-744E-656564454649" + - &efi_system_partition_guid "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" + - &filesystem_data_guid "0FC63DAF-8483-4772-8E79-3D69D8477DE4" + +partition_table: + type: "gpt" + partitions: + - size: "1 MiB" + bootable: true + type: *bios_boot_partition_guid + - size: "501 MiB" + type: *efi_system_partition_guid + payload_type: "filesystem" + payload: + type: vfat + mountpoint: "/boot/efi" + label: "EFI-SYSTEM" + fstab_options: "umask=0077,shortname=winnt" + fstab_freq: 0 + fstab_passno: 2 + - size: "4 GiB" + type: *filesystem_data_guid + payload_type: "filesystem" + payload: + type: xfs + label: "root" + mountpoint: "/" + fstab_options: "ro" +DISKEOF +' | save Dockerfile + podman build -t localhost/bootc-bib-test . + + # Create output directory for bib + mkdir output + + # Run bootc-image-builder to create a qcow2 + # We use --local to pull from local containers-storage + # The embedded disk.yaml will be used for partitioning + print "=== Running bootc-image-builder ===" + let bib_image = $BIB_IMAGE + # Note: we disable SELinux labeling since we're running in a test VM + # and use unconfined_t to avoid permission issues + podman run --rm --privileged -v /var/lib/containers/storage:/var/lib/containers/storage --security-opt label=type:unconfined_t -v ./output:/output $bib_image --type qcow2 --local localhost/bootc-bib-test + + # Verify output was created + print "=== Verifying output ===" + let disk_path = "output/qcow2/disk.qcow2" + assert ($disk_path | path exists) $"Expected disk image at ($disk_path)" + + # Check the disk has reasonable virtual size (at least 4GB as per disk.yaml) + # Note: qcow2 files are sparse, so file size != virtual size + # We use qemu-img to get the actual virtual disk size + let info = qemu-img info --output=json $disk_path | from json + let virtual_size = $info | get virtual-size + print $"Disk image virtual size: ($virtual_size | into filesize)" + # The disk.yaml specifies ~4.5 GiB total, so virtual size should be at least 4 GiB + assert ($virtual_size > 4000000000) "Disk image virtual size seems too small" + + # Also print file size for reference (qcow2 is sparse/compressed) + let file_size = ls $disk_path | get size | first + print $"Disk image file size: ($file_size)" + + print "=== Success: bootc-image-builder created disk image ===" + tap ok +} diff --git a/tmt/tests/tests.fmf b/tmt/tests/tests.fmf index 2075740e7..319918962 100644 --- a/tmt/tests/tests.fmf +++ b/tmt/tests/tests.fmf @@ -89,3 +89,10 @@ - dosfstools - e2fsprogs test: bash booted/test-install-to-filesystem-var-mount.sh + +/test-33-bib-build: + summary: Test building a qcow2 disk image with bootc-image-builder + duration: 45m + require: + - qemu-img + test: nu booted/test-bib-build.nu