#!/usr/bin/python3 # # Copyright (C) 2022 Red Hat, Inc. # SPDX-License-Identifier: LGPL-2.1-or-later import os from anacondalib import INSTALLER_VM_MEMORY_MB, VirtInstallMachineCase, disk_images, pixel_tests_ignore, run_boot from installer import Installer from review import Review from storage import EFI_PARTITION_DEFAULT_SIZE, EFI_PARTITION_DEFAULT_SIZE_MB, Storage from storagelib import StorageCase # pylint: disable=import-error from testlib import nondestructive, skipImage, test_main # pylint: disable=import-error from utils import move_standard_fedora_disk_to_MBR_disk, move_standard_fedora_disk_to_win_disk, pretend_default_scheme TEST_DIR = os.path.dirname(__file__) ROOT_DIR = os.path.dirname(TEST_DIR) BOTS_DIR = f'{ROOT_DIR}/bots' @nondestructive class TestStorageMountPoints(VirtInstallMachineCase, StorageCase): @run_boot("bios", "efi") @disk_images([("", 15), ("fedora-43", "15")]) @skipImage("btrfs support missing on fedora-eln image", "fedora-eln-boot") def testBasic(self): """ Description: Test the basic functionality of the mount point mapping table. Expected results: - The mount point mapping table is displayed correctly. - The user can select a device / mount point / format type. - The user can add and remove rows. - The 'Next' button is disabled when the mount point mapping table is not valid. - Swap partitions are not selectable for the required mount point rows. - The review screen should show the correct mountpoints and devices """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) dev = "vdb" i.open() i.reach(i.steps.INSTALLATION_METHOD) s.select_mountpoint([("vda", False), ("vdb", True)]) # verify gathered requests # root partition is not auto-mapped s.check_mountpoint_row(1, "/", "Select a device", True) s.select_mountpoint_row_device(1, "root") s.check_mountpoint_row_format_type(1, "btrfs") next_idx = 2 def select_boot_mountpoints(next_idx=next_idx): if self.is_efi: s.select_mountpoint_row_device(next_idx, f"{dev}2") s.check_mountpoint_row_format_type(next_idx, "EFI System Partition") next_idx += 1 s.check_mountpoint_row(next_idx, "/boot", "Select a device", False) s.select_mountpoint_row_device(next_idx, f"{dev}3") s.check_mountpoint_row_format_type(next_idx, "ext4") next_idx += 1 return next_idx next_idx = select_boot_mountpoints() s.add_mountpoint_row() s.select_mountpoint_row_device(next_idx, "home") s.check_mountpoint_row_reformat(next_idx, False) s.select_mountpoint_row_mountpoint(next_idx, "/home") s.check_mountpoint_row_format_type(next_idx, "btrfs") # Toggle reformat option s.select_mountpoint_row_reformat(next_idx - 1) if self.is_efi: s.select_mountpoint_row_reformat(next_idx - 2) # FIXME: https://github.com/cockpit-project/cockpit/pull/21392 # b.assert_pixels( # "#app", # "mount-point-mapping-table", # ignore=pixel_tests_ignore, # ) if self.is_efi: i.next(should_fail=True) i.reach(i.steps.REVIEW) # verify review screen r.check_disk(dev, "16.1 GB vdb (Virtio Block Device)") next_idx = 2 if self.is_efi: r.check_disk_row(dev, "/boot/efi", f"vdb{next_idx}", "105 MB", True, "efi") next_idx += 1 r.check_disk_row(dev, "/boot", f"vdb{next_idx}", "2.10 GB", True, "ext4") r.check_disk_row(dev, "/", f"vdb{next_idx + 1}", "11.8 GB", True, "btrfs subvolume") r.check_disk_row(dev, "/home", f"vdb{next_idx + 1}", "11.8 GB", False) applied_partitioning = s.dbus_get_applied_partitioning() # When re-entering the mount points mapping page new partitioning should be created, # but the previous selection should be preserved i.reach_on_sidebar(i.steps.INSTALLATION_METHOD) s.select_mountpoint([("vda", False), ("vdb", True)]) s.check_mountpoint_row(1, "/", "root", True) next_idx = 2 if self.is_efi: s.check_mountpoint_row(next_idx, "/boot/efi", f"{dev}2", False) next_idx += 1 s.check_mountpoint_row(next_idx, "/boot", f"{dev}3", False) if self.is_efi: i.next(should_fail=True) i.next() new_applied_partitioning = s.dbus_get_applied_partitioning() self.assertNotEqual(new_applied_partitioning, applied_partitioning) # When going back and forward 'Next' button should not be disabled # https://bugzilla.redhat.com/show_bug.cgi?id=2242086 i.back(previous_page=i.steps.CUSTOM_MOUNT_POINT) i.check_next_disabled(False) # Swap partitions should not be selectable for the required mount point rows # https://bugzilla.redhat.com/show_bug.cgi?id=2239836 i.back() disk = "/dev/vdb" m.execute(f"sgdisk --new=0:0:0 {disk}") m.execute(f"mkswap {disk}5") s.rescan_disks() s.select_mountpoint([("vda", False), ("vdb", True)]) s.check_mountpoint_row_device_available(1, f"{dev}5", True, True) def _testNoRootMountPoint_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) # EFI system partition, /boot on ext4, / on xfs, /home on btrfs disk = "/dev/vda" s.partition_disk(disk, [(EFI_PARTITION_DEFAULT_SIZE, "efi"), ("1GiB", "ext4"), ("10GiB", "xfs"), ("", "ext4")]) def testNoRootMountPoint(self): """ Description: Test the case when the root mount point is not selected. Expected results: - The 'Next' button is disabled when the mount point mapping table does not contain a root mount point. - When the user deselects reformat for "/" and goes next/back, the reformat choice is preserved (rhbz#2443812). """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) i.open() i.reach(i.steps.INSTALLATION_METHOD) dev = "vda" s.select_mountpoint([(dev, True)]) # verify gathered requests s.select_mountpoint_row_device(2, f"{dev}1") s.select_mountpoint_row_device(3, f"{dev}2") s.check_mountpoint_row(1, "/", "Select a device", True) s.check_mountpoint_row(2, "/boot/efi", f"{dev}1", False, "EFI System Partition") s.check_mountpoint_row(3, "/boot", f"{dev}2", False, "ext4") # Test moving back and forth between screens. i.back() i.next(next_page=i.steps.CUSTOM_MOUNT_POINT) s.check_mountpoint_row(1, "/", "Select a device", True) s.check_mountpoint_row(2, "/boot/efi", f"{dev}1", False, "EFI System Partition") s.check_mountpoint_row(3, "/boot", f"{dev}2", False, "ext4") s.add_mountpoint_row() s.select_mountpoint_row_device(4, f"{dev}4") s.check_mountpoint_row_format_type(4, "ext4") s.select_mountpoint_row_mountpoint(4, "/home") s.check_mountpoint_row_reformat(4, False) i.check_next_disabled() # BZ#2443812: deselected reformat for "/" is maintained after next/back. s.select_mountpoint_row_device(1, f"{dev}3") s.select_mountpoint_row_reformat(1, False) i.next(next_page=i.steps.ACCOUNTS) i.back(previous_page=i.steps.CUSTOM_MOUNT_POINT) s.check_mountpoint_row_reformat(1, False) def _testMultipleDisks_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) # EFI system partition, /boot partition, / disk1 = "/dev/vda" s.partition_disk(disk1, [(EFI_PARTITION_DEFAULT_SIZE, "efi"), ("1GiB", "xfs"), ("", "xfs")]) # /dev/vdb1 /home partition disk2 = "/dev/vdb" s.partition_disk(disk2, [("", "xfs")]) @disk_images([("", 15), ("", 10)]) def testMultipleDisks(self): """ Description: Tests the case when multiple disks are selected, and also checks that bootloader partition requirements are correctly enforced Expected results: - The mount point mapping scenario is available and can be used with multiple disks - FIXME: The bootloader requirements (EFI system partition) are verified for the selected disk[s] """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) dev1 = "vda" dev2 = "vdb" i.open() i.reach(i.steps.INSTALLATION_METHOD) # FIXME: Currently we don't check the partition constraints for mountable partitions, # we only check that the biosboot requirement is met for BIOS installations # # # Select only vdb disk and verify that mount point assignment is # # not available (missing EFI system partition) # s.select_disks([(dev1, False), (dev2, True)]) # s.wait_scenario_available("mount-point-mapping", False) # Select only vda disk and verify that the partitioning request is correct s.select_mountpoint([(dev1, True), (dev2, False)]) s.check_mountpoint_row_device_available(1, "vdb1", False) s.check_mountpoint_row_device_available(1, "vda3") # Go back and change the disk selection. The partitioning should be re-created i.back() s.select_mountpoint([(dev1, True), (dev2, True)]) s.check_mountpoint_row_device_available(1, "vda2", True) s.check_mountpoint_row_device_available(1, "vdb1") s.select_mountpoint_row_device(1, f"{dev1}3") s.check_mountpoint_row(1, "/", f"{dev1}3", True, "xfs") s.select_mountpoint_row_device(2, f"{dev1}1") s.check_mountpoint_row(2, "/boot/efi", f"{dev1}1", False, "EFI System Partition") s.select_mountpoint_row_device(3, f"{dev1}2") s.check_mountpoint_row(3, "/boot", f"{dev1}2", False, "xfs") s.add_mountpoint_row() s.select_mountpoint_row_device(4, f"{dev2}1") s.select_mountpoint_row_mountpoint(4, "/home") s.check_mountpoint_row(4, "/home", f"{dev2}1", False, "xfs") i.reach(i.steps.REVIEW) # verify review screen disk = "vda" r.check_disk(disk, "16.1 GB vda (Virtio Block Device)") r.check_disk_row(disk, "/boot/efi", "vda1", EFI_PARTITION_DEFAULT_SIZE_MB, False) r.check_disk_row(disk, "/boot", "vda2", "1.07 GB", False) r.check_disk_row(disk, "/", "vda3", "14.5 GB", True, "xfs") disk = "vdb" r.check_disk(disk, "10.7 GB vdb (Virtio Block Device)") r.check_disk_row(disk, "/home", "vdb1", "10.7 GB", False) b.assert_pixels( "#app", "review-multiple-disks", ignore=pixel_tests_ignore, ) def _testPayloadSizeCheck_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) # EFI system partition, /boot partition, / disk1 = "/dev/vda" s.partition_disk(disk1, [(EFI_PARTITION_DEFAULT_SIZE, "efi"), ("1GiB", "xfs"), ("1GiB", "xfs"), ("1GiB", "xfs"), ("", "xfs")]) @disk_images([("", 15)]) def testPayloadSizeCheck(self): """ Description: Test free space check Expected results: - A warning about insufficient space is showed to the user on the review screen - The warning prevents continuing with the installation - There are hints beside the checked mount points in case of failed check - The link for changing partitioning layout moves user to the right page """ b = self.browser m = self.machine i = Installer(b, m, scenario="mount-point-mapping") s = Storage(b, m) r = Review(b, m) i.open() i.reach(i.steps.INSTALLATION_METHOD) dev = "vda" s.select_mountpoint([(dev, True)]) # perform assignment with not enough space on mount points # single mount point used to count the required space s.select_mountpoint_row_device(1, f"{dev}3") s.select_mountpoint_row_device(2, f"{dev}1") s.select_mountpoint_row_device(3, f"{dev}2") i.reach(i.steps.REVIEW) r.check_size_error() # check that there is a hint with required size beside the device r.check_disk_row(dev, "/", f"{dev}3", "1.07 GB", True, "xfs", is_encrypted=False) r.check_disk_mount_point_helper_text(dev, "/", "Needs at least") # check that it is not possible to continue on the next page (install) i.check_next_disabled() b.click(f"#{i.steps.REVIEW}-next-confirmation-checkbox") i.check_next_disabled() ##### go back on sidebar to installation method and update the assignment i.click_step_on_sidebar(i.steps.INSTALLATION_METHOD) s.select_mountpoint([(dev, True)]) # modify assignment adding small "/usr", still not enough space on mount points # two mount points used to count the required space s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(4, "/usr") s.select_mountpoint_row_device(4, f"{dev}4") s.select_mountpoint_row_reformat(4) i.reach(i.steps.REVIEW) r.check_size_error() # check that there is a hint suitable for multiple devices r.check_disk_row(dev, "/", f"{dev}3", "1.07 GB", True, "xfs", is_encrypted=False) r.check_disk_mount_point_helper_text(dev, "/", "May need more free space") r.check_disk_row(dev, "/usr", f"{dev}4", "1.07 GB", True, "xfs", is_encrypted=False) r.check_disk_mount_point_helper_text(dev, "/usr", "May need more free space") # check that it is not possible to continue on the next page (install) i.check_next_disabled() b.click(f"#{i.steps.REVIEW}-next-confirmation-checkbox") i.check_next_disabled() ###### go back by alert button and update the assignment b.click(f"#{i.steps.REVIEW}-change-partition-layout") # modify assignment adding big enough "/usr" # two mount points used to count the required space s.select_mountpoint_row_device(4, f"{dev}5") i.reach(i.steps.REVIEW) r.check_size_error(False) # check that it is possible to continue on the next page (install) i.check_next_disabled() b.click(f"#{i.steps.REVIEW}-next-confirmation-checkbox") i.check_next_disabled(False) def _testEncryptedUnlock_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk1 = "/dev/vda" s.partition_disk( disk1, [(EFI_PARTITION_DEFAULT_SIZE, "efi"), ("1GiB", None), ("1GiB", None), ("1GiB", None), ("1GiB", "xfs")], ) s.create_luks_partition(f"{disk1}2", "einszwei", "encrypted-vol0", "xfs") s.create_luks_partition(f"{disk1}3", "einszweidrei", "encrypted-vol1", "xfs") s.create_luks_partition(f"{disk1}4", "einszweidreivier", "encrypted-vol2", "xfs") def testEncryptedUnlock(self): """ Description: Test 'Mount point mapping' with encrypted partitions Expected results: - The 'Unlock' dialog is available for unlocking the partitions before entering the mount point mapping - The user can unlock the disk using a passphrase. - The user can select the unlocked devices in the mount point mapping table. - The review screen should show the correct mountpoints and devices """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) dev1 = "vda" i.open() i.reach(i.steps.INSTALLATION_METHOD) s.unlock_all_encrypted() s.unlock_device("1234", ["vda2", "vda3", "vda4"], []) b.click("#unlock-device-dialog-close-btn") s.unlock_all_encrypted() s.unlock_device("einszwei", ["vda2", "vda3", "vda4"], ["vda2"]) # The 'Unlock' dialog should stay open unless all LUKS devices are unlocked s.unlock_device("einszweidrei", ["vda3", "vda4"], ["vda3"]) # The 'Unlock' dialog closes when all LUKS devices are unlocked s.unlock_device("einszweidreivier", ["vda4"], ["vda4"]) s.select_mountpoint([(dev1, True)]) b.wait_not_present(f"#{i.steps.CUSTOM_MOUNT_POINT}-table tbody tr:nth-child(4) td[data-label='Format type'] #unlock-luks-btn") self._testEncryptedUnlock(b, m) def _testEncryptedUnlock(self, b, m): dev1 = "vda" i = Installer(b, m) s = Storage(b, m) r = Review(b, m) s.check_mountpoint_row_mountpoint(2, "/boot/efi") s.check_mountpoint_row_mountpoint(3, "/boot") s.select_mountpoint_row_device(2, f"{dev1}1") s.select_mountpoint_row_device(3, f"{dev1}5") s.check_mountpoint_row_mountpoint(1, "/") toggle_selector = f"#{i.steps.CUSTOM_MOUNT_POINT}-table-row-1-device-select-toggle:not([disabled]):not([aria-disabled=true])" b.click(toggle_selector) b.click(".pf-v6-c-menu__content li:nth-of-type(3) button") b.wait_not_present(".pf-v6-c-menu") b.wait_js_func("ph_text", f"#{i.steps.CUSTOM_MOUNT_POINT}-table-row-1 .pf-v6-c-select__toggle-text", "luks") s.check_mountpoint_row_format_type(1, "xfs") i.reach(i.steps.REVIEW) r.check_disk_row(dev1, "/", "vda2", "", True, "xfs", True) def testEncryptedUnlockCockpit(self): """ Description: Test 'Mount point mapping' with encrypted partitions created using Cockpit Storage Expected results: - The user can create an encrypted partition with cockpit storage - The 'Unlock' dialog is available for unlocking the partitions before entering the mount point mapping - The user can unlock the disk using a passphrase - The user can selected the unlocked devices in the mount point mapping table - The review screen should show the correct mountpoints and devices """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) _r = Review(b, m) # noqa: F841 i.open() i.reach(i.steps.INSTALLATION_METHOD) s.check_disk_selected("vda") s.modify_storage() s.confirm_entering_cockpit_storage() b.wait_visible(".cockpit-storage-integration-sidebar") s.check_constraint("/", True) s.check_constraint("/boot/efi", True) s.check_constraint("/boot", False) frame = "iframe[name='cockpit-storage']" b._wait_present(frame) b.switch_to_frame("cockpit-storage") b._wait_present("#storage.ct-page-fill") self.click_dropdown(self.card_row("Storage", 1), "Create partition table") self.confirm() self.click_dropdown(self.card_row("Storage", 2), "Create partition") self.dialog({"size": 524, "type": "efi", "mount_point": "/boot/efi"}) # FIXME: Cockpit uses MB/GB for units whereas anaconda uses MiB/GiB, so # when anaconda backend recommends a 1GiB boot partition and Cockpit # creates a 1GB partition, it is rounded down to 931MiB and doesn't # meet the boot partition requirement, causing the test to fail. For # now, we create a 1100MiB partition to ensure the requirement is met, # but this should be addressed in the future by using consistent units # in both Cockpit and Anaconda. self.click_dropdown(self.card_row("Storage", 3), "Create partition") self.dialog({ "size": 1100, "type": "xfs", "crypto": self.default_crypto_type, "passphrase": "einszwei", "passphrase2": "einszwei", }) self.click_dropdown(self.card_row("Storage", 4), "Create partition") self.dialog({ "size": 1100, "type": "xfs", "crypto": self.default_crypto_type, "passphrase": "einszweidrei", "passphrase2": "einszweidrei", }) self.click_dropdown(self.card_row("Storage", 5), "Create partition") self.dialog({ "size": 1100, "type": "xfs", "crypto": self.default_crypto_type, "passphrase": "einszweidreivier", "passphrase2": "einszweidreivier", }) self.click_dropdown(self.card_row("Storage", 6), "Create partition") self.dialog({"size": 1100, "type": "ext4"}) # Exit the cockpit-storage iframe b.switch_to_top() s.return_to_installation() s.return_to_installation_confirm() i.wait_current_page(i.steps.INSTALLATION_METHOD) s.select_mountpoint([("vda", True)]) self._testEncryptedUnlock(b, m) def _testDuplicateDeviceNames_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk = "/dev/vda" btrfsname = "home" s.partition_disk( disk, [ (EFI_PARTITION_DEFAULT_SIZE, "efi"), ("1GiB", "ext4"), ("5GiB", "btrfs", "-f", "-L", "root"), ("5GiB", "btrfs", "-f", "-L", btrfsname), ("", "btrfs", "-f", "-L", btrfsname) ] ) @skipImage("btrfs support missing on fedora-eln image", "fedora-eln-boot") def testDuplicateDeviceNames(self): """ Description: Test the case when the devices with the same name exist Expected results: - The devices with the same name are displayed in the mount point mapping table - The user can select the devices with the same name in the mount point mapping table - The review screen should show the correct mountpoints and devices References: - https://bugzilla.redhat.com/show_bug.cgi?id=2237878 """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) btrfsname = "home" btrfs_volume_ids = s.get_btrfs_volume_ids(btrfsname) i.open() i.reach(i.steps.INSTALLATION_METHOD) s.select_mountpoint([("vda", True)]) s.select_mountpoint_row_device(1, "root") s.select_mountpoint_row_device(2, "vda1") s.select_mountpoint_row_device(3, "vda2") s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(4, "/home/joe") s.select_mountpoint_row_device(4, "home", device_id=btrfs_volume_ids[0]) s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(5, "/home/alan") s.select_mountpoint_row_device(5, "home", device_id=btrfs_volume_ids[1]) i.reach(i.steps.REVIEW) # verify review screen disk = "vda" r.check_disk(disk, "16.1 GB vda (Virtio Block Device)") r.check_disk_row(disk, "/boot/efi", "vda1", EFI_PARTITION_DEFAULT_SIZE_MB, False) r.check_disk_row(disk, "/boot", "vda2", "1.07 GB", False) r.check_disk_row(disk, "/", "vda3", "5.37 GB", True, "btrfs volume") r.check_disk_row(disk, "/home/joe", "vda4", "5.37 GB", False, "btrfs volume") r.check_disk_row(disk, "/home/alan", "vda5", "3.77 GB", False, "btrfs volume") def _testUnusableFormats_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk = "/dev/vda" s.partition_disk(disk, [(EFI_PARTITION_DEFAULT_SIZE, "efi"), ("1GiB", "ext4"), ("1GiB", None), ("1GiB", "lvmpv")]) def testUnusableFormats(self): """ Description: Test the case when the devices with unusable formats exist Expected results: - The devices with unusable formats are not displayed in the mount point mapping table """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) dev = "vda" i.open() i.reach(i.steps.INSTALLATION_METHOD) s.rescan_disks() s.select_mountpoint([(dev, True)]) # unformatted and unmountable devices should not be available s.check_mountpoint_row_device_available(1, f"{dev}3", False) s.check_mountpoint_row_device_available(1, f"{dev}4", False) def _testExtendedPartition_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) # Configure disk layout with a logical Btrfs partition disk = "/dev/vda" s.partition_disk( disk, [ ("512MiB", "efi"), ("1GiB", "ext4"), ("", "extended"), ("10GiB", "logical") ], is_mbr=True ) # Create subvolumes for the logical Btrfs partition m.execute(f""" mkfs.btrfs -f -L BTRFS {disk}5 mount {disk}5 /mnt btrfs subvolume create /mnt/root btrfs subvolume create /mnt/home umount /mnt """) def testExtendedPartition(self): """ Description: Test 'Mount point mapping' with a disk that has an extended partition Expected results: - The extended partition is not selectable - The other partitions are selectable """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) i.open() i.reach(i.steps.INSTALLATION_METHOD) s.select_mountpoint([("vda", True)]) s.select_mountpoint_row_device(1, "root") s.select_mountpoint_row_device(2, "vda1") s.select_mountpoint_row_device(3, "vda2") s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(4, "/home") s.select_mountpoint_row_device(4, "home") def _testVfatWithoutESP_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk = "/dev/vda" # Vfat partition, /boot on ext4, / on xfs s.partition_disk(disk, [(EFI_PARTITION_DEFAULT_SIZE, "vfat"), ("1GiB", "ext4"), ("", "xfs")]) def testVfatWithoutESP(self): """ Description: Test that assigning /boot/efi to a vfat partition without the ESP flag shows an appropriate error message. Expected results: - When a vfat partition without ESP type is selected for /boot/efi, an error about missing ESP marking is shown. """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) dev = "vda" i.open() i.reach(i.steps.INSTALLATION_METHOD) s.select_mountpoint([(dev, True)]) s.select_mountpoint_row_device(2, f"{dev}1") s.select_mountpoint_row_device(1, f"{dev}3") s.select_mountpoint_row_device(3, f"{dev}2") s.wait_mountpoint_table_column_helper(2, "device", text="must be on an EFI System Partition") def _testEncryptedHomeSecondDisk_partition_disk(self): b = self.browser m = self.machine s = Storage(b, m) disk1 = "/dev/vda" disk2 = "/dev/vdb" # On disk1: EFI, /boot (ext4), and root (xfs) s.partition_disk(disk1, [("512MiB", "efi"), ("1GiB", "ext4"), ("", "xfs")]) # On disk2: whole-disk LUKS with xfs inside (no partition table) m.execute(f"wipefs -a {disk2}") s.create_luks_partition(disk2, "homepass", "encrypted-home", "xfs") @disk_images([("", 15), ("", 10)]) def testEncryptedHomeSecondDisk(self): """ Description: Test encrypted /home reuse on a separate disk via 'Mount point mapping'. Expected results: - The 'Unlock' dialog is available and used to unlock the /home disk - The user can assign /boot, /boot/efi, and / on disk1 - The user can assign /home to the unlocked encrypted device on disk2 - The review screen shows /home as encrypted and mounted (not reformatted) References: - https://bugzilla.redhat.com/show_bug.cgi?id=2396646 """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) dev1 = "vda" dev2 = "vdb" i.open() i.reach(i.steps.INSTALLATION_METHOD) s.select_disks([(dev1, True), (dev2, True)]) # Unlock the encrypted second disk (home) s.unlock_all_encrypted() s.unlock_device("homepass", [f"{dev2}"], [f"{dev2}"]) # Proceed to mount point mapping with both disks selected s.select_mountpoint() # Assign /, /boot/efi and /boot on disk1 s.select_mountpoint_row_device(1, f"{dev1}3") next_idx = 2 s.select_mountpoint_row_device(next_idx, f"{dev1}1") s.check_mountpoint_row_format_type(next_idx, "EFI System Partition") next_idx += 1 s.select_mountpoint_row_device(next_idx, f"{dev1}2") s.check_mountpoint_row_format_type(next_idx, "ext4") next_idx += 1 # Add and assign /home to the unlocked encrypted device on disk2 s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(next_idx, "/home") luks_device = s.get_luks_device_name(f"/dev/{dev2}") s.select_mountpoint_row_device(next_idx, luks_device) # Verify review shows /home as encrypted and mounted on disk2 i.reach(i.steps.REVIEW) r.check_disk(dev1, "16.1 GB vda (Virtio Block Device)") r.check_disk_row(dev1, "/boot/efi", f"{dev1}1", "537 MB", False, "efi") r.check_disk_row(dev1, "/boot", f"{dev1}2", "1.07 GB", False, "ext4") r.check_disk_row(dev1, "/", f"{dev1}3", "14.5 GB", True, "xfs") r.check_disk(dev2, "10.7 GB vdb (Virtio Block Device)") r.check_disk_row(dev2, "/home", "", "10.7 GB", False, "xfs", is_encrypted=True, action="mount") # TODO: these tests should be made nondestructive class TestStorageMountPointsDestructive(VirtInstallMachineCase, StorageCase): provision = {"machine1": {"memory_mb": INSTALLER_VM_MEMORY_MB}} def _testMBRParttable_partition_disk(self): storage = Storage(self.browser, self.machine) move_standard_fedora_disk_to_MBR_disk(storage, self.machine, "vda", "vdb") @disk_images([("", 15), ("fedora-rawhide", 15)]) # https://fedoraproject.org/wiki/Changes/Anaconda_Drop_Support_UEFI_on_MBR # Fedora installer has phased out support for booting in UEFI mode on MBR-partitioned disks. @run_boot("bios") def testMBRParttable(self): """ Description: Test the case when the disk is MBR partitioned. Expected results: - The mount point mapping scenario is available and can be used with MBR partitioned disks. """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) # This is required for home-reuse availability check pretend_default_scheme(self, "BTRFS") i.open() i.reach(i.steps.INSTALLATION_METHOD) s.wait_scenario_available("mount-point-mapping", True) s.select_mountpoint([("vda", True), ("vdb", False)]) s.select_mountpoint_row_device(1, "root") s.select_mountpoint_row_device(2, "vda1") s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(3, "/home") s.select_mountpoint_row_device(3, "home") s.select_mountpoint_row_reformat(2) i.reach(i.steps.REVIEW) # verify review screen disk = "vda" r.check_disk(disk, "16.1 GB vda (Virtio Block Device)") r.check_disk_row(disk, "/boot", "vda1", "1.07 GB", True, "ext4") r.check_disk_row(disk, "/", "vda2", "14.0 GB", True, "btrfs subvolume") r.check_disk_row(disk, "/home", "vda2", "14.0 GB", False, "btrfs subvolume") def _testWindowsSingleDiskHomeReuse_partition_disk(self): storage = Storage(self.browser, self.machine) move_standard_fedora_disk_to_win_disk(storage, self.machine, "vda", "vdb") @disk_images([("", 35), ("fedora-rawhide", 15)]) def testWindowsSingleDiskHomeReuse(self): """ Description: Test home reuse via 'Mount point mapping' installation method with a disk containig dual boot setup with Windows and Fedora (shared EFI partition). Expected results: - The mount point mapping scenario is available and can be used for reuse of the home partition. - The home reuse expected layout is shown in the review screen """ b = self.browser m = self.machine i = Installer(b, m) s = Storage(b, m) r = Review(b, m) i.open() i.reach(i.steps.INSTALLATION_METHOD) s.wait_scenario_available("mount-point-mapping", True) s.select_mountpoint([("vda", True), ("vdb", False)]) s.select_mountpoint_row_device(1, "root") s.select_mountpoint_row_device(2, "vda1") s.select_mountpoint_row_device(3, "vda4") s.select_mountpoint_row_reformat(3) s.add_mountpoint_row() s.select_mountpoint_row_mountpoint(4, "/home") s.select_mountpoint_row_device(4, "home") s.check_mountpoint_row_reformat(4, False) i.next(should_fail=True) i.reach(i.steps.REVIEW) dev_win_fed = "vda" r.check_disk(dev_win_fed, f"37.6 GB {dev_win_fed} (Virtio Block Device)") r.check_disk_row(dev_win_fed, "/boot/efi", f"{dev_win_fed}1", "105 MB", False, "vfat", is_encrypted=False, action="mount") r.check_disk_row(dev_win_fed, "/boot", f"{dev_win_fed}4", "1.07 GB", True, "ext4", is_encrypted=False) r.check_disk_row(dev_win_fed, "/home", f"{dev_win_fed}5", "14.0 GB", False, "btrfs subvolume", is_encrypted=False, action="mount") r.check_disk_row(dev_win_fed, "/", f"{dev_win_fed}5", "14.0 GB", True, "btrfs subvolume", is_encrypted=False) if __name__ == '__main__': test_main()