643 lines
29 KiB
Diff
643 lines
29 KiB
Diff
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
|
|
|