fix stage2 as default sources
This commit is contained in:
parent
1b0586d1f1
commit
0018beb09f
@ -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
|
||||
|
||||
642
anaconda-Fix-stage2-as-default-sources.patch
Normal file
642
anaconda-Fix-stage2-as-default-sources.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user