#!/usr/bin/python3 # # Copyright (C) 2025 Red Hat, Inc. # SPDX-License-Identifier: LGPL-2.1-or-later from anacondalib import INSTALLER_VM_MEMORY_MB, VirtInstallMachineCase from installer import Installer from review import Review from storage import Storage from testlib import test_main, timeout # pylint: disable=import-error class TestStorageMountPointsBtrfs_E2E(VirtInstallMachineCase): provision = {"machine1": {"memory_mb": INSTALLER_VM_MEMORY_MB}} def _testPreserveHome_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk = "/dev/vda" tmp_mount = "/tmp/btrfs-mount-test" # GPT: 1: EFI, 2: btrfs volume s.partition_disk(disk, [("100MiB", "efi"), ("", "btrfs")]) m.execute(f""" set -ex mkdir -p {tmp_mount} mount {disk}2 {tmp_mount} btrfs subvolume create {tmp_mount}/root btrfs subvolume create {tmp_mount}/home # Create a nested subvolume in root to test bug 2394554 # First create the parent directories inside the root subvolume root_mount="{tmp_mount}/root_mount" mkdir -p "$root_mount" mount -o subvol=root {disk}2 "$root_mount" mkdir -p "$root_mount/var/lib" btrfs subvolume create "$root_mount/var/lib/machines" umount "$root_mount" rmdir "$root_mount" umount {tmp_mount} rmdir {tmp_mount} """) @timeout(1200) def testPreserveHome(self): """ Description: EFI install using mount point assignment. Map / to btrfs subvolume 'root', preserve existing btrfs subvolume 'home'. The root subvolume contains a nested subvolume 'root/var/lib/machines' to test that dependent devices are properly handled when the parent is reformatted. Related bug: https://bugzilla.redhat.com/show_bug.cgi?id=2394554 Expected results: - /boot/efi present - / on btrfs subvolume reformatted - /home preserved - Nested subvolume root/var/lib/machines is properly handled when root is reformatted """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) dev = "vda" i.open() i.reach(i.steps.INSTALLATION_METHOD) # Select the disk and enter mount point mapping s.select_mountpoint([(dev, True)]) # Assign root, efi, boot and home # Row 1: / s.select_mountpoint_row_device(1, "root") # Row 2: /boot or /boot/efi depending on firmware; we're EFI-only s.select_mountpoint_row_device(2, f"{dev}1") s.check_mountpoint_row_format_type(2, "EFI System Partition") s.remove_mountpoint_row(3, 3) # Remove default /boot row # Add /home row, select home subvol, do NOT reformat s.add_mountpoint_row() s.select_mountpoint_row_device(3, "home") s.select_mountpoint_row_mountpoint(3, "/home") # Review and install i.next(should_fail=True) i.reach(i.steps.REVIEW) r.check_disk(dev, "16.1 GB vda (Virtio Block Device)") r.check_disk_row(dev, "/boot/efi", f"{dev}1", "105 MB", False) r.check_disk_row(dev, "/", f"{dev}2", "16.0 GB", True, "btrfs subvolume") r.check_disk_row(dev, "/home", f"{dev}2", "16.0 GB", False) self.install(button_text="Apply mount point assignment and install", needs_confirmation=True) def _testReformatBtrfsVolume_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk = "/dev/vda" # GPT: 1: EFI, 2: ext4 for /boot, 3: btrfs volume for / s.partition_disk(disk, [("100MiB", "efi"), ("1GiB", "ext4"), ("", "btrfs")]) # Create a btrfs volume (not subvolume!) on partition 3 with label "root" # This is key - we're creating a BTRFS volume, not subvolumes within it # The bug occurs when reformatting a BTRFS volume (which changes its UUID) # Use -f to force overwrite since partition_disk already created a btrfs filesystem m.execute(f""" set -ex mkfs.btrfs -f -L root {disk}3 """) @timeout(1200) def testReformatBtrfsVolume(self): """ Description: EFI install using mount point assignment. Reformat a BTRFS volume (not subvolume) and assign it to /. This tests the scenario where the BTRFS volume UUID changes during reformatting. Related bug: https://bugzilla.redhat.com/show_bug.cgi?id=2496875 Expected results: - /boot/efi present - /boot on ext4 partition - / on reformatted btrfs volume - No error when generating kickstart after reformatting BTRFS volume """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) dev = "vda" i.open() i.reach(i.steps.INSTALLATION_METHOD) # Select the disk and enter mount point mapping s.select_mountpoint([(dev, True)]) # Assign mount points # Row 1: / on vda3 (btrfs volume) s.select_mountpoint_row_device(1, "root") # Enable reformat - this is what triggers the bug s.select_mountpoint_row_reformat(1, True) # Row 2: /boot/efi on vda1 s.select_mountpoint_row_device(2, f"{dev}1") s.check_mountpoint_row_format_type(2, "EFI System Partition") # Row 3: /boot on vda2 (ext4) s.select_mountpoint_row_device(3, f"{dev}2") s.select_mountpoint_row_reformat(3, True) # Review and install i.next(should_fail=True) i.reach(i.steps.REVIEW) self.install(button_text="Apply mount point assignment and install", needs_confirmation=True) if __name__ == '__main__': test_main()