fix stage2 as default sources

This commit is contained in:
t_feng 2020-08-07 16:53:55 +08:00
parent 1b0586d1f1
commit 0018beb09f
3 changed files with 779 additions and 1 deletions

View File

@ -0,0 +1,127 @@
From 4e699fe30da24771b80ff1fe64d7791bcb444f79 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Tue, 21 Jul 2020 10:57:00 +0200
Subject: [PATCH] Allow to detect devices with the iso9660 file system as
optical media
Test that the DBus method FindOpticalMedia identifies devices with the iso9660 file
system as optical media, so it is able to find NVDIMM devices with iso9660.
The DBus method GetDevicesToIgnore of the NVDIMM module shouldn't return NVDIMM
devices with the iso9660 file system. They can be used as an installation source.
Protect all devices with the iso9660 file system. It will protect, for example, NVDIMM
devices with the iso9660 file system that can be used only as an installation source
anyway.
Related: rhbz#1856264
---
.../modules/storage/devicetree/model.py | 5 ++++
pyanaconda/modules/storage/nvdimm/nvdimm.py | 12 ++++++++-
.../module_device_tree_test.py | 27 ++++++++++++++++---
3 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/modules/storage/devicetree/model.py b/pyanaconda/modules/storage/devicetree/model.py
index 4d0ecdb..cdee5a8 100644
--- a/pyanaconda/modules/storage/devicetree/model.py
+++ b/pyanaconda/modules/storage/devicetree/model.py
@@ -303,6 +303,11 @@ class InstallerStorage(Blivet):
# cdroms, involves unmounting which is undesirable (see bug #1671713).
protected.extend(dev for dev in self.devicetree.devices if dev.type == "cdrom")
+ # Protect also all devices with an iso9660 file system. It will protect
+ # NVDIMM devices that can be used only as an installation source anyway
+ # (see the bug #1856264).
+ protected.extend(dev for dev in self.devicetree.devices if dev.format.type == "iso9660")
+
# Mark the collected devices as protected.
for dev in protected:
log.debug("Marking device %s as protected.", dev.name)
diff --git a/pyanaconda/modules/storage/nvdimm/nvdimm.py b/pyanaconda/modules/storage/nvdimm/nvdimm.py
index 0bbcc6e..4476dd1 100644
--- a/pyanaconda/modules/storage/nvdimm/nvdimm.py
+++ b/pyanaconda/modules/storage/nvdimm/nvdimm.py
@@ -21,6 +21,7 @@ import gi
gi.require_version("BlockDev", "2.0")
from gi.repository import BlockDev as blockdev
+from blivet import udev
from blivet.static_data import nvdimm
from pykickstart.constants import NVDIMM_ACTION_RECONFIGURE, NVDIMM_ACTION_USE
@@ -90,6 +91,9 @@ class NVDIMMModule(KickstartBaseModule):
installation, the device(s) must be specified by nvdimm kickstart
command. Also, only devices in sector mode are allowed.
+ Don't ignore devices that have an iso9660 file system. We might
+ want to use them as an installation source.
+
:return: a set of device names
"""
namespaces_to_use = self.get_namespaces_to_use()
@@ -97,7 +101,13 @@ class NVDIMMModule(KickstartBaseModule):
devices_to_ignore = set()
for ns_name, ns_info in nvdimm.namespaces.items():
- if ns_info.mode != blockdev.NVDIMMNamespaceMode.SECTOR:
+ info = udev.get_device(device_node="/dev/" + ns_info.blockdev)
+
+ if info and udev.device_get_format(info) == "iso9660":
+ log.debug("%s / %s won't be ignored - NVDIMM device has "
+ "an iso9660 file system", ns_name, ns_info.blockdev)
+ continue
+ elif ns_info.mode != blockdev.NVDIMMNamespaceMode.SECTOR:
log.debug("%s / %s will be ignored - NVDIMM device is not "
"in sector mode", ns_name, ns_info.blockdev)
elif ns_name not in namespaces_to_use and ns_info.blockdev not in devices_to_use:
diff --git a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
index 838c70e..5e52843 100644
--- a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
@@ -24,10 +24,10 @@ from unittest.mock import patch, Mock, PropertyMock
from tests.nosetests.pyanaconda_tests import patch_dbus_publish_object, check_task_creation
from blivet.devices import StorageDevice, DiskDevice, DASDDevice, ZFCPDiskDevice, PartitionDevice, \
- LUKSDevice, iScsiDiskDevice, NVDIMMNamespaceDevice, FcoeDiskDevice
+ LUKSDevice, iScsiDiskDevice, NVDIMMNamespaceDevice, FcoeDiskDevice, OpticalDevice
from blivet.errors import StorageError, FSError
from blivet.formats import get_format
-from blivet.formats.fs import FS
+from blivet.formats.fs import FS, Iso9660FS
from blivet.formats.luks import LUKS
from blivet.size import Size
@@ -627,9 +627,28 @@ class DeviceTreeInterfaceTestCase(unittest.TestCase):
str(cm.exception), "Failed to unmount dev1 from /path: Fake error."
)
- def find_install_media_test(self):
+ @patch.object(Iso9660FS, "check_module")
+ def find_install_media_test(self, check_module):
"""Test FindInstallMedia."""
- self.assertEqual(self.interface.FindOpticalMedia(), [])
+ dev1 = OpticalDevice("dev1")
+ dev1.size = Size("2 GiB")
+ dev1.format = get_format("iso9660")
+ dev1.controllable = True
+ self._add_device(dev1)
+
+ dev2 = StorageDevice("dev2")
+ dev2.size = Size("2 GiB")
+ dev2.format = get_format("iso9660")
+ dev2.controllable = True
+ self._add_device(dev2)
+
+ dev3 = StorageDevice("dev3")
+ dev3.size = Size("2 GiB")
+ dev3.format = get_format("ext4")
+ dev3.controllable = True
+ self._add_device(dev3)
+
+ self.assertEqual(self.interface.FindOpticalMedia(), ["dev1", "dev2"])
@patch.object(FS, "update_size_info")
def find_mountable_partitions_test(self, update_size_info):
--
2.23.0

View File

@ -0,0 +1,642 @@
From 5283a20d41050551b54d6d12960ac28e0e5e1648 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Tue, 21 Jul 2020 11:17:40 +0200
Subject: [PATCH] Fix stage2 as default sources
We should prioritize stage2 device as the default source.
This is especially needed for DVD ISO because it is booting
with inst.stage2 instead and we should use the DVD
as the source for the default CDROM.
The situation is even worse thanks to the fact that
DVD ISOs are using inst.stage2=hd:...
Find stage2 device and test this device first during
the auto-discover feature of CDRom source.
Resolves: rhbz#1856264
---
.../modules/payloads/source/cdrom/cdrom.py | 7 +-
.../payloads/source/cdrom/cdrom_interface.py | 7 +-
.../payloads/source/cdrom/initialization.py | 64 +++-
pyanaconda/modules/payloads/source/utils.py | 8 +-
.../modules/storage/devicetree/handler.py | 5 +-
.../storage/devicetree/handler_interface.py | 5 +-
pyanaconda/payload/utils.py | 2 +-
.../module_device_tree_test.py | 23 +-
.../module_source_cdrom_test.py | 286 ++++++++++++++++--
9 files changed, 362 insertions(+), 45 deletions(-)
diff --git a/pyanaconda/modules/payloads/source/cdrom/cdrom.py b/pyanaconda/modules/payloads/source/cdrom/cdrom.py
index 93df362..bb751ae 100644
--- a/pyanaconda/modules/payloads/source/cdrom/cdrom.py
+++ b/pyanaconda/modules/payloads/source/cdrom/cdrom.py
@@ -32,7 +32,12 @@ log = get_module_logger(__name__)
class CdromSourceModule(PayloadSourceBase, MountingSourceMixin, RPMSourceMixin):
- """The CD-ROM source payload module."""
+ """The CD-ROM source payload module.
+
+ This source will try to automatically detect installation source. First it tries to look only
+ stage2 device used to boot the environment then it will use first valid iso9660 media with a
+ valid structure.
+ """
def __init__(self):
super().__init__()
diff --git a/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py b/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py
index 0c5b6d7..74d2f14 100644
--- a/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py
+++ b/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py
@@ -25,7 +25,12 @@ from pyanaconda.modules.payloads.source.source_base_interface import PayloadSour
@dbus_interface(PAYLOAD_SOURCE_CDROM.interface_name)
class CdromSourceInterface(PayloadSourceBaseInterface):
- """Interface for the payload CD-ROM image source."""
+ """Interface for the payload CD-ROM image source.
+
+ This source will try to automatically detect installation source. First it tries to look only
+ stage2 device used to boot the environment then it will use first valid iso9660 media with a
+ valid structure.
+ """
def connect_signals(self):
super().connect_signals()
diff --git a/pyanaconda/modules/payloads/source/cdrom/initialization.py b/pyanaconda/modules/payloads/source/cdrom/initialization.py
index a182fcd..7fc38fc 100644
--- a/pyanaconda/modules/payloads/source/cdrom/initialization.py
+++ b/pyanaconda/modules/payloads/source/cdrom/initialization.py
@@ -15,13 +15,15 @@
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
+from pyanaconda.core.kernel import kernel_arguments
from pyanaconda.modules.common.constants.objects import DEVICE_TREE
from pyanaconda.modules.common.constants.services import STORAGE
from pyanaconda.modules.common.errors.payload import SourceSetupError
-from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask
from pyanaconda.modules.common.structures.storage import DeviceData
-from pyanaconda.payload.utils import mount, unmount, PayloadSetupError
+from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask
from pyanaconda.modules.payloads.source.utils import is_valid_install_disk
+from pyanaconda.payload.source.factory import SourceFactory, PayloadSourceTypeUnrecognized
+from pyanaconda.payload.utils import mount, unmount, PayloadSetupError
from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
@@ -37,13 +39,62 @@ class SetUpCdromSourceTask(SetUpMountTask):
return "Set up CD-ROM Installation Source"
def _do_mount(self):
- """Run CD-ROM installation source setup."""
- log.debug("Trying to detect CD-ROM automatically")
+ """Run CD-ROM installation source setup.
+ Try to discover installation media and mount that. Device used for booting (inst.stage2)
+ has a priority.
+ """
+ log.debug("Trying to detect CD-ROM automatically")
device_tree = STORAGE.get_proxy(DEVICE_TREE)
+
+ device_candidates = self._get_device_candidate_list(device_tree)
+ device_name = self._choose_installation_device(device_tree, device_candidates)
+
+ if not device_name:
+ raise SourceSetupError("Found no CD-ROM")
+
+ return device_name
+
+ def _get_device_candidate_list(self, device_tree):
+ stage2_device = self._probe_stage2_for_cdrom(device_tree)
+ device_candidates = device_tree.FindOpticalMedia()
+
+ if stage2_device in device_candidates:
+ device_candidates = [stage2_device] + device_candidates
+
+ return device_candidates
+
+ @staticmethod
+ def _probe_stage2_for_cdrom(device_tree):
+ # TODO: This is temporary method which should be moved closer to the inst.repo logic
+ log.debug("Testing if inst.stage2 is a CDROM device")
+ stage2_string = kernel_arguments.get("stage2")
+
+ if not stage2_string:
+ return None
+
+ try:
+ source = SourceFactory.parse_repo_cmdline_string(stage2_string)
+ except PayloadSourceTypeUnrecognized:
+ log.warning("Unknown stage2 method: %s", stage2_string)
+ return None
+
+ # We have HDD here because DVD ISO has inst.stage2=hd:LABEL=....
+ # TODO: Let's return back support of inst.cdrom=<device> which should work based on the
+ # documentation and use that as inst.stage2 parameter for Pungi
+ if not source.is_harddrive:
+ log.debug("Stage2 can't be used as source %s", stage2_string)
+ return None
+
+ # We can ignore source.path here because DVD ISOs are not using that.
+ stage2_device = device_tree.ResolveDevice(source.partition)
+ log.debug("Found possible stage2 default installation source %s", stage2_device)
+ return stage2_device
+
+ def _choose_installation_device(self, device_tree, devices_candidates):
device_name = ""
- for dev_name in device_tree.FindOpticalMedia():
+ for dev_name in devices_candidates:
try:
device_data = DeviceData.from_structure(device_tree.GetDeviceData(dev_name))
mount(device_data.path, self._target_mount, "iso9660", "ro")
@@ -57,7 +108,4 @@ class SetUpCdromSourceTask(SetUpMountTask):
else:
unmount(self._target_mount)
- if not device_name:
- raise SourceSetupError("Found no CD-ROM")
-
return device_name
diff --git a/pyanaconda/modules/payloads/source/utils.py b/pyanaconda/modules/payloads/source/utils.py
index b9642a9..5030fc5 100644
--- a/pyanaconda/modules/payloads/source/utils.py
+++ b/pyanaconda/modules/payloads/source/utils.py
@@ -84,10 +84,10 @@ def find_and_mount_device(device_spec, mount_point):
device_path = "/dev/" + matches[0]
try:
- # FIXME: Add back RO mounting. This was removed because we can't mount one source
- # RW and RO at the same time. This source is also mounted by IsoChooser dialog in the
- # SourceSpoke.
- mount(device_path, mount_point, "auto")
+ mount(device=device_path,
+ mountpoint=mount_point,
+ fstype="auto",
+ options="defaults,ro")
return True
except OSError as e:
log.error("Mount of device failed: %s", e)
diff --git a/pyanaconda/modules/storage/devicetree/handler.py b/pyanaconda/modules/storage/devicetree/handler.py
index 1fca6c0..453f27d 100644
--- a/pyanaconda/modules/storage/devicetree/handler.py
+++ b/pyanaconda/modules/storage/devicetree/handler.py
@@ -82,16 +82,17 @@ class DeviceTreeHandler(ABC):
msg = "Failed to tear down {}: {}".format(device_name, str(e))
raise DeviceSetupError(msg) from None
- def mount_device(self, device_name, mount_point):
+ def mount_device(self, device_name, mount_point, options):
"""Mount a filesystem on the device.
:param device_name: a name of the device
:param mount_point: a path to the mount point
+ :param options: a string with mount options or an empty string to use defaults
:raise: MountFilesystemError if mount fails
"""
device = self._get_device(device_name)
try:
- device.format.mount(mountpoint=mount_point)
+ device.format.mount(mountpoint=mount_point, options=options or None)
except FSError as e:
msg = "Failed to mount {} at {}: {}". format(
device_name,
diff --git a/pyanaconda/modules/storage/devicetree/handler_interface.py b/pyanaconda/modules/storage/devicetree/handler_interface.py
index 3839e17..2a16eb7 100644
--- a/pyanaconda/modules/storage/devicetree/handler_interface.py
+++ b/pyanaconda/modules/storage/devicetree/handler_interface.py
@@ -46,14 +46,15 @@ class DeviceTreeHandlerInterface(InterfaceTemplate):
"""
self.implementation.teardown_device(device_name)
- def MountDevice(self, device_name: Str, mount_point: Str):
+ def MountDevice(self, device_name: Str, mount_point: Str, options: Str):
"""Mount a filesystem on the device.
:param device_name: a name of the device
:param mount_point: a path to the mount point
+ :param options: a string with mount options or an empty string to use defaults
:raise: MountFilesystemError if mount fails
"""
- self.implementation.mount_device(device_name, mount_point)
+ self.implementation.mount_device(device_name, mount_point, options)
def UnmountDevice(self, device_name: Str, mount_point: Str):
"""Unmount a filesystem on the device.
diff --git a/pyanaconda/payload/utils.py b/pyanaconda/payload/utils.py
index e0c7d6c..eb94f79 100644
--- a/pyanaconda/payload/utils.py
+++ b/pyanaconda/payload/utils.py
@@ -71,7 +71,7 @@ def mount_device(device_name, mount_point):
:param str mount_point: a path to the mount point
"""
device_tree = STORAGE.get_proxy(DEVICE_TREE)
- device_tree.MountDevice(device_name, mount_point)
+ device_tree.MountDevice(device_name, mount_point, "ro")
def unmount_device(device_name, mount_point):
diff --git a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
index 33b06e8..838c70e 100644
--- a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
@@ -582,12 +582,29 @@ class DeviceTreeInterfaceTestCase(unittest.TestCase):
self._add_device(StorageDevice("dev1", fmt=get_format("ext4")))
with tempfile.TemporaryDirectory() as d:
- self.interface.MountDevice("dev1", d)
- mount.assert_called_once_with(mountpoint=d)
+ self.interface.MountDevice("dev1", d, "")
+ mount.assert_called_once_with(mountpoint=d, options=None)
mount.side_effect = FSError("Fake error.")
with self.assertRaises(MountFilesystemError) as cm:
- self.interface.MountDevice("dev1", "/path")
+ self.interface.MountDevice("dev1", "/path", "")
+
+ self.assertEqual(
+ str(cm.exception), "Failed to mount dev1 at /path: Fake error."
+ )
+
+ @patch.object(FS, "mount")
+ def mount_device_with_options_test(self, mount):
+ """Test MountDevice with options specified."""
+ self._add_device(StorageDevice("dev1", fmt=get_format("ext4")))
+
+ with tempfile.TemporaryDirectory() as d:
+ self.interface.MountDevice("dev1", d, "ro,auto")
+ mount.assert_called_once_with(mountpoint=d, options="ro,auto")
+
+ mount.side_effect = FSError("Fake error.")
+ with self.assertRaises(MountFilesystemError) as cm:
+ self.interface.MountDevice("dev1", "/path", "ro,auto")
self.assertEqual(
str(cm.exception), "Failed to mount dev1 at /path: Fake error."
diff --git a/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py b/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py
index 386322d..4c964a7 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py
@@ -124,6 +124,8 @@ class CdromSourceTestCase(unittest.TestCase):
class CdromSourceSetupTaskTestCase(unittest.TestCase):
+ # TODO: To avoid so much patching it would be great to split tests to parts and test those
+
mount_location = "/mnt/put-cdrom-here"
def setup_install_source_task_name_test(self):
@@ -156,8 +158,15 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
device_tree.FindOpticalMedia = Mock()
device_tree.FindOpticalMedia.return_value = [dev.name for dev in devices]
+ def _find_device_by_name(name):
+ for dev in devices:
+ if dev.name == name:
+ return DeviceData.to_structure(dev)
+
+ return None
+
device_tree.GetDeviceData = Mock()
- device_tree.GetDeviceData.side_effect = [DeviceData.to_structure(dev) for dev in devices]
+ device_tree.GetDeviceData.side_effect = _find_device_by_name
return device_tree
@@ -172,42 +181,261 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
This matches the logic in tested method.
"""
for n in range(num_called):
- self.assertIn(
- call("test{}".format(n)),
- device_tree_mock.GetDeviceData.mock_calls
- )
- self.assertIn(
- call("/dev/cdrom-test{}".format(n), self.mount_location, "iso9660", "ro"),
- mount_mock.mock_calls
- )
+ self._check_if_device_was_tried(device_tree_mock,
+ mount_mock,
+ "test{}".format(n))
for n in range(num_called, num_called + num_untouched):
- self.assertNotIn(
- call("test{}".format(n)),
- device_tree_mock.GetDeviceData.mock_calls
- )
- self.assertNotIn(
- call("/dev/cdrom-test{}".format(n), self.mount_location, "iso9660", "ro"),
- mount_mock.mock_calls
- )
+ self._check_if_device_was_not_tried(device_tree_mock,
+ mount_mock,
+ "test{}".format(n))
self.assertEqual(device_tree_mock.GetDeviceData.call_count, num_called)
self.assertEqual(mount_mock.call_count, num_called)
+ def _check_if_device_was_tried(self,
+ device_tree_mock,
+ mount_mock,
+ device_name):
+ self.assertIn(
+ call(device_name),
+ device_tree_mock.GetDeviceData.mock_calls
+ )
+
+ self.assertIn(
+ call("/dev/cdrom-{}".format(device_name), self.mount_location, "iso9660", "ro"),
+ mount_mock.mock_calls
+ )
+
+ def _check_if_device_was_not_tried(self,
+ device_tree_mock,
+ mount_mock,
+ device_name):
+ self.assertNotIn(
+ call(device_name),
+ device_tree_mock.GetDeviceData.mock_calls
+ )
+
+ self.assertNotIn(
+ call("/dev/cdrom-{}".format(device_name), self.mount_location, "iso9660", "ro"),
+ mount_mock.mock_calls
+ )
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - prioritize inst.stage2 CD-ROMs.
+
+ Add valid stage2 CDROM device and it has to be tested first.
+ """
+ kernel_arguments_mock.get.return_value = "hd:LABEL=my-cool-dvd"
+ device_tree = self.set_up_device_tree(2)
+ device_tree.ResolveDevice.return_value = "test1"
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ # Only one device was checked
+ device_tree.ResolveDevice.assert_called_once_with("LABEL=my-cool-dvd")
+
+ self._check_if_device_was_tried(device_tree, mount_mock, "test1")
+ self._check_if_device_was_not_tried(device_tree, mount_mock, "test0")
+
+ # First device (stage2 device) is valid one
+ valid_mock.assert_called_once()
+
+ # First device works so no unmount is called here
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test1")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_unrecognized_source_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - unrecognized stage2 source.
+
+ This should not happen but when we have the code there let's check it.
+ """
+ kernel_arguments_mock.get.return_value = "wrong source!"
+ device_tree = self.set_up_device_tree(1)
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ device_tree.ResolveDevice.assert_not_called()
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_not_hdd_source_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - stage2 is not HDD source.
+
+ We are testing HDD because DVD ISOs are created with inst.stage2=hd: . We want to change
+ this behavior on master so let's change this test too then.
+
+ TODO: Change this test when DVD ISOs will use cdrom:<device> instead of inst.stage2=hd:...
+ """
+ kernel_arguments_mock.get.return_value = "nfs:test.org:/super/cool/path"
+ device_tree = self.set_up_device_tree(1)
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ device_tree.ResolveDevice.assert_not_called()
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
@patch_dbus_get_proxy
- def choose_from_multiple_cdroms_test(self, proxy_getter, mount_mock, unmount_mock, valid_mock):
+ def priority_stage2_cant_be_resolved_source_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - can't resolve stage2 device.
+
+ Stage2 device can't be resolved. This should not happen but let's make sure the code works.
+ """
+ kernel_arguments_mock.get.return_value = "hd:LABEL=my-cool-dvd"
+ device_tree = self.set_up_device_tree(1)
+ proxy_getter.return_value = device_tree
+ # When device can't be resolved it returns an empty string.
+ device_tree.ResolveDevice.return_value = ""
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ self._check_if_device_was_not_tried(device_tree, mount_mock, "")
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_not_optical_media_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - stage2 is not optical media.
+
+ We should not pick stage2 device if it is not an optical_media which means type iso9660.
+ """
+ kernel_arguments_mock.get.return_value = "hd:LABEL=correct-device"
+ device_tree = self.set_up_device_tree(1)
+ device_tree.ResolveDevice.return_value = "not-optical-media"
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ device_tree.ResolveDevice.assert_called_once_with("LABEL=correct-device")
+
+ self._check_if_device_was_not_tried(device_tree, mount_mock, "correct-device")
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def choose_from_multiple_cdroms_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
"""Test CD-ROM Source setup installation source task run - choice from multiple CD-ROMs.
Fake four CD-ROM devices: First fails to mount, second has nothing useful, third has what
we want so is left mounted, fourth is entirely skipped.
The other two tests below are needed only to test the exit when nothing is found.
"""
+ kernel_arguments_mock.get.return_value = None
device_tree = self.set_up_device_tree(4)
proxy_getter.return_value = device_tree
-
mount_mock.side_effect = \
[PayloadSetupError("Mocked failure"), DEFAULT, DEFAULT, DEFAULT]
@@ -231,18 +459,24 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
# Test device name returned
self.assertEqual(result, "test2")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
@patch_dbus_get_proxy
- def failure_to_mount_test(self, proxy_getter, mount_mock, unmount_mock, valid_mock):
+ def failure_to_mount_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
"""Test CD-ROM Source setup installation source task run - mount failure.
Mocks one disk which fails to mount, expect exception.
"""
+ kernel_arguments_mock.get.return_value = None
device_tree = self.set_up_device_tree(1)
proxy_getter.return_value = device_tree
-
mount_mock.side_effect = PayloadSetupError("Mocked failure")
valid_mock.return_value = True
@@ -258,18 +492,24 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
# exception happened due to no disk
self.assertEqual(str(cm.exception), "Found no CD-ROM")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
@patch_dbus_get_proxy
- def no_cdrom_with_valid_source_test(self, proxy_getter, mount_mock, unmount_mock, valid_mock):
+ def no_cdrom_with_valid_source_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
"""Test CD-ROM Source setup installation source task run - no valid source CD-ROMs.
Mocks one CD-ROM device which has nothing useful, expect exception.
"""
+ kernel_arguments_mock.get.return_value = None
device_tree = self.set_up_device_tree(1)
proxy_getter.return_value = device_tree
-
valid_mock.return_value = False
with self.assertRaises(SourceSetupError) as cm:
--
2.23.0

View File

@ -1,7 +1,7 @@
%define _empty_manifest_terminate_build 0
Name: anaconda
Version: 33.19
Release: 2
Release: 3
Summary: Graphical system installer
License: GPLv2+ and MIT
URL: http://fedoraproject.org/wiki/Anaconda
@ -29,6 +29,9 @@ Patch9015: modify-network-hostname-dot-illegal.patch
Patch9016: disable-ssh-login-checkbox.patch
Patch9017: bugfix-add-kdump-parameter-into-kernel-cmdline.patch
Patch6001: anaconda-Fix-stage2-as-default-sources.patch
Patch6002: anaconda-Allow-to-detect-devices-with-the-iso9660-file-system.patch
%define dbusver 1.2.3
%define dnfver 3.6.0
%define dracutver 034-7
@ -239,6 +242,12 @@ update-desktop-database &> /dev/null || :
%{_datadir}/gtk-doc
%changelog
* Fri Aug 7 2020 fengtao <fengtao40@huawei.com> - 33.19-3
- Type:bugfix
- Id:NA
- SUG:NA
- DESC:fix stage2 as default sources
* Tue Jul 14 2020 zhangqiumiao <zhangqiumiao1@huawei.com> - 33.19-2
- Type:bugfix
- Id:NA