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

