From 27667a0985af6c6133ecd08009f2cbfa589c5343 Mon Sep 17 00:00:00 2001 From: xuxiaolong <505279206@qq.com> Date: Fri, 2 Apr 2021 10:25:06 +0800 Subject: [PATCH] sync 49 fixbug from github (cherry picked from commit 0cd8608199f6b9726c451e0e9fe3be4a1dbe7cca) --- anaconda.spec | 59 ++++++- bugfix-Add-missing-make-BuildRequires.patch | 26 +++ ...ot-parameter-when-SELinux-is-set-to-.patch | 63 ++++++++ ...us-method-IsDeviceShrinkable-1875677.patch | 149 ++++++++++++++++++ bugfix-Allow-to-format-selected-DASDs.patch | 32 ++++ ...ways-clear-treeinfo-metadata-1872056.patch | 31 ++++ bugfix-Always-specify-the-boot-disk.patch | 43 +++++ ...icy-even-when-network-was-configured.patch | 27 ++++ ...eak-lines-in-labels-in-software-sele.patch | 53 +++++++ ...ordering-to-US-layout-first-native-s.patch | 30 ++++ ...-original-partitions-are-mounted-too.patch | 66 ++++++++ ...r-using-only-existing-fields-1860058.patch | 34 ++++ ...al-storage-model-during-the-initiali.patch | 50 ++++++ ...tween-RAID-levels-of-a-device-and-it.patch | 107 +++++++++++++ bugfix-Do-not-mount-as-RW-in-Dracut.patch | 32 ++++ ...pokes-after-we-leave-the-Summary-hub.patch | 98 ++++++++++++ ...ontainer-data-for-non-container-devi.patch | 37 +++++ ...ssl-certificate-for-metadata-1745064.patch | 30 ++++ ...sh-on-first-entering-of-source-spoke.patch | 40 +++++ ...creating-cached-LVs-on-encrypted-PVs.patch | 56 +++++++ ...r-in-initrd-shift-count-out-of-range.patch | 35 ++++ ...reeinfo-repositories-were-never-disa.patch | 34 ++++ ...FS-path-is-pointing-directly-to-ISO-.patch | 79 ++++++++++ ...ickstart-file-error-with-user-groups.patch | 40 +++++ bugfix-Fix-more-SElinux-contexts.patch | 32 ++++ ...rguments-when-creating-dracut-argume.patch | 48 ++++++ ...eading-kernel-list-when-collecting-c.patch | 41 +++++ ...x-for-an-URL-type-of-additional-repo.patch | 40 +++++ ...he-logic-for-enabling-latest-updates.patch | 41 +++++ ...-when-removing-additional-repository.patch | 34 ++++ ...en-starting-installation-with-inst.c.patch | 36 +++++ ...s-from-threads-without-new-instances.patch | 36 +++++ ...positories-disabled-after-payload-re.patch | 101 ++++++++++++ ...itions-on-a-disk-with-the-iso9660-fi.patch | 101 ++++++++++++ ...-Only-pass-one-initrd-image-to-kexec.patch | 40 +++++ ...d.unit-anaconda.target-in-anaconda-g.patch | 32 ++++ ...re-DNF-payload-after-options-are-set.patch | 29 ++++ ...-repositories-on-every-payload-reset.patch | 120 ++++++++++++++ ...fo-repositories-instead-of-disabling.patch | 128 +++++++++++++++ ...-level-of-the-device-request-1828092.patch | 31 ++++ ...-mandatory-if-there-is-not-admin-use.patch | 28 ++++ ...he-Resize-dialog-in-the-reversed-ord.patch | 86 ++++++++++ ...ssage-when-entered-size-is-not-valid.patch | 96 +++++++++++ ...ne-character-should-not-be-displayed.patch | 26 +++ ...out-for-synchronous-activation-of-a-.patch | 59 +++++++ ...rash-when-updating-a-connection-with.patch | 41 +++++ ...ry-to-activate-connection-that-has-n.patch | 30 ++++ ...iguration-of-virtual-devices-by-boot.patch | 58 +++++++ ...ing-of-hostname-from-ip-if-mac-is-de.patch | 95 +++++++++++ ...ddr-when-binding-to-mac-more-robustl.patch | 29 ++++ 50 files changed, 2687 insertions(+), 2 deletions(-) create mode 100644 bugfix-Add-missing-make-BuildRequires.patch create mode 100644 bugfix-Add-selinux-0-boot-parameter-when-SELinux-is-set-to-.patch create mode 100644 bugfix-Add-the-DBus-method-IsDeviceShrinkable-1875677.patch create mode 100644 bugfix-Allow-to-format-selected-DASDs.patch create mode 100644 bugfix-Always-clear-treeinfo-metadata-1872056.patch create mode 100644 bugfix-Always-specify-the-boot-disk.patch create mode 100644 bugfix-Apply-onboot-policy-even-when-network-was-configured.patch create mode 100644 bugfix-Automatically-break-lines-in-labels-in-software-sele.patch create mode 100644 bugfix-Change-keyboard-ordering-to-US-layout-first-native-s.patch create mode 100644 bugfix-Check-if-original-partitions-are-mounted-too.patch create mode 100644 bugfix-Create-ssh-user-using-only-existing-fields-1860058.patch create mode 100644 bugfix-Create-the-initial-storage-model-during-the-initiali.patch create mode 100644 bugfix-Differentiate-between-RAID-levels-of-a-device-and-it.patch create mode 100644 bugfix-Do-not-mount-as-RW-in-Dracut.patch create mode 100644 bugfix-Don-t-enter-spokes-after-we-leave-the-Summary-hub.patch create mode 100644 bugfix-Don-t-generate-container-data-for-non-container-devi.patch create mode 100644 bugfix-Fix-checking-ssl-certificate-for-metadata-1745064.patch create mode 100644 bugfix-Fix-crash-on-first-entering-of-source-spoke.patch create mode 100644 bugfix-Fix-creating-cached-LVs-on-encrypted-PVs.patch create mode 100644 bugfix-Fix-error-in-initrd-shift-count-out-of-range.patch create mode 100644 bugfix-Fix-issue-that-treeinfo-repositories-were-never-disa.patch create mode 100644 bugfix-Fix-issue-when-NFS-path-is-pointing-directly-to-ISO-.patch create mode 100644 bugfix-Fix-kickstart-file-error-with-user-groups.patch create mode 100644 bugfix-Fix-more-SElinux-contexts.patch create mode 100644 bugfix-Fix-passing-of-arguments-when-creating-dracut-argume.patch create mode 100644 bugfix-Fix-regression-reading-kernel-list-when-collecting-c.patch create mode 100644 bugfix-Fix-the-combo-box-for-an-URL-type-of-additional-repo.patch create mode 100644 bugfix-Fix-the-logic-for-enabling-latest-updates.patch create mode 100644 bugfix-Fix-traceback-when-removing-additional-repository.patch create mode 100644 bugfix-Fix-traceback-when-starting-installation-with-inst.c.patch create mode 100644 bugfix-Handle-exceptions-from-threads-without-new-instances.patch create mode 100644 bugfix-Keep-treeinfo-repositories-disabled-after-payload-re.patch create mode 100644 bugfix-Never-mount-partitions-on-a-disk-with-the-iso9660-fi.patch create mode 100644 bugfix-Only-pass-one-initrd-image-to-kexec.patch create mode 100644 bugfix-Recognize-systemd.unit-anaconda.target-in-anaconda-g.patch create mode 100644 bugfix-Reconfigure-DNF-payload-after-options-are-set.patch create mode 100644 bugfix-Reload-treeinfo-repositories-on-every-payload-reset.patch create mode 100644 bugfix-Remove-treeinfo-repositories-instead-of-disabling.patch create mode 100644 bugfix-Reset-the-RAID-level-of-the-device-request-1828092.patch create mode 100644 bugfix-Root-password-is-mandatory-if-there-is-not-admin-use.patch create mode 100644 bugfix-Run-actions-of-the-Resize-dialog-in-the-reversed-ord.patch create mode 100644 bugfix-Show-warning-message-when-entered-size-is-not-valid.patch create mode 100644 bugfix-The-underline-character-should-not-be-displayed.patch create mode 100644 bugfix-network-add-timeout-for-synchronous-activation-of-a-.patch create mode 100644 bugfix-network-do-not-crash-when-updating-a-connection-with.patch create mode 100644 bugfix-network-do-not-try-to-activate-connection-that-has-n.patch create mode 100644 bugfix-network-fix-configuration-of-virtual-devices-by-boot.patch create mode 100644 bugfix-network-fix-parsing-of-hostname-from-ip-if-mac-is-de.patch create mode 100644 bugfix-network-get-hwadddr-when-binding-to-mac-more-robustl.patch diff --git a/anaconda.spec b/anaconda.spec index af8e7bd..6b93d13 100644 --- a/anaconda.spec +++ b/anaconda.spec @@ -1,7 +1,7 @@ %define _empty_manifest_terminate_build 0 Name: anaconda Version: 33.19 -Release: 18 +Release: 19 Summary: Graphical system installer License: GPLv2+ and MIT URL: http://fedoraproject.org/wiki/Anaconda @@ -58,6 +58,55 @@ Patch9024: Change-length-limit-of-hostname-from-255-to-64.patch Patch6020: bugfix-Schedule-timed-actions-with-the-right-selector-18516.patch Patch6021: bugfix-Reset-the-state-of-the-custom-partitioning-spoke.patch +Patch6022: bugfix-Fix-regression-reading-kernel-list-when-collecting-c.patch +Patch6023: bugfix-Fix-more-SElinux-contexts.patch +Patch6024: bugfix-Fix-issue-when-NFS-path-is-pointing-directly-to-ISO-.patch +Patch6025: bugfix-Create-the-initial-storage-model-during-the-initiali.patch +Patch6026: bugfix-Always-specify-the-boot-disk.patch +Patch6027: bugfix-Fix-passing-of-arguments-when-creating-dracut-argume.patch +Patch6028: bugfix-Reconfigure-DNF-payload-after-options-are-set.patch +Patch6029: bugfix-Only-pass-one-initrd-image-to-kexec.patch +Patch6030: bugfix-Fix-creating-cached-LVs-on-encrypted-PVs.patch +Patch6031: bugfix-Run-actions-of-the-Resize-dialog-in-the-reversed-ord.patch +Patch6032: bugfix-Reload-treeinfo-repositories-on-every-payload-reset.patch +Patch6033: bugfix-Remove-treeinfo-repositories-instead-of-disabling.patch +Patch6034: bugfix-Fix-crash-on-first-entering-of-source-spoke.patch +Patch6035: bugfix-Keep-treeinfo-repositories-disabled-after-payload-re.patch +Patch6036: bugfix-Fix-issue-that-treeinfo-repositories-were-never-disa.patch +Patch6037: bugfix-Fix-kickstart-file-error-with-user-groups.patch +Patch6038: bugfix-Create-ssh-user-using-only-existing-fields-1860058.patch +Patch6039: bugfix-Automatically-break-lines-in-labels-in-software-sele.patch +Patch6040: bugfix-Reset-the-RAID-level-of-the-device-request-1828092.patch +Patch6041: bugfix-Change-keyboard-ordering-to-US-layout-first-native-s.patch +Patch6042: bugfix-Handle-exceptions-from-threads-without-new-instances.patch +Patch6043: bugfix-network-fix-configuration-of-virtual-devices-by-boot.patch +Patch6044: bugfix-network-do-not-try-to-activate-connection-that-has-n.patch +Patch6045: bugfix-network-add-timeout-for-synchronous-activation-of-a-.patch +Patch6046: bugfix-Fix-traceback-when-removing-additional-repository.patch +Patch6047: bugfix-network-do-not-crash-when-updating-a-connection-with.patch +Patch6048: bugfix-Do-not-mount-as-RW-in-Dracut.patch +Patch6049: bugfix-The-underline-character-should-not-be-displayed.patch +Patch6050: bugfix-Recognize-systemd.unit-anaconda.target-in-anaconda-g.patch +Patch6051: bugfix-Always-clear-treeinfo-metadata-1872056.patch +Patch6052: bugfix-Apply-onboot-policy-even-when-network-was-configured.patch +Patch6053: bugfix-network-fix-parsing-of-hostname-from-ip-if-mac-is-de.patch +Patch6054: bugfix-Don-t-generate-container-data-for-non-container-devi.patch +Patch6055: bugfix-Differentiate-between-RAID-levels-of-a-device-and-it.patch +Patch6056: bugfix-Show-warning-message-when-entered-size-is-not-valid.patch +Patch6057: bugfix-Add-the-DBus-method-IsDeviceShrinkable-1875677.patch +Patch6058: bugfix-Check-if-original-partitions-are-mounted-too.patch +Patch6059: bugfix-network-get-hwadddr-when-binding-to-mac-more-robustl.patch +Patch6060: bugfix-Fix-the-combo-box-for-an-URL-type-of-additional-repo.patch +Patch6061: bugfix-Never-mount-partitions-on-a-disk-with-the-iso9660-fi.patch +Patch6062: bugfix-Add-missing-make-BuildRequires.patch +Patch6063: bugfix-Allow-to-format-selected-DASDs.patch +Patch6064: bugfix-Add-selinux-0-boot-parameter-when-SELinux-is-set-to-.patch +Patch6065: bugfix-Root-password-is-mandatory-if-there-is-not-admin-use.patch +Patch6066: bugfix-Fix-traceback-when-starting-installation-with-inst.c.patch +Patch6067: bugfix-Fix-checking-ssl-certificate-for-metadata-1745064.patch +Patch6068: bugfix-Fix-error-in-initrd-shift-count-out-of-range.patch +Patch6069: bugfix-Fix-the-logic-for-enabling-latest-updates.patch +Patch6070: bugfix-Don-t-enter-spokes-after-we-leave-the-Summary-hub.patch %define dbusver 1.2.3 %define dnfver 3.6.0 @@ -271,7 +320,13 @@ update-desktop-database &> /dev/null || : %{_datadir}/gtk-doc %changelog -* Thu Mar 18 2021 liuxin - 33.19-18 +* Mon Mar 29 2021 xuxiaolong - 33.19-19 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:sync 50 bugfix commit from github + +* Sat Mar 27 2021 zhangrui - 33.19-18 - Type:bugfix - ID:NA - SUG:NA diff --git a/bugfix-Add-missing-make-BuildRequires.patch b/bugfix-Add-missing-make-BuildRequires.patch new file mode 100644 index 0000000..189d507 --- /dev/null +++ b/bugfix-Add-missing-make-BuildRequires.patch @@ -0,0 +1,26 @@ +From f7398e8ceaa634bff73b1b1cd04ac0aa572d5249 Mon Sep 17 00:00:00 2001 +From: Martin Pitt +Date: Thu, 1 Oct 2020 15:44:43 +0200 +Subject: [PATCH] Add missing "make" BuildRequires + +The .spec calls make, and it's not present in the Fedora container +images. +--- + anaconda.spec.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/anaconda.spec.in b/anaconda.spec.in +index d2b34a65f..5c5146c9c 100644 +--- a/anaconda.spec.in ++++ b/anaconda.spec.in +@@ -54,6 +54,7 @@ BuildRequires: gobject-introspection-devel + BuildRequires: glade-devel + BuildRequires: libgnomekbd-devel + BuildRequires: libxklavier-devel >= %{libxklavierver} ++BuildRequires: make + BuildRequires: pango-devel + BuildRequires: python3-kickstart >= %{pykickstartver} + BuildRequires: python3-devel +-- +2.23.0 + diff --git a/bugfix-Add-selinux-0-boot-parameter-when-SELinux-is-set-to-.patch b/bugfix-Add-selinux-0-boot-parameter-when-SELinux-is-set-to-.patch new file mode 100644 index 0000000..97f264f --- /dev/null +++ b/bugfix-Add-selinux-0-boot-parameter-when-SELinux-is-set-to-.patch @@ -0,0 +1,63 @@ +From 8437fe761224a97967a076e05143304a225c3e05 Mon Sep 17 00:00:00 2001 +From: Ondrej Mosnacek +Date: Fri, 2 Oct 2020 13:06:26 +0200 +Subject: [PATCH] Add selinux=0 boot parameter when SELinux is set to disabled + (#1882464) + +We are trying to eliminate the reliance on disabling SELinux via +/etc/selinux/config in Fedora [1], since this functionality is being +deprecated upstream. + +Even though only setting SELINUX=disabled in /etc/selinux/config will +still lead to a similar result as if SELinux would be disabled +completely, users might complain that Anaconda didn't actually do the +right thing, so let's make sure it is done properly by adding selinux=0 +to the target system's kernel command line when the user requests +SELinux to be disabled via anaconda command line or kickstart. + +[1] https://fedoraproject.org/wiki/Changes/Remove_Support_For_SELinux_Runtime_Disable + +Signed-off-by: Ondrej Mosnacek +--- + pyanaconda/modules/storage/bootloader/base.py | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py +index d690ca056..12f8f54b2 100644 +--- a/pyanaconda/modules/storage/bootloader/base.py ++++ b/pyanaconda/modules/storage/bootloader/base.py +@@ -35,8 +35,9 @@ from pyanaconda.core.configuration.anaconda import conf + from pyanaconda.core.i18n import N_, _ + from pyanaconda.modules.common.constants.objects import FCOE, ISCSI, BOOTLOADER + from pyanaconda.modules.common.structures.iscsi import Node +-from pyanaconda.modules.common.constants.services import STORAGE, NETWORK ++from pyanaconda.modules.common.constants.services import STORAGE, NETWORK, SECURITY + from pyanaconda.modules.common.structures.network import NetworkDeviceInfo ++from pykickstart.constants import SELINUX_DISABLED + + log = get_module_logger(__name__) + +@@ -729,6 +730,7 @@ class BootLoader(object): + self._set_storage_boot_args(storage) + self._preserve_some_boot_args() + self._set_graphical_boot_args() ++ self._set_security_boot_args() + + def _set_extra_boot_args(self): + """Set the extra boot args.""" +@@ -885,6 +887,12 @@ class BootLoader(object): + self.boot_args.update(args) + self.dracut_args.update(args) + ++ def _set_security_boot_args(self): ++ """Set LSM-related boot args.""" ++ proxy = SECURITY.get_proxy() ++ if proxy.SELinux == SELINUX_DISABLED: ++ self.boot_args.add('selinux=0') ++ + # + # configuration + # +-- +2.23.0 + diff --git a/bugfix-Add-the-DBus-method-IsDeviceShrinkable-1875677.patch b/bugfix-Add-the-DBus-method-IsDeviceShrinkable-1875677.patch new file mode 100644 index 0000000..d8f6d22 --- /dev/null +++ b/bugfix-Add-the-DBus-method-IsDeviceShrinkable-1875677.patch @@ -0,0 +1,149 @@ +From cf8d3811b89b90211cac0cbd1e5ceb40ea7b641b Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Mon, 7 Sep 2020 17:09:15 +0200 +Subject: [PATCH] Add the DBus method IsDeviceShrinkable (#1875677) + +Replace the DBus method IsDeviceResizable with IsDeviceShrinkable and fix its +implementation. A shrinkable device has to be resizable and its minimal size +has to be lower then the current size. This should fix the issue with XFS, that +is resizable, but not shrinkable. + +Resolves: rhbz#1875677 +--- + .../automatic/resizable_interface.py | 6 ++-- + .../automatic/resizable_module.py | 6 ++-- + pyanaconda/ui/gui/spokes/lib/resize.py | 10 +++---- + .../pyanaconda_tests/module_resizable_test.py | 29 +++++++++++++++---- + 4 files changed, 34 insertions(+), 17 deletions(-) + +diff --git a/pyanaconda/modules/storage/partitioning/automatic/resizable_interface.py b/pyanaconda/modules/storage/partitioning/automatic/resizable_interface.py +index 760a49ecb..c531a0b42 100644 +--- a/pyanaconda/modules/storage/partitioning/automatic/resizable_interface.py ++++ b/pyanaconda/modules/storage/partitioning/automatic/resizable_interface.py +@@ -37,13 +37,13 @@ class ResizableDeviceTreeInterface(DeviceTreeInterface): + """ + return self.implementation.is_device_partitioned(device_name) + +- def IsDeviceResizable(self, device_name: Str) -> Bool: +- """Is the specified device resizable? ++ def IsDeviceShrinkable(self, device_name: Str) -> Bool: ++ """Is the specified device shrinkable? + + :param device_name: a name of the device + :return: True or False + """ +- return self.implementation.is_device_resizable(device_name) ++ return self.implementation.is_device_shrinkable(device_name) + + def GetDevicePartitions(self, device_name: Str) -> List[Str]: + """Get partitions of the specified device. +diff --git a/pyanaconda/modules/storage/partitioning/automatic/resizable_module.py b/pyanaconda/modules/storage/partitioning/automatic/resizable_module.py +index 9603dfc1b..12d32e891 100644 +--- a/pyanaconda/modules/storage/partitioning/automatic/resizable_module.py ++++ b/pyanaconda/modules/storage/partitioning/automatic/resizable_module.py +@@ -52,14 +52,14 @@ class ResizableDeviceTreeModule(DeviceTreeModule): + """Is the specified device partitioned?""" + return device.is_disk and device.partitioned and device.format.supported + +- def is_device_resizable(self, device_name): +- """Is the specified device resizable? ++ def is_device_shrinkable(self, device_name): ++ """Is the specified device shrinkable? + + :param device_name: a name of the device + :return: True or False + """ + device = self._get_device(device_name) +- return device.resizable ++ return device.resizable and device.min_size < device.size + + def get_device_partitions(self, device_name): + """Get partitions of the specified device. +diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py +index 4695e5332..ee165ada7 100644 +--- a/pyanaconda/ui/gui/spokes/lib/resize.py ++++ b/pyanaconda/ui/gui/spokes/lib/resize.py +@@ -228,13 +228,13 @@ class ResizeDialog(GUIObject): + + # Calculate the free size. + # Devices that are not resizable are still deletable. +- is_resizable = self._device_tree.IsDeviceResizable(device_name) ++ is_shrinkable = self._device_tree.IsDeviceShrinkable(device_name) + size_limits = self._device_tree.GetDeviceSizeLimits(device_name) + + min_size = Size(size_limits[0]) + device_size = Size(device_data.size) + +- if is_resizable: ++ if is_shrinkable: + free_size = device_size - min_size + resize_string = _("%(freeSize)s of %(devSize)s") % { + "freeSize": free_size.human_readable(max_places=1), +@@ -394,10 +394,10 @@ class ResizeDialog(GUIObject): + + # If the selected filesystem does not support shrinking, make that + # button insensitive. +- is_resizable = self._device_tree.IsDeviceResizable(device_name) +- self._shrink_button.set_sensitive(is_resizable) ++ is_shrinkable = self._device_tree.IsDeviceShrinkable(device_name) ++ self._shrink_button.set_sensitive(is_shrinkable) + +- if is_resizable: ++ if is_shrinkable: + min_size = self._device_tree.GetDeviceSizeLimits(device_name)[0] + self._setup_slider(min_size, device_data.size, Size(obj.target)) + +diff --git a/tests/nosetests/pyanaconda_tests/module_resizable_test.py b/tests/nosetests/pyanaconda_tests/module_resizable_test.py +index 3c60e166b..42880b4ca 100644 +--- a/tests/nosetests/pyanaconda_tests/module_resizable_test.py ++++ b/tests/nosetests/pyanaconda_tests/module_resizable_test.py +@@ -18,9 +18,11 @@ + # Red Hat Author(s): Vendula Poncova + # + import unittest ++from unittest.mock import patch + + from blivet.devices import StorageDevice, DiskDevice, PartitionDevice + from blivet.formats import get_format ++from blivet.formats.fs import FS + from blivet.size import Size + + from pyanaconda.modules.storage.partitioning.automatic.resizable_interface import \ +@@ -66,13 +68,28 @@ class ResizableDeviceTreeTestCase(unittest.TestCase): + self.assertEqual(self.interface.IsDevicePartitioned("dev1"), False) + self.assertEqual(self.interface.IsDevicePartitioned("dev2"), True) + +- def is_device_resizable_test(self): +- """Test IsDeviceResizable.""" ++ @patch.object(FS, "update_size_info") ++ def is_device_shrinkable_test(self, update_size_info): ++ """Test IsDeviceShrinkable.""" + self.module.on_storage_changed(create_storage()) +- self._add_device(StorageDevice( +- "dev1" +- )) +- self.assertEqual(self.interface.IsDeviceResizable("dev1"), False) ++ ++ dev1 = StorageDevice( ++ "dev1", ++ exists=True, ++ size=Size("10 GiB"), ++ fmt=get_format(None, exists=True) ++ ) ++ ++ self._add_device(dev1) ++ self.assertEqual(self.interface.IsDeviceShrinkable("dev1"), False) ++ ++ dev1._resizable = True ++ dev1.format._resizable = True ++ dev1.format._min_size = Size("1 GiB") ++ self.assertEqual(self.interface.IsDeviceShrinkable("dev1"), True) ++ ++ dev1.format._min_size = Size("10 GiB") ++ self.assertEqual(self.interface.IsDeviceShrinkable("dev1"), False) + + def get_device_partitions_test(self): + """Test GetDevicePartitions.""" +-- +2.23.0 + diff --git a/bugfix-Allow-to-format-selected-DASDs.patch b/bugfix-Allow-to-format-selected-DASDs.patch new file mode 100644 index 0000000..3b5e851 --- /dev/null +++ b/bugfix-Allow-to-format-selected-DASDs.patch @@ -0,0 +1,32 @@ +From d1d43dc872aa05b7273883fe42debd55e11e6df6 Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Mon, 5 Oct 2020 18:57:24 +0200 +Subject: [PATCH] Allow to format selected DASDs + +TUI should allow to format selected DASDs the same way as GUI. + +(cherry-picked from a commit 4f1bc77) + +Related: rhbz#1874394 +--- + pyanaconda/ui/tui/spokes/storage.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py +index 813dbb052..4ed97d27e 100644 +--- a/pyanaconda/ui/tui/spokes/storage.py ++++ b/pyanaconda/ui/tui/spokes/storage.py +@@ -258,6 +258,10 @@ class StorageSpoke(NormalTUISpoke): + # Wait for storage. + threadMgr.wait(THREAD_STORAGE) + ++ # Allow to format DASDs. ++ self._disk_init_module.SetFormatUnrecognizedEnabled(True) ++ self._disk_init_module.SetFormatLDLEnabled(True) ++ + # Get selected disks. + disks = filter_disks_by_names(self._available_disks, self._selected_disks) + +-- +2.23.0 + diff --git a/bugfix-Always-clear-treeinfo-metadata-1872056.patch b/bugfix-Always-clear-treeinfo-metadata-1872056.patch new file mode 100644 index 0000000..8358be9 --- /dev/null +++ b/bugfix-Always-clear-treeinfo-metadata-1872056.patch @@ -0,0 +1,31 @@ +From 9ef262fbd07508a5dd9becb30a0136fded45e792 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Thu, 3 Sep 2020 14:53:18 +0200 +Subject: [PATCH] Always clear treeinfo metadata (#1872056) + +Metadata from the treeinfo were loaded only during the load of new metadata. +However, this does not work if we have source without metadata (e.g. +mirrorlist). In that case we are loading additional repositories from the old +metadata (not mounted anymore) and not the new ones which may have unexpected +results. + +Resolves: rhbz#1872056 +--- + pyanaconda/payload/dnf/payload.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index 5fba7e0e7..880886685 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -1477,6 +1477,7 @@ class DNFPayload(Payload): + def reset(self): + tear_down_sources(self.proxy) + self.reset_additional_repos() ++ self._install_tree_metadata = None + + shutil.rmtree(DNF_CACHE_DIR, ignore_errors=True) + shutil.rmtree(DNF_PLUGINCONF_DIR, ignore_errors=True) +-- +2.23.0 + diff --git a/bugfix-Always-specify-the-boot-disk.patch b/bugfix-Always-specify-the-boot-disk.patch new file mode 100644 index 0000000..125e02f --- /dev/null +++ b/bugfix-Always-specify-the-boot-disk.patch @@ -0,0 +1,43 @@ +From 6326cb3e866027a5862c0fbd0a1f0a2a86b6836b Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Tue, 23 Jun 2020 17:55:37 +0200 +Subject: [PATCH] Always specify the boot disk + +We should always specify the boot disk when we allocate partitions. Otherwise, +Blivet will choose one of the available disks that don't have to be valid. + +(cherry-picked from a commit 856e011) +--- + .../storage/partitioning/automatic/automatic_partitioning.py | 2 +- + .../modules/storage/partitioning/custom/custom_partitioning.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py b/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py +index acceb4b4e..a88c55d4d 100644 +--- a/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py ++++ b/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py +@@ -175,7 +175,7 @@ class AutomaticPartitioningTask(NonInteractivePartitioningTask): + devs = schedule_partitions(storage, disks, devs, scheme, requests, encrypted, luks_fmt_args) + + # run the autopart function to allocate and grow partitions +- do_partitioning(storage) ++ do_partitioning(storage, boot_disk=storage.bootloader.stage1_disk) + schedule_volumes(storage, devs, scheme, requests, encrypted) + + # grow LVs +diff --git a/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py b/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py +index 218bbe13f..754a48e2e 100644 +--- a/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py ++++ b/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py +@@ -136,7 +136,7 @@ class CustomPartitioningTask(NonInteractivePartitioningTask): + self._execute_partition_data(storage, data, partition_data) + + if data.partition.partitions: +- do_partitioning(storage) ++ do_partitioning(storage, boot_disk=storage.bootloader.stage1_disk) + + def _execute_partition_data(self, storage, data, partition_data): + """Execute the partition data. +-- +2.23.0 + diff --git a/bugfix-Apply-onboot-policy-even-when-network-was-configured.patch b/bugfix-Apply-onboot-policy-even-when-network-was-configured.patch new file mode 100644 index 0000000..dfc1407 --- /dev/null +++ b/bugfix-Apply-onboot-policy-even-when-network-was-configured.patch @@ -0,0 +1,27 @@ +From b7258aafb1e55b055bc6bcd18b10c83f5a5feec6 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 29 Jul 2020 12:43:26 +0200 +Subject: [PATCH] Apply onboot policy even when network was configured in UI. + +Resolves: rhbz#1856632 +--- + pyanaconda/modules/network/network.py | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/pyanaconda/modules/network/network.py b/pyanaconda/modules/network/network.py +index aa5a14b38..507d3b5c1 100644 +--- a/pyanaconda/modules/network/network.py ++++ b/pyanaconda/modules/network/network.py +@@ -372,9 +372,6 @@ class NetworkService(KickstartService): + # Not if any network device was configured via kickstart. + if self._original_network_data: + return False +- # Not if any network device was configured in UI. +- if self._use_device_configurations: +- return False + # Not if there is no configuration to apply the policy to + if not self._device_configurations or not self._device_configurations.get_all(): + return False +-- +2.23.0 + diff --git a/bugfix-Automatically-break-lines-in-labels-in-software-sele.patch b/bugfix-Automatically-break-lines-in-labels-in-software-sele.patch new file mode 100644 index 0000000..896f7a8 --- /dev/null +++ b/bugfix-Automatically-break-lines-in-labels-in-software-sele.patch @@ -0,0 +1,53 @@ +From 6c8bfa8649e71d4f20eea69b57dc47b514dd498c Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Tue, 11 Aug 2020 17:34:49 +0200 +Subject: [PATCH] Automatically break lines in labels in software selection + spoke + +Resolves: rhbz#1822787 +--- + pyanaconda/ui/gui/spokes/software_selection.glade | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/software_selection.glade b/pyanaconda/ui/gui/spokes/software_selection.glade +index 2965e66df..87804c72e 100644 +--- a/pyanaconda/ui/gui/spokes/software_selection.glade ++++ b/pyanaconda/ui/gui/spokes/software_selection.glade +@@ -1,5 +1,5 @@ + +- ++ + + + +@@ -60,10 +60,12 @@ + + True + False ++ end + 6 + True +- 0 + Base Environment ++ True ++ 0 + + + +@@ -78,10 +80,12 @@ + + True + False ++ end + 6 + True +- 0 + Additional software for Selected Environment ++ True ++ 0 + + + +-- +2.23.0 + diff --git a/bugfix-Change-keyboard-ordering-to-US-layout-first-native-s.patch b/bugfix-Change-keyboard-ordering-to-US-layout-first-native-s.patch new file mode 100644 index 0000000..9322582 --- /dev/null +++ b/bugfix-Change-keyboard-ordering-to-US-layout-first-native-s.patch @@ -0,0 +1,30 @@ +From e05cc18294e67099bf87076e4f23fe5f031fecb5 Mon Sep 17 00:00:00 2001 +From: Sundeep Anand +Date: Wed, 12 Aug 2020 17:56:19 +0530 +Subject: [PATCH] Change keyboard ordering to US layout first, 'native' second. + Resolves: rhbz#1039185 + +--- + pyanaconda/keyboard.py | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py +index 2c3226c6e..081fc96fd 100644 +--- a/pyanaconda/keyboard.py ++++ b/pyanaconda/keyboard.py +@@ -171,8 +171,10 @@ def set_x_keyboard_defaults(localization_proxy, xkl_wrapper): + # store it normalized + new_layouts = [normalize_layout_variant(layouts[0])] + if not langtable.supports_ascii(layouts[0]): +- # does not support typing ASCII chars, append the default layout +- new_layouts.append(DEFAULT_KEYBOARD) ++ # The default keymap setting should have "us" before the native layout ++ # which does not support ascii, ++ # refer: https://bugzilla.redhat.com/show_bug.cgi?id=1039185 ++ new_layouts.insert(0, DEFAULT_KEYBOARD) + else: + log.error("Failed to get layout for chosen locale '%s'", locale) + new_layouts = [DEFAULT_KEYBOARD] +-- +2.23.0 + diff --git a/bugfix-Check-if-original-partitions-are-mounted-too.patch b/bugfix-Check-if-original-partitions-are-mounted-too.patch new file mode 100644 index 0000000..c021bd1 --- /dev/null +++ b/bugfix-Check-if-original-partitions-are-mounted-too.patch @@ -0,0 +1,66 @@ +From 6515d0779a41c1ea902ada86e4e911821cded92e Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Thu, 3 Sep 2020 19:27:28 +0200 +Subject: [PATCH] Check if original partitions are mounted, too + +Resolves: rhbz#1751698 +--- + pyanaconda/modules/storage/checker/utils.py | 30 +++++++++++++++------ + 1 file changed, 22 insertions(+), 8 deletions(-) + +diff --git a/pyanaconda/modules/storage/checker/utils.py b/pyanaconda/modules/storage/checker/utils.py +index ff3ee3a6b..c40aa1dc3 100644 +--- a/pyanaconda/modules/storage/checker/utils.py ++++ b/pyanaconda/modules/storage/checker/utils.py +@@ -417,11 +417,15 @@ def verify_luks2_memory_requirements(storage, constraints, report_error, report_ + def verify_mounted_partitions(storage, constraints, report_error, report_warning): + """ Check the selected disks to make sure all their partitions are unmounted. + ++ Check both the currently known and original partitions. ++ + :param storage: a storage to check + :param constraints: a dictionary of constraints + :param report_error: a function for error reporting + :param report_warning: a function for warning reporting + """ ++ partitions_to_check = {} ++ + for disk in storage.disks: + if disk.protected: + continue +@@ -430,14 +434,24 @@ def verify_mounted_partitions(storage, constraints, report_error, report_warning + continue + + for part in disk.format.partitions: +- part_dev = storage.devicetree.get_device_by_path(part.path) +- if part_dev and part_dev.protected: +- log.debug("Not checking protected %s for being mounted, assuming live " +- "image mount", part.path) +- continue +- if part.busy: +- report_error(_("%s is currently mounted and cannot be used for the " +- "installation. Please unmount it and retry.") % part.path) ++ if part.path not in partitions_to_check: ++ partitions_to_check[part.path] = part ++ ++ if hasattr(disk.original_format, "partitions"): ++ for part in disk.original_format.partitions: ++ if part.path not in partitions_to_check: ++ partitions_to_check[part.path] = part ++ ++ for path, part in partitions_to_check.items(): ++ part_dev = storage.devicetree.get_device_by_path(path) ++ if part_dev and part_dev.protected: ++ log.debug("Not checking protected %s for being mounted, assuming live " ++ "image mount", path) ++ return ++ ++ if part.busy: ++ report_error(_("%s is currently mounted and cannot be used for the " ++ "installation. Please unmount it and retry.") % path) + + + def verify_lvm_destruction(storage, constraints, report_error, report_warning): +-- +2.23.0 + diff --git a/bugfix-Create-ssh-user-using-only-existing-fields-1860058.patch b/bugfix-Create-ssh-user-using-only-existing-fields-1860058.patch new file mode 100644 index 0000000..2fecea9 --- /dev/null +++ b/bugfix-Create-ssh-user-using-only-existing-fields-1860058.patch @@ -0,0 +1,34 @@ +From 76d20274ea13439bdfa277aa18a99a1ee9a61d1c Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Mon, 3 Aug 2020 15:05:53 +0200 +Subject: [PATCH] Create ssh user using only existing fields (#1860058) + +This fixes the bug where "homedir" and other fields do not exist on +F24_SshPwData and no user is created for SSH access to installation +environment. + +Resolves: rhbz#1860058 + +Cherry-picked from df09030f0e7c8f350ba36ce99fa1bc33e4f45b6a +--- + utils/handle-sshpw | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/utils/handle-sshpw b/utils/handle-sshpw +index 0918610be..fc4726d88 100755 +--- a/utils/handle-sshpw ++++ b/utils/handle-sshpw +@@ -47,8 +47,8 @@ for ud in userdata: + users.set_user_password(username=ud.username, password=ud.password, + is_crypted=ud.isCrypted, lock=ud.lock) + else: +- users.create_user(username=ud.username, password=ud.password, is_crypted=ud.isCrypted, lock=ud.lock, +- homedir=ud.homedir, shell=ud.shell, gecos=ud.gecos, root="/") ++ users.create_user(username=ud.username, password=ud.password, is_crypted=ud.isCrypted, ++ lock=ud.lock, root="/") + + if ud.sshkey: + # Setup the account so that only the sshkey can be used +-- +2.23.0 + diff --git a/bugfix-Create-the-initial-storage-model-during-the-initiali.patch b/bugfix-Create-the-initial-storage-model-during-the-initiali.patch new file mode 100644 index 0000000..b6285a6 --- /dev/null +++ b/bugfix-Create-the-initial-storage-model-during-the-initiali.patch @@ -0,0 +1,50 @@ +From 5cb9170cafc3f81193fd872a21933a0fa2bd5f2c Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Mon, 6 Jul 2020 14:04:28 +0200 +Subject: [PATCH] Create the initial storage model during the initialization + +After connecting all objects of the Storage service to signals, create +the initial storage model. It will be propagated to all these objects. + +Otherwise, the objects might raise the UnavailableStorageError exception. + +(cherry-picked from a commit fabc9a0) +--- + pyanaconda/modules/storage/storage.py | 4 ++++ + tests/nosetests/pyanaconda_tests/module_storage_test.py | 5 +++++ + 2 files changed, 9 insertions(+) + +diff --git a/pyanaconda/modules/storage/storage.py b/pyanaconda/modules/storage/storage.py +index 9c5aff943..08254b0ce 100644 +--- a/pyanaconda/modules/storage/storage.py ++++ b/pyanaconda/modules/storage/storage.py +@@ -133,6 +133,10 @@ class StorageService(KickstartService): + self.on_protected_devices_changed + ) + ++ # After connecting modules to signals, create the initial ++ # storage model. It will be propagated to all modules. ++ self._set_storage(create_storage()) ++ + def _add_module(self, storage_module): + """Add a base kickstart module.""" + self._modules.append(storage_module) +diff --git a/tests/nosetests/pyanaconda_tests/module_storage_test.py b/tests/nosetests/pyanaconda_tests/module_storage_test.py +index 708981233..6bb1723d5 100644 +--- a/tests/nosetests/pyanaconda_tests/module_storage_test.py ++++ b/tests/nosetests/pyanaconda_tests/module_storage_test.py +@@ -120,6 +120,11 @@ class StorageInterfaceTestCase(unittest.TestCase): + storage_reset_callback = Mock() + self.storage_module.partitioning_reset.connect(storage_reset_callback) + ++ self.assertIsNotNone(self.storage_module.storage) ++ storage_changed_callback.assert_not_called() ++ storage_reset_callback.assert_not_called() ++ ++ self.storage_module._current_storage = None + self.assertIsNotNone(self.storage_module.storage) + storage_changed_callback.assert_called_once() + storage_reset_callback.assert_not_called() +-- +2.23.0 + diff --git a/bugfix-Differentiate-between-RAID-levels-of-a-device-and-it.patch b/bugfix-Differentiate-between-RAID-levels-of-a-device-and-it.patch new file mode 100644 index 0000000..9a72e7c --- /dev/null +++ b/bugfix-Differentiate-between-RAID-levels-of-a-device-and-it.patch @@ -0,0 +1,107 @@ +From c9857a91ece047c0fc2df3554e625d15b4700818 Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Thu, 13 Aug 2020 13:04:14 +0200 +Subject: [PATCH] Differentiate between RAID levels of a device and its + container + +The current logic returned the same RAID level for the device and its container, +but we expect that only one of them will have the RAID level set. +--- + .../partitioning/interactive/add_device.py | 4 +- + .../storage/partitioning/interactive/utils.py | 37 +++++++++++++++---- + 2 files changed, 31 insertions(+), 10 deletions(-) + +diff --git a/pyanaconda/modules/storage/partitioning/interactive/add_device.py b/pyanaconda/modules/storage/partitioning/interactive/add_device.py +index 82bb9917a..852cf8fbd 100644 +--- a/pyanaconda/modules/storage/partitioning/interactive/add_device.py ++++ b/pyanaconda/modules/storage/partitioning/interactive/add_device.py +@@ -24,7 +24,7 @@ from pyanaconda.modules.common.errors.configuration import StorageConfigurationE + from pyanaconda.modules.common.structures.device_factory import DeviceFactoryRequest + from pyanaconda.modules.common.task import Task + from pyanaconda.modules.storage.partitioning.interactive.utils import \ +- get_device_raid_level_name, get_container_size_policy, get_device_factory_arguments ++ get_container_raid_level_name, get_container_size_policy, get_device_factory_arguments + from pyanaconda.core.storage import PARTITION_ONLY_FORMAT_TYPES + + log = get_module_logger(__name__) +@@ -141,7 +141,7 @@ class AddDeviceTask(Task): + # Don't override user-initiated changes to a defined container. + request.disks = [d.name for d in container.disks] + request.container_encrypted = container.encrypted +- request.container_raid_level = get_device_raid_level_name(container) ++ request.container_raid_level = get_container_raid_level_name(container) + request.container_size_policy = get_container_size_policy(container) + + # The existing container has a name. +diff --git a/pyanaconda/modules/storage/partitioning/interactive/utils.py b/pyanaconda/modules/storage/partitioning/interactive/utils.py +index 04313eded..d3e56030a 100644 +--- a/pyanaconda/modules/storage/partitioning/interactive/utils.py ++++ b/pyanaconda/modules/storage/partitioning/interactive/utils.py +@@ -696,12 +696,6 @@ def get_device_raid_level(device): + if hasattr(device, "data_level"): + return device.data_level + +- if hasattr(device, "volume"): +- return device.volume.data_level +- +- if not hasattr(device, "vg") and hasattr(device, "lvs") and len(device.parents) == 1: +- return get_device_raid_level(device.parents[0]) +- + return None + + +@@ -711,6 +705,33 @@ def get_device_raid_level_name(device): + return raid_level.name if raid_level else "" + + ++def get_container_raid_level(container): ++ """Get the RAID level of the given container. ++ ++ :param container: a container ++ :return: a RAID level ++ """ ++ # Try to get a RAID level of this device. ++ raid_level = get_device_raid_level(container) ++ ++ if raid_level: ++ return raid_level ++ ++ device = container.raw_device ++ ++ # Or get a RAID level of the LVM container. ++ if hasattr(device, "lvs") and len(device.parents) == 1: ++ return get_container_raid_level(device.parents[0]) ++ ++ return None ++ ++ ++def get_container_raid_level_name(device): ++ """Get the RAID level name of the given container.""" ++ raid_level = get_container_raid_level(device) ++ return raid_level.name if raid_level else "" ++ ++ + def collect_file_system_types(device): + """Collect supported file system types for the given device. + +@@ -855,7 +876,7 @@ def set_container_data(request: DeviceFactoryRequest, container): + request.container_spec = container.name + request.container_name = container.name + request.container_encrypted = container.encrypted +- request.container_raid_level = get_device_raid_level_name(container) ++ request.container_raid_level = get_container_raid_level_name(container) + request.container_size_policy = get_container_size_policy(container) + + if request.container_encrypted: +@@ -1100,7 +1121,7 @@ def _destroy_device(storage, device): + disks=container.disks, + container_name=container.name, + container_encrypted=container.encrypted, +- container_raid_level=get_device_raid_level(container), ++ container_raid_level=get_container_raid_level(container), + container_size=container.size_policy, + ) + +-- +2.23.0 + diff --git a/bugfix-Do-not-mount-as-RW-in-Dracut.patch b/bugfix-Do-not-mount-as-RW-in-Dracut.patch new file mode 100644 index 0000000..1bd705e --- /dev/null +++ b/bugfix-Do-not-mount-as-RW-in-Dracut.patch @@ -0,0 +1,32 @@ +From 681285fff08169abd175beafae9e4144735e8cd9 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Fri, 21 Aug 2020 12:59:03 +0200 +Subject: [PATCH] Do not mount as RW in Dracut + +Dracut do not have reason to mount sources as RW it's more that it wasn't +specified and until recently we just did not bother. However, we changed the +logic that installation sources in stage2 environment does not re-using mounts +from the Dracut so this will now fail to set the environment because you can't +mount one thing as RW and RO at once. + +Resolves: rhbz#1871049 +(cherry picked from commit 408ae390c9ed7d14ad6c51979a18d839720e8be6) +--- + dracut/anaconda-diskroot | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dracut/anaconda-diskroot b/dracut/anaconda-diskroot +index 7e52e052b..8846b1108 100755 +--- a/dracut/anaconda-diskroot ++++ b/dracut/anaconda-diskroot +@@ -64,6 +64,6 @@ if [ -e /tmp/dd_interactive -a ! -e /tmp/dd.done ]; then + fi + + info "anaconda using disk root at $dev" +-mount $dev $repodir || warn "Couldn't mount $dev" ++mount -o ro $dev $repodir || warn "Couldn't mount $dev" + anaconda_live_root_dir $repodir $path + run_checkisomd5 $dev +-- +2.23.0 + diff --git a/bugfix-Don-t-enter-spokes-after-we-leave-the-Summary-hub.patch b/bugfix-Don-t-enter-spokes-after-we-leave-the-Summary-hub.patch new file mode 100644 index 0000000..ae3a42d --- /dev/null +++ b/bugfix-Don-t-enter-spokes-after-we-leave-the-Summary-hub.patch @@ -0,0 +1,98 @@ +From e0351e363baedcf788d7ff39fea282885229b4dc Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Fri, 27 Nov 2020 16:46:59 +0100 +Subject: [PATCH] Don't enter spokes after we leave the Summary hub + +If we decide to automatically leave the Summary hub and start the installation, +don't allow to enter spokes from the Summary hub anymore. There might be some +unprocessed callbacks in the even queue. + +Resolved: rhzb#1866022 +--- + pyanaconda/ui/gui/hubs/__init__.py | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py +index ee30fd004..81979470b 100644 +--- a/pyanaconda/ui/gui/hubs/__init__.py ++++ b/pyanaconda/ui/gui/hubs/__init__.py +@@ -85,10 +85,11 @@ class Hub(GUIObject, common.Hub): + GUIObject.__init__(self, data) + common.Hub.__init__(self, storage, payload) + +- # enable the autoContinue feature if we are in kickstart ++ # enable the auto continue feature if we are in kickstart + # mode, but if the user interacts with the hub, it will be + # disabled again +- self._autoContinue = flags.automatedInstall ++ self._auto_continue = flags.automatedInstall ++ self._click_continue = False + + self._hubs_collection.append(self) + self.timeout = None +@@ -262,7 +263,7 @@ class Hub(GUIObject, common.Hub): + # If this is a kickstart, consider the user to be warned and + # let them continue anyway, manually + if flags.automatedInstall: +- self._autoContinue = False ++ self._auto_continue = False + self._checker_ignore = True + else: + warning = _("Please complete items marked with this icon before continuing to the next step.") +@@ -301,7 +302,6 @@ class Hub(GUIObject, common.Hub): + log.debug("no spokes available on %s, continuing automatically", self) + gtk_call_once(self.window.emit, "continue-clicked") + +- click_continue = False + # Grab all messages that may have appeared since last time this method ran. + while True: + try: +@@ -357,9 +357,9 @@ class Hub(GUIObject, common.Hub): + + if self.continuePossible: + if self._inSpoke: +- self._autoContinue = False +- elif self._autoContinue: +- click_continue = True ++ self._auto_continue = False ++ elif self._auto_continue: ++ self._click_continue = True + + elif code == hubQ.HUB_CODE_MESSAGE: + spoke.selector.set_property("status", args[1]) +@@ -368,9 +368,9 @@ class Hub(GUIObject, common.Hub): + q.task_done() + + # queue is now empty, should continue be clicked? +- if self._autoContinue and click_continue and self.window.get_may_continue(): ++ if self._auto_continue and self._click_continue and self.window.get_may_continue(): + # enqueue the emit to the Gtk message queue +- log.debug("_autoContinue clicking continue button") ++ log.debug("automatically clicking continue button") + gtk_call_once(self.window.emit, "continue-clicked") + + return True +@@ -410,14 +410,18 @@ class Hub(GUIObject, common.Hub): + if selector: + selector.grab_focus() + ++ # The automated kickstart installation already continues. Nothing to do. ++ if self._click_continue: ++ return ++ + # On automated kickstart installs, our desired behavior is to display + # the hub while background processes work, then skip to the progress + # hub immediately after everything's done. + # However if the user proves his intent to change the kickstarted + # values by entering any of the spokes, we need to disable the +- # autoContinue feature and wait for the user to explicitly state ++ # auto continue feature and wait for the user to explicitly state + # that he is done configuring by pressing the continue button. +- self._autoContinue = False ++ self._auto_continue = False + + # Enter the spoke + self._inSpoke = True +-- +2.23.0 + diff --git a/bugfix-Don-t-generate-container-data-for-non-container-devi.patch b/bugfix-Don-t-generate-container-data-for-non-container-devi.patch new file mode 100644 index 0000000..f4d9001 --- /dev/null +++ b/bugfix-Don-t-generate-container-data-for-non-container-devi.patch @@ -0,0 +1,37 @@ +From 0c3cb13730730da2edcc6567bec8256eee9b1770 Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Thu, 13 Aug 2020 12:39:40 +0200 +Subject: [PATCH] Don't generate container data for non-container device types + +If the current device type is not a container device type, don't generate +container data for the device factory request. +--- + pyanaconda/modules/storage/partitioning/interactive/utils.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/pyanaconda/modules/storage/partitioning/interactive/utils.py b/pyanaconda/modules/storage/partitioning/interactive/utils.py +index 0057abd6e..04313eded 100644 +--- a/pyanaconda/modules/storage/partitioning/interactive/utils.py ++++ b/pyanaconda/modules/storage/partitioning/interactive/utils.py +@@ -808,6 +808,7 @@ def generate_device_factory_request(storage, device) -> DeviceFactoryRequest: + if device_type is None: + raise UnsupportedDeviceError("Unsupported type of {}.".format(device.name)) + ++ # Generate the device data. + request = DeviceFactoryRequest() + request.device_spec = device.name + request.device_name = getattr(device.raw_device, "lvname", device.raw_device.name) +@@ -828,6 +829,10 @@ def generate_device_factory_request(storage, device) -> DeviceFactoryRequest: + + request.disks = [d.name for d in disks] + ++ if request.device_type not in CONTAINER_DEVICE_TYPES: ++ return request ++ ++ # Generate the container data. + factory = devicefactory.get_device_factory( + storage, + device_type=device_type, +-- +2.23.0 + diff --git a/bugfix-Fix-checking-ssl-certificate-for-metadata-1745064.patch b/bugfix-Fix-checking-ssl-certificate-for-metadata-1745064.patch new file mode 100644 index 0000000..9c709c5 --- /dev/null +++ b/bugfix-Fix-checking-ssl-certificate-for-metadata-1745064.patch @@ -0,0 +1,30 @@ +From e0168180824ab04d8ee6d798efb039bf3d5555dc Mon Sep 17 00:00:00 2001 +From: Jan Stodola +Date: Sat, 31 Oct 2020 22:16:35 +0100 +Subject: [PATCH] Fix checking ssl certificate for metadata (#1745064) + +If the url kickstart command is used with the --noverifyssl option, the +ssl certificate check needs to be disabled for the repository metadata. + +Resolves: rhbz#1745064 +--- + pyanaconda/payload/dnf/payload.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index 623518c66..f146b0dce 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -1677,7 +1677,8 @@ class DNFPayload(Payload): + # - the path to a cert file + # - True, to use the system's certificates + # - False, to not verify +- ssl_verify = data.ssl_configuration.ca_cert_path or conf.payload.verify_ssl ++ ssl_verify = (data.ssl_configuration.ca_cert_path ++ or (conf.payload.verify_ssl and data.ssl_verification_enabled)) + ssl_client_cert = data.ssl_configuration.client_cert_path or None + ssl_client_key = data.ssl_configuration.client_key_path or None + ssl_cert = (ssl_client_cert, ssl_client_key) if ssl_client_cert else None +-- +2.23.0 + diff --git a/bugfix-Fix-crash-on-first-entering-of-source-spoke.patch b/bugfix-Fix-crash-on-first-entering-of-source-spoke.patch new file mode 100644 index 0000000..07f45a2 --- /dev/null +++ b/bugfix-Fix-crash-on-first-entering-of-source-spoke.patch @@ -0,0 +1,40 @@ +From c3dbffacabc60f0149b142a1f6b3f29739e9288b Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Mon, 27 Jul 2020 18:13:30 +0200 +Subject: [PATCH] Fix crash on first entering of source spoke + +This is called by removing treeinfo repositories which happens thanks to the +initialization of the spoke and selecting first line. Just let everything go +because the repository is added later again (or at least it seems to be working +like that). + +Related: rhbz#1851207 +(cherry picked from commit 5136a4f961c98fec373033027502fba8b409c04d) +--- + pyanaconda/ui/gui/spokes/installation_source.py | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/installation_source.py b/pyanaconda/ui/gui/spokes/installation_source.py +index 0bd3b6938..7ed95c51d 100644 +--- a/pyanaconda/ui/gui/spokes/installation_source.py ++++ b/pyanaconda/ui/gui/spokes/installation_source.py +@@ -1639,10 +1639,12 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + + # Remove the input validation checks for this repo + repo = self._repo_store[itr][REPO_OBJ] +- self.remove_check(self._repo_checks[repo.repo_id].name_check) +- self.remove_check(self._repo_checks[repo.repo_id].url_check) +- self.remove_check(self._repo_checks[repo.repo_id].proxy_check) +- del self._repo_checks[repo.repo_id] ++ # avoid crash when the source is changed because of initialization ++ if repo.repo_id in self._repo_checks: ++ self.remove_check(self._repo_checks[repo.repo_id].name_check) ++ self.remove_check(self._repo_checks[repo.repo_id].url_check) ++ self.remove_check(self._repo_checks[repo.repo_id].proxy_check) ++ del self._repo_checks[repo.repo_id] + + self._repo_store.remove(itr) + if len(self._repo_store) == 0: +-- +2.23.0 + diff --git a/bugfix-Fix-creating-cached-LVs-on-encrypted-PVs.patch b/bugfix-Fix-creating-cached-LVs-on-encrypted-PVs.patch new file mode 100644 index 0000000..e7ea085 --- /dev/null +++ b/bugfix-Fix-creating-cached-LVs-on-encrypted-PVs.patch @@ -0,0 +1,56 @@ +From 373da9db5d1c7d138f87abfb69165bd9de413a41 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Mon, 13 Jul 2020 14:53:42 +0200 +Subject: [PATCH] Fix creating cached LVs on encrypted PVs + +We need to get the child device for encrypted PVs because the PV +devices from kickstart are the underlying partitions, not the +lvmpv formatted LUKS devices. + +Resolves: rhbz#1855973 +--- + .../partitioning/custom/custom_partitioning.py | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py b/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py +index 754a48e2e..17c125dd6 100644 +--- a/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py ++++ b/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py +@@ -851,6 +851,16 @@ class CustomPartitioningTask(NonInteractivePartitioningTask): + if data.logvol.lvList: + grow_lvm(storage) + ++ def _get_cache_pv_devices(self, devicetree, logvol_data): ++ pv_devices = [] ++ for pvname in logvol_data.cache_pvs: ++ pv = lookup_alias(devicetree, pvname) ++ if pv.format.type == "luks": ++ pv_devices.append(pv.children[0]) ++ else: ++ pv_devices.append(pv) ++ return pv_devices ++ + def _execute_logvol_data(self, storage, data, logvol_data): + """Execute the logvol data. + +@@ -927,7 +937,7 @@ class CustomPartitioningTask(NonInteractivePartitioningTask): + + # If cache PVs specified, check that they belong to the same VG this LV is a member of + if logvol_data.cache_pvs: +- pv_devices = (lookup_alias(devicetree, pv) for pv in logvol_data.cache_pvs) ++ pv_devices = self._get_cache_pv_devices(devicetree, logvol_data) + if not all(pv in vg.pvs for pv in pv_devices): + raise KickstartParseError( + _("Cache PVs must belong to the same VG as the cached LV"), +@@ -1096,7 +1106,7 @@ class CustomPartitioningTask(NonInteractivePartitioningTask): + maxsize = None + + if logvol_data.cache_size and logvol_data.cache_pvs: +- pv_devices = [lookup_alias(devicetree, pv) for pv in logvol_data.cache_pvs] ++ pv_devices = self._get_cache_pv_devices(devicetree, logvol_data) + cache_size = Size("%d MiB" % logvol_data.cache_size) + cache_mode = logvol_data.cache_mode or None + cache_request = LVMCacheRequest(cache_size, pv_devices, cache_mode) +-- +2.23.0 + diff --git a/bugfix-Fix-error-in-initrd-shift-count-out-of-range.patch b/bugfix-Fix-error-in-initrd-shift-count-out-of-range.patch new file mode 100644 index 0000000..bde8d47 --- /dev/null +++ b/bugfix-Fix-error-in-initrd-shift-count-out-of-range.patch @@ -0,0 +1,35 @@ +From bc8779761fe60313a1c754a6b24c2861e86a5e62 Mon Sep 17 00:00:00 2001 +From: Jan Stodola +Date: Sat, 14 Nov 2020 21:27:45 +0100 +Subject: [PATCH] Fix error in initrd: shift count out of range + +anaconda_live_root_dir() can be called with just one argument (for example +when booting boot.iso) and the following error is reported: + +20:26:12,641 INFO dracut-initqueue:anaconda using disk root at /dev/sr0 +20:26:12,650 DEBUG kernel:ISO 9660 Extensions: Microsoft Joliet Level 3 +20:26:12,654 DEBUG kernel:ISO 9660 Extensions: RRIP_1991A +20:26:12,654 INFO dracut-initqueue:/lib/anaconda-lib.sh: line 71: shift: 2: shift count out of range +20:26:12,656 INFO dracut-initqueue:anaconda: found /run/install/repo//images/install.img + +Remove the shift call, since it has no use. +--- + dracut/anaconda-lib.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh +index 3b86f3df9..0dc8c817e 100755 +--- a/dracut/anaconda-lib.sh ++++ b/dracut/anaconda-lib.sh +@@ -68,7 +68,7 @@ rulesfile="/etc/udev/rules.d/90-anaconda.rules" + # try to find a usable runtime image from the repo mounted at $mnt. + # if successful, move the mount(s) to $repodir/$isodir. + anaconda_live_root_dir() { +- local img="" iso="" srcdir="" mnt="$1" path="$2"; shift 2 ++ local img="" iso="" srcdir="" mnt="$1" path="$2" + img=$(find_runtime $mnt/$path) + if [ -n "$img" ]; then + info "anaconda: found $img" +-- +2.23.0 + diff --git a/bugfix-Fix-issue-that-treeinfo-repositories-were-never-disa.patch b/bugfix-Fix-issue-that-treeinfo-repositories-were-never-disa.patch new file mode 100644 index 0000000..ed3a178 --- /dev/null +++ b/bugfix-Fix-issue-that-treeinfo-repositories-were-never-disa.patch @@ -0,0 +1,34 @@ +From a57be7d30897ecf301de673e41d1af975b4f593b Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Wed, 29 Jul 2020 14:12:51 +0200 +Subject: [PATCH] Fix issue that treeinfo repositories were never disabled + +The add_repo() method always enable repository at the end. We should improve +this correctly in the upstream to avoid the confusion. + +Related: rhbz#1851207 +(cherry picked from commit d26f4e4cd054288360993220bc9cee4b7abf5ddc) +--- + pyanaconda/payload/dnf/payload.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index 02a66cd25..56c52f54e 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -1852,7 +1852,11 @@ class DNFPayload(Payload): + repo.treeinfo_origin = True + log.debug("Adding new treeinfo repository: %s enabled: %s", + repo_md.name, repo_enabled) +- self.add_repo(repo) ++ ++ if repo_enabled: ++ self.add_repo(repo) ++ else: ++ self.add_disabled_repo(repo) + + def _cleanup_old_treeinfo_repositories(self): + """Remove all old treeinfo repositories before loading new ones. +-- +2.23.0 + diff --git a/bugfix-Fix-issue-when-NFS-path-is-pointing-directly-to-ISO-.patch b/bugfix-Fix-issue-when-NFS-path-is-pointing-directly-to-ISO-.patch new file mode 100644 index 0000000..b5d2951 --- /dev/null +++ b/bugfix-Fix-issue-when-NFS-path-is-pointing-directly-to-ISO-.patch @@ -0,0 +1,79 @@ +From 6317147760315ebc269470b3fdb3f66eaeefe9b2 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Fri, 19 Jun 2020 13:24:57 +0200 +Subject: [PATCH] Fix issue when NFS path is pointing directly to ISO + (#1848718) + +This is totally my fault... The problem is that I thought that this will happen +when mounting and finding the ISO but not for the NFS mount. NFS mount can't be +done for an ISO image but only for the directory. + +Resolves: rhbz#1848718 +Resolves: rhbz#1849083 + +Reported-by: Adam Williamson +--- + .../payloads/source/nfs/initialization.py | 28 ++++++++++++++++--- + 1 file changed, 24 insertions(+), 4 deletions(-) + +diff --git a/pyanaconda/modules/payloads/source/nfs/initialization.py b/pyanaconda/modules/payloads/source/nfs/initialization.py +index 99601bf32..f21c641ea 100644 +--- a/pyanaconda/modules/payloads/source/nfs/initialization.py ++++ b/pyanaconda/modules/payloads/source/nfs/initialization.py +@@ -19,6 +19,7 @@ import os.path + + from pyanaconda.anaconda_loggers import get_module_logger + from pyanaconda.core.payload import parse_nfs_url ++from pyanaconda.core.util import join_paths + from pyanaconda.modules.common.errors.payload import SourceSetupError + from pyanaconda.modules.common.task import Task + from pyanaconda.modules.payloads.source.utils import find_and_mount_iso_image, \ +@@ -54,12 +55,16 @@ class SetUpNFSSourceTask(Task): + mount_point + )) + ++ options, host, path = parse_nfs_url(self._url) ++ path, image = self._split_iso_from_path(path) + try: +- self._mount_nfs() ++ self._mount_nfs(host, options, path) + except PayloadSetupError: + raise SourceSetupError("Could not mount NFS url '{}'".format(self._url)) + +- iso_name = find_and_mount_iso_image(self._device_mount, self._iso_mount) ++ iso_source_path = join_paths(self._device_mount, image) if image else self._device_mount ++ ++ iso_name = find_and_mount_iso_image(iso_source_path, self._iso_mount) + + if iso_name: + log.debug("Using the ISO '%s' mounted at '%s'.", iso_name, self._iso_mount) +@@ -74,9 +79,24 @@ class SetUpNFSSourceTask(Task): + raise SourceSetupError( + "Nothing useful found for NFS source at {}".format(self._url)) + +- def _mount_nfs(self): +- options, host, path = parse_nfs_url(self._url) ++ @staticmethod ++ def _split_iso_from_path(path): ++ """Split ISO from NFS path. ++ ++ NFS path could also contain pointer to ISO which should be mounted. Problem of this ++ is that NFS path with ISO cannot be mounted as NFS mount. We have to split these ++ before mount. ++ ++ :param path: path on the NFS server which could point to ISO ++ :return: tuple of path, iso_file_name; is_file_name is empty if no ISO is part of the path ++ :rtype: tuple (str, str) ++ """ ++ if path.endswith(".iso"): ++ return path.rsplit("/", maxsplit=1) ++ ++ return path, "" + ++ def _mount_nfs(self, host, options, path): + if not options: + options = "nolock" + elif "nolock" not in options: +-- +2.23.0 + diff --git a/bugfix-Fix-kickstart-file-error-with-user-groups.patch b/bugfix-Fix-kickstart-file-error-with-user-groups.patch new file mode 100644 index 0000000..5f8ca48 --- /dev/null +++ b/bugfix-Fix-kickstart-file-error-with-user-groups.patch @@ -0,0 +1,40 @@ +From dac59c13424e403f73e3cad46e7412482b17f92a Mon Sep 17 00:00:00 2001 +From: Kai Kang +Date: Thu, 6 Aug 2020 17:09:25 +0800 +Subject: [PATCH] Fix kickstart file error with user groups + +When fill the "Group Membership" in "ADVANCED USER CONFIGURATION" +dialog with the provided example text: + +wheel, my-team (1245), project-x (29935) + +It keeps the spaces between group name(project-x) and group id('(29935)'), +and then write them to kickstart file. When boot anaconda with the kickstart +file, it fails with: + +| unrecognzed arguments: (1245),project-x (29935) + +Filter out the spaces between group name and group id to avoid such +issue. + +Signed-off-by: Kai Kang +--- + pyanaconda/ui/gui/spokes/user.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py +index 82fbdc8f8..05e01f8a6 100644 +--- a/pyanaconda/ui/gui/spokes/user.py ++++ b/pyanaconda/ui/gui/spokes/user.py +@@ -157,7 +157,7 @@ class AdvancedUserDialog(GUIObject, GUIDialogInputCheckHandler): + self.user.gid = USER_GID_NOT_SET + + # ''.split(',') returns [''] instead of [], which is not what we want +- self.user.groups = [g.strip() for g in self._tGroups.get_text().split(",") if g] ++ self.user.groups = [''.join(g.split()) for g in self._tGroups.get_text().split(",") if g] + + # Send ready signal to main event loop + hubQ.send_ready(self.__class__.__name__, False) +-- +2.23.0 + diff --git a/bugfix-Fix-more-SElinux-contexts.patch b/bugfix-Fix-more-SElinux-contexts.patch new file mode 100644 index 0000000..4867a62 --- /dev/null +++ b/bugfix-Fix-more-SElinux-contexts.patch @@ -0,0 +1,32 @@ +From 1e873f5084f84e16c5d26b65f29ba401ee7f7f94 Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Wed, 3 Jun 2020 15:54:00 +0200 +Subject: [PATCH] Fix more SElinux contexts + +Apparently we have them wrong in /boot/loader/entries and /etc/dnf/modules.d/ +See the linmked bugs for more details. This is a bit workaroundish, but works. + +Resolves: rhbz#1775975 +Resolves: rhbz#1834189 +--- + data/post-scripts/80-setfilecons.ks | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/data/post-scripts/80-setfilecons.ks b/data/post-scripts/80-setfilecons.ks +index d6f183ce8..f08e308e3 100644 +--- a/data/post-scripts/80-setfilecons.ks ++++ b/data/post-scripts/80-setfilecons.ks +@@ -13,7 +13,9 @@ restorecon -ir /etc/sysconfig/network-scripts /etc/lvm /etc/X11/xorg.conf.d \ + /var/lib /var/lib/iscsi /var/lock /var/log /var/spool \ + /var/cache/yum \ + /dev \ +- /root ++ /root \ ++ /boot \ ++ /etc/dnf/modules.d + + # Also relabel the OSTree variants of the traditional mounts if present + restorecon -ir /var/roothome /var/home /var/opt /var/srv /var/media /var/mnt +-- +2.23.0 + diff --git a/bugfix-Fix-passing-of-arguments-when-creating-dracut-argume.patch b/bugfix-Fix-passing-of-arguments-when-creating-dracut-argume.patch new file mode 100644 index 0000000..c421c31 --- /dev/null +++ b/bugfix-Fix-passing-of-arguments-when-creating-dracut-argume.patch @@ -0,0 +1,48 @@ +From 1f384563fd5aa4070cd0b75a6bcaee1648884499 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Thu, 4 Jun 2020 13:21:53 +0200 +Subject: [PATCH] Fix passing of arguments when creating dracut arguments for + FCoE + +Resolves: rhbz#1843741 + +Port of https://github.com/rhinstaller/anaconda/pull/2644 +--- + pyanaconda/modules/storage/bootloader/base.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py +index 9ec3def57..4711513ee 100644 +--- a/pyanaconda/modules/storage/bootloader/base.py ++++ b/pyanaconda/modules/storage/bootloader/base.py +@@ -792,19 +792,25 @@ class BootLoader(object): + network_args = [] + ibft = False + nic = "" ++ host_address = dep.host_address or "" + if isinstance(dep, blivet.devices.iScsiDiskDevice): + if dep.iface == "default" or ":" in dep.iface: + node = _get_iscsi_node_from_device(dep) + if iscsi_proxy.IsNodeFromIbft(Node.to_structure(node)): + ibft = True + else: +- nic = iface_for_host_ip(dep.host_address) ++ nic = iface_for_host_ip(host_address) + else: + nic = iscsi_proxy.GetInterface(dep.iface) + else: + nic = dep.nic + if nic or ibft: +- network_args = network_proxy.GetDracutArguments(nic, dep.host_address, "", ibft) ++ network_args = network_proxy.GetDracutArguments( ++ nic, ++ host_address, ++ "", ++ ibft ++ ) + + self.boot_args.update(network_args) + self.dracut_args.update(network_args) +-- +2.23.0 + diff --git a/bugfix-Fix-regression-reading-kernel-list-when-collecting-c.patch b/bugfix-Fix-regression-reading-kernel-list-when-collecting-c.patch new file mode 100644 index 0000000..808d243 --- /dev/null +++ b/bugfix-Fix-regression-reading-kernel-list-when-collecting-c.patch @@ -0,0 +1,41 @@ +From 9858b6e456630d5bdad5b6084c87e60749964f26 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Thu, 11 Jun 2020 16:56:07 +0200 +Subject: [PATCH] Fix regression reading kernel list when collecting + configurations (#1846156) + +We have to have payload prepared to be able to read list of kernels from the +installation source. However, during transitioning to storage module we moved +reading list of kernels to place where the installation tasks are collected +instead of where they are executed. + +Create a function which will read this list and execute everything later during +the installation tasks execution. + +Resolves: rhbz#1846156 +--- + pyanaconda/installation.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/installation.py b/pyanaconda/installation.py +index a6ec79401..d9596bac8 100644 +--- a/pyanaconda/installation.py ++++ b/pyanaconda/installation.py +@@ -159,9 +159,12 @@ def _prepare_configuration(payload, ksdata): + # been created, fixing the kernel root and subvol args and adding the missing initrd entry. + bootloader_proxy = STORAGE.get_proxy(BOOTLOADER) + +- if payload.type in PAYLOAD_LIVE_TYPES: ++ def fix_btrfs_bootloader(): + btrfs_task = bootloader_proxy.FixBTRFSWithTask(payload.kernel_version_list) +- generate_initramfs.append_dbus_tasks(STORAGE, [btrfs_task]) ++ sync_run_task(STORAGE.get_proxy(btrfs_task)) ++ ++ if payload.type in PAYLOAD_LIVE_TYPES: ++ generate_initramfs.append(Task("Fix bootloader on BTRFS", fix_btrfs_bootloader)) + + # Invoking zipl should be the last thing done on a s390x installation (see #1652727). + zipl_task = bootloader_proxy.FixZIPLWithTask() +-- +2.23.0 + diff --git a/bugfix-Fix-the-combo-box-for-an-URL-type-of-additional-repo.patch b/bugfix-Fix-the-combo-box-for-an-URL-type-of-additional-repo.patch new file mode 100644 index 0000000..6981d62 --- /dev/null +++ b/bugfix-Fix-the-combo-box-for-an-URL-type-of-additional-repo.patch @@ -0,0 +1,40 @@ +From 2585d3380ebbd516757a2420486e68e2809961db Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Tue, 15 Sep 2020 17:25:28 +0200 +Subject: [PATCH] Fix the combo box for an URL type of additional repositories + (#1879127) + +In the commit ff9a7e1, we introduced new constants for the URL source types with +values 'BASEURL', 'MIRRORLIST' and 'METALINK'. In the commit cc2c3d3, we started +to use these constants in the Installation Source spoke and removed the old ones +with values 'url', 'mirrorlist' and 'metalink'. We updated the combo box for the +base repository, but forgot to update the combo box for additional repositories. + +The combo box items have to have ids that match the values of the constants, +otherwise the URL type of additional repositories will be always 'BASEURL'. + +Resolves: rhbz#1879127 +--- + pyanaconda/ui/gui/spokes/installation_source.glade | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/installation_source.glade b/pyanaconda/ui/gui/spokes/installation_source.glade +index e53fa230c..bc07a4a7b 100644 +--- a/pyanaconda/ui/gui/spokes/installation_source.glade ++++ b/pyanaconda/ui/gui/spokes/installation_source.glade +@@ -1296,9 +1296,9 @@ + False + start + +- repository URL +- mirrorlist +- metalink ++ repository URL ++ mirrorlist ++ metalink + + + +-- +2.23.0 + diff --git a/bugfix-Fix-the-logic-for-enabling-latest-updates.patch b/bugfix-Fix-the-logic-for-enabling-latest-updates.patch new file mode 100644 index 0000000..7d117e5 --- /dev/null +++ b/bugfix-Fix-the-logic-for-enabling-latest-updates.patch @@ -0,0 +1,41 @@ +From 98e011f1f8af900ed6f65432ad7466973d44735a Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Fri, 27 Nov 2020 14:33:31 +0100 +Subject: [PATCH] Fix the logic for enabling latest updates + +Fix bugs introduced in the commit 4a2b8f2. The negation of the logic wasn't +applied correctly. Without the fix, updates repositories are disabled when the +updates are enabled. +--- + pyanaconda/ui/gui/spokes/installation_source.py | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/installation_source.py b/pyanaconda/ui/gui/spokes/installation_source.py +index 00a180613..e528d8662 100644 +--- a/pyanaconda/ui/gui/spokes/installation_source.py ++++ b/pyanaconda/ui/gui/spokes/installation_source.py +@@ -1085,7 +1085,7 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + uncheck it. + """ + self._updates_box.set_sensitive(self._mirror_active()) +- active = self._mirror_active() or self.payload.is_repo_enabled("updates") ++ active = self._mirror_active() and self.payload.is_repo_enabled("updates") + self._updates_radio_button.set_active(active) + + @property +@@ -1646,10 +1646,8 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + + def on_updatesRadioButton_toggled(self, button): + """Toggle the enable state of the updates repo.""" +- if self._updates_radio_button.get_active(): +- self.payload.set_updates_enabled(False) +- else: +- self.payload.set_updates_enabled(True) ++ active = self._updates_radio_button.get_active() ++ self.payload.set_updates_enabled(active) + + # Refresh the metadata using the new set of repos + self._updates_change = True +-- +2.23.0 + diff --git a/bugfix-Fix-traceback-when-removing-additional-repository.patch b/bugfix-Fix-traceback-when-removing-additional-repository.patch new file mode 100644 index 0000000..9ccbdd6 --- /dev/null +++ b/bugfix-Fix-traceback-when-removing-additional-repository.patch @@ -0,0 +1,34 @@ +From b7ee1291870a0d6689ff6d81e1c50999f38cd6b7 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Fri, 21 Aug 2020 15:07:28 +0200 +Subject: [PATCH] Fix traceback when removing additional repository + +I made a mistake by missing `not` in the condition. That way the repo removal as +user action crashed Anaconda because variable which was not set was immediately +used. + +Unfortunately, I tested this just on the failing use-case and in that case it +looked like it is working correctly (but didn't really). + +Resolves: rhbz#1871037 +(cherry picked from commit a92428aa61f31d3f25786d4e90108d0d7751d680) +--- + pyanaconda/ui/gui/spokes/installation_source.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pyanaconda/ui/gui/spokes/installation_source.py b/pyanaconda/ui/gui/spokes/installation_source.py +index 7ed95c51d..76631754b 100644 +--- a/pyanaconda/ui/gui/spokes/installation_source.py ++++ b/pyanaconda/ui/gui/spokes/installation_source.py +@@ -1629,7 +1629,7 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + :param repo_model_path: repo_model_path of what we can remove or None + :type repo_model_path: repo_store repo_model_path + """ +- if repo_model_path is None: ++ if repo_model_path is not None: + itr = self._repo_store[repo_model_path].iter + else: + itr = self._repo_selection.get_selected()[1] +-- +2.23.0 + diff --git a/bugfix-Fix-traceback-when-starting-installation-with-inst.c.patch b/bugfix-Fix-traceback-when-starting-installation-with-inst.c.patch new file mode 100644 index 0000000..e3001b8 --- /dev/null +++ b/bugfix-Fix-traceback-when-starting-installation-with-inst.c.patch @@ -0,0 +1,36 @@ +From 0f9873a2ffbf3a180a236c4f036e54520773f2ca Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Tue, 22 Sep 2020 16:28:48 +0200 +Subject: [PATCH] Fix traceback when starting installation with inst.console + (no args) + +None is the default value which would fail on os.path.basename call. +--- + pyanaconda/modules/storage/bootloader/base.py | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py +index b1122287a..a8eb26cc7 100644 +--- a/pyanaconda/modules/storage/bootloader/base.py ++++ b/pyanaconda/modules/storage/bootloader/base.py +@@ -903,10 +903,16 @@ class BootLoader(object): + + def _set_console(self): + """ Set console options based on boot arguments. """ +- console = kernel_arguments.get("console", "") ++ console = kernel_arguments.get("console") ++ ++ if not console: ++ return ++ + console = os.path.basename(console) + self.console, _x, self.console_options = console.partition(",") + ++ log.debug("Console is set to %s with options '%s'", self.console, self.console_options) ++ + def write_config_console(self, config): + """Write console-related configuration lines.""" + pass +-- +2.23.0 + diff --git a/bugfix-Handle-exceptions-from-threads-without-new-instances.patch b/bugfix-Handle-exceptions-from-threads-without-new-instances.patch new file mode 100644 index 0000000..84f56ba --- /dev/null +++ b/bugfix-Handle-exceptions-from-threads-without-new-instances.patch @@ -0,0 +1,36 @@ +From 8ab916a0fe7b46b20c3a51828600b4f7f207717a Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Tue, 18 Aug 2020 15:23:49 +0200 +Subject: [PATCH] Handle exceptions from threads without new instances + +It is not possible to instantiate some exceptions with just an instance as +the only argument, for example UnicodeError and descendants. However, these +days it is possible to raise directly with the provided instance, no need to +instantiate the class. The instance also has the traceback already set, so no +need to set it either. + +The original apparently came to be so due to incrementally rewriting python2's +3-argument form of raise. See also previous commits affecting this line, +in chronological order: 07b7034, d16512e, a6085b8. + +Resolves: rhbz#1835027 +--- + pyanaconda/threading.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pyanaconda/threading.py b/pyanaconda/threading.py +index e0ab80229..d2327cf39 100644 +--- a/pyanaconda/threading.py ++++ b/pyanaconda/threading.py +@@ -168,7 +168,7 @@ class ThreadManager(object): + with self._errors_lock: + exc_info = self._errors.pop(name) + if exc_info: +- raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) ++ raise exc_info[1] + + def in_main_thread(self): + """Return True if it is run in the main thread.""" +-- +2.23.0 + diff --git a/bugfix-Keep-treeinfo-repositories-disabled-after-payload-re.patch b/bugfix-Keep-treeinfo-repositories-disabled-after-payload-re.patch new file mode 100644 index 0000000..931e6de --- /dev/null +++ b/bugfix-Keep-treeinfo-repositories-disabled-after-payload-re.patch @@ -0,0 +1,101 @@ +From 7982cf9937165ad34fe3c4bdf2cf2155a4f5e7f8 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Thu, 30 Jul 2020 13:25:28 +0200 +Subject: [PATCH] Keep treeinfo repositories disabled after payload reset + +Without this change user can't disable repositories because they are +reloaded and enabled automatically as new ones. + +Related: rhbz#1851207 +(cherry picked from commit 0750143fca814b660eba719c2df597d3af5998f8) +--- + pyanaconda/payload/dnf/payload.py | 33 +++++++++++++++++++++++++------ + 1 file changed, 27 insertions(+), 6 deletions(-) + +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index 227d32c82..02a66cd25 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -1455,7 +1455,7 @@ class DNFPayload(Payload): + log.info("Configuring the base repo") + self.reset() + +- self._cleanup_old_treeinfo_repositories() ++ disabled_treeinfo_repo_names = self._cleanup_old_treeinfo_repositories() + + # Find the source and its type. + source_proxy = self.get_source_proxy() +@@ -1511,7 +1511,7 @@ class DNFPayload(Payload): + base_repo_url = self._get_base_repo_location(install_tree_url) + log.debug("releasever from %s is %s", base_repo_url, self._base.conf.releasever) + +- self._load_treeinfo_repositories(base_repo_url) ++ self._load_treeinfo_repositories(base_repo_url, disabled_treeinfo_repo_names) + except configparser.MissingSectionHeaderError as e: + log.error("couldn't set releasever from base repo (%s): %s", source_type, e) + +@@ -1817,11 +1817,13 @@ class DNFPayload(Payload): + log.debug("No base repository found in treeinfo file. Using installation tree root.") + return install_tree_url + +- def _load_treeinfo_repositories(self, base_repo_url): ++ def _load_treeinfo_repositories(self, base_repo_url, repo_names_to_disable): + """Load new repositories from treeinfo file. + + :param base_repo_url: base repository url. This is not saved anywhere when the function + is called. It will be add to the existing urls if not None. ++ :param repo_names_to_disable: list of repository names which should be disabled after load ++ :type repo_names_to_disable: [str] + """ + if self._install_tree_metadata: + existing_urls = [] +@@ -1838,11 +1840,18 @@ class DNFPayload(Payload): + for repo_md in self._install_tree_metadata.get_metadata_repos(): + if repo_md.path not in existing_urls: + repo_treeinfo = self._install_tree_metadata.get_treeinfo_for(repo_md.name) +- repo_enabled = repo_treeinfo.type in enabled_repositories_from_treeinfo ++ ++ # disable repositories disabled by user manually before ++ if repo_md.name in repo_names_to_disable: ++ repo_enabled = False ++ else: ++ repo_enabled = repo_treeinfo.type in enabled_repositories_from_treeinfo ++ + repo = RepoData(name=repo_md.name, baseurl=repo_md.path, + install=False, enabled=repo_enabled) + repo.treeinfo_origin = True +- log.debug("Adding new treeinfo repository %s", repo_md.name) ++ log.debug("Adding new treeinfo repository: %s enabled: %s", ++ repo_md.name, repo_enabled) + self.add_repo(repo) + + def _cleanup_old_treeinfo_repositories(self): +@@ -1850,12 +1859,24 @@ class DNFPayload(Payload): + + Find all repositories added from treeinfo file and remove them. After this step new + repositories will be loaded from the new link. ++ ++ :return: list of repository names which were disabled before removal ++ :rtype: [str] + """ ++ disabled_repo_names = [] ++ + for ks_repo_name in self.addons: +- if self.get_addon_repo(ks_repo_name).treeinfo_origin: ++ repo = self.get_addon_repo(ks_repo_name) ++ if repo.treeinfo_origin: + log.debug("Removing old treeinfo repository %s", ks_repo_name) ++ ++ if not repo.enabled: ++ disabled_repo_names.append(ks_repo_name) ++ + self.remove_repo(ks_repo_name) + ++ return disabled_repo_names ++ + def _write_dnf_repo(self, repo, repo_path): + """Write a repo object to a DNF repo.conf file. + +-- +2.23.0 + diff --git a/bugfix-Never-mount-partitions-on-a-disk-with-the-iso9660-fi.patch b/bugfix-Never-mount-partitions-on-a-disk-with-the-iso9660-fi.patch new file mode 100644 index 0000000..0191b1b --- /dev/null +++ b/bugfix-Never-mount-partitions-on-a-disk-with-the-iso9660-fi.patch @@ -0,0 +1,101 @@ +From b224f888c225d9735abaa82d0156ae5a4c38d4f5 Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Fri, 18 Sep 2020 15:13:14 +0200 +Subject: [PATCH] Never mount partitions on a disk with the iso9660 filesystem + +Blivet doesn't recognize these partitions, so we mount the disk in stage2. +However, it will fail if one of its partitions is already mounted, for example +in stage1. Therefore, skip these partitions in the script that looks for a root +image on devices and use the disk instead. + +The boot.iso has the following structure: + +NAME TYPE SIZE FSTYPE LABEL +sda disk 8.8G iso9660 RHEL-8-3-0-BaseOS-x86_64 +|-sda1 part 8.8G iso9660 RHEL-8-3-0-BaseOS-x86_64 +`-sda2 part 10M vfat ANACONDA + +And the following default boot options: + +inst.stage2=hd:LABEL=RHEL-8-3-0-BaseOS-x86_64 rd.live.check quiet + +Anaconda runs the anaconda-diskroot script for every device that matches the +specification from the inst.stage2 option. In this example, it is sda and sda1, +because both of them have the specified label RHEL-8-3-0-BaseOS-x86_64. With +the fix, the script will detect that sda1 is a partition on a disk with the +iso9660 filesystem and stop to process sda1. The script will succeed with sda. + +We should never rely on the order of the devices. + +(cherry-picked from a commit 301a09d) + +Related: rhbz#1878784 +--- + dracut/anaconda-diskroot | 17 ++++++++++++++++- + dracut/anaconda-lib.sh | 22 ++++++++++++++++++++++ + 2 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/dracut/anaconda-diskroot b/dracut/anaconda-diskroot +index 8846b1108..2797e6762 100755 +--- a/dracut/anaconda-diskroot ++++ b/dracut/anaconda-diskroot +@@ -41,7 +41,22 @@ dev="$1" + path="$2" # optional, could be empty + kickstart="$(getarg ks= inst.ks=)" + +-[ -e "/dev/root" ] && exit 1 # we already have a root device! ++# Log the device that triggered this job. ++debug_msg "Trying to find a root image on the device $dev." ++ ++# Do we already have a root device? ++# Then do not run again. ++[ -e "/dev/root" ] && exit 1 ++ ++# Skip partitions on a disk with the iso9660 filesystem. Blivet doesn't ++# recognize these partitions, so we mount the disk in stage2. However, it ++# will fail if one of its partitions is already mounted, for example here. ++# Therefore, skip the partitions and use the disk to find our root image. ++# See the bug 1878784. ++if dev_is_on_disk_with_iso9660 "$dev"; then ++ debug_msg "Skipping $dev on a disk with iso9660." ++ exit 1 ++fi + + # If we're waiting for a cdrom kickstart, the user might need to swap discs. + # So if this is a CDROM drive, make a note of it, but don't mount it (yet). +diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh +index e2ab7a205..3b86f3df9 100755 +--- a/dracut/anaconda-lib.sh ++++ b/dracut/anaconda-lib.sh +@@ -253,6 +253,28 @@ dev_is_cdrom() { + udevadm info --query=property --name=$1 | grep -q 'ID_CDROM=1' + } + ++dev_is_on_disk_with_iso9660() { ++ # Get the name of the device. ++ local dev_name="${1}" ++ ++ # Get the path of the device. ++ local dev_path="$(udevadm info -q path --name ${dev_name})" ++ ++ # Is the device a partition? ++ udevadm info -q property --path ${dev_path} | grep -q 'DEVTYPE=partition' || return 1 ++ ++ # Get the path of the parent. ++ local disk_path="${dev_path%/*}" ++ ++ # Is the parent a disk? ++ udevadm info -q property --path ${disk_path} | grep -q 'DEVTYPE=disk' || return 1 ++ ++ # Does the parent has the iso9660 filesystem? ++ udevadm info -q property --path ${disk_path} | grep -q 'ID_FS_TYPE=iso9660' || return 1 ++ ++ return 0 ++} ++ + # dracut doesn't bring up the network unless: + # a) $netroot is set (i.e. you have a network root device), or + # b) /tmp/net.ifaces exists. +-- +2.23.0 + diff --git a/bugfix-Only-pass-one-initrd-image-to-kexec.patch b/bugfix-Only-pass-one-initrd-image-to-kexec.patch new file mode 100644 index 0000000..91c2167 --- /dev/null +++ b/bugfix-Only-pass-one-initrd-image-to-kexec.patch @@ -0,0 +1,40 @@ +From 4766a00a9d67bfe93573e1160ac05fe9c8883aa9 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Thu, 9 Jul 2020 15:51:23 +0200 +Subject: [PATCH] Only pass one initrd image to kexec + +The kexec command line tool can only get a single initrd, but a boot entry +can have multiple ones. For example the tuned package adds a variable that +could be set to a second initrd image. + +If that's the case, it will lead to the following error: + +FileNotFoundError: [Errno 2] No such file or directory: +'/mnt/sysroot/boot/initramfs-4.18.0-223.el8.x86_64.img $tuned_initrd' + +Resolves: rhbz#1855290 + +Signed-off-by: Javier Martinez Canillas +--- + pyanaconda/kexec.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/pyanaconda/kexec.py b/pyanaconda/kexec.py +index 02033bb7e..37d2b4a14 100644 +--- a/pyanaconda/kexec.py ++++ b/pyanaconda/kexec.py +@@ -72,6 +72,11 @@ def run_grubby(args=None): + if boot_info_fields: + raise GrubbyInfoError("Missing values: %s" % ", ".join(boot_info_fields)) + ++ # There could be multiple initrd images defined for a boot entry, but ++ # the kexec command line tool only supports passing a single initrd. ++ if "initrd" in boot_info_args: ++ boot_info_args["initrd"] = boot_info_args["initrd"].split(" ")[0] ++ + boot_info = boot_info_class(**boot_info_args) + log.info("grubby boot info for (%s): %s", args, boot_info) + return boot_info +-- +2.23.0 + diff --git a/bugfix-Recognize-systemd.unit-anaconda.target-in-anaconda-g.patch b/bugfix-Recognize-systemd.unit-anaconda.target-in-anaconda-g.patch new file mode 100644 index 0000000..2529ae6 --- /dev/null +++ b/bugfix-Recognize-systemd.unit-anaconda.target-in-anaconda-g.patch @@ -0,0 +1,32 @@ +From ac6010448ba29f8c5b979d11cabeb09a91cf260c Mon Sep 17 00:00:00 2001 +From: Mikhail Novosyolov +Date: Mon, 31 Aug 2020 23:44:17 +0300 +Subject: [PATCH] Recognize systemd.unit=anaconda.target in anaconda-generator + +anaconda.target may be activated not only by symlinking /etc/systemd/systemd/default.target, +this symlink may even not exist, but by e.g. adding "systemd.unit=anaconda.target" +to kernel cmdline (see kernel-command-line(7) from systemd) + +`systemctl is-active -q anaconda.target` could be used here, but systemctl is not available from systemd generators. + +P.S. See https://www.redhat.com/archives/anaconda-devel-list/2012-August/msg00118.html for description why generator is needed. +--- + data/systemd/anaconda-generator | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/systemd/anaconda-generator b/data/systemd/anaconda-generator +index cda87480d..bafe74ea1 100755 +--- a/data/systemd/anaconda-generator ++++ b/data/systemd/anaconda-generator +@@ -5,7 +5,7 @@ + ANACONDA_TARGET="/lib/systemd/system/anaconda.target" + CURRENT_DEFAULT_TARGET=$(readlink /etc/systemd/system/default.target) + +-if [ "$ANACONDA_TARGET" != "$CURRENT_DEFAULT_TARGET" ]; then ++if ! { [ "$ANACONDA_TARGET" = "$CURRENT_DEFAULT_TARGET" ] || grep -q 'systemd.unit=anaconda.target' /proc/cmdline ;} ; then + exit 0 + fi + +-- +2.23.0 + diff --git a/bugfix-Reconfigure-DNF-payload-after-options-are-set.patch b/bugfix-Reconfigure-DNF-payload-after-options-are-set.patch new file mode 100644 index 0000000..c039241 --- /dev/null +++ b/bugfix-Reconfigure-DNF-payload-after-options-are-set.patch @@ -0,0 +1,29 @@ +From 2acb1357ee8b931662a1353a8956d5a0be176dec Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Tue, 23 Jun 2020 18:52:32 +0200 +Subject: [PATCH] Reconfigure DNF payload after options are set + +Fixes broken multilib boot option. + +Resolves: rhbz#1847603 +--- + pyanaconda/payload/dnf/payload.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index f92720890..b38e78cd3 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -173,6 +173,9 @@ class DNFPayload(Payload): + if opts.multiLib: + self.data.packages.multiLib = opts.multiLib + ++ # Reset all the other things now that we have new configuration. ++ self._configure() ++ + @property + def type(self): + """The DBus type of the payload.""" +-- +2.23.0 + diff --git a/bugfix-Reload-treeinfo-repositories-on-every-payload-reset.patch b/bugfix-Reload-treeinfo-repositories-on-every-payload-reset.patch new file mode 100644 index 0000000..3cdf27c --- /dev/null +++ b/bugfix-Reload-treeinfo-repositories-on-every-payload-reset.patch @@ -0,0 +1,120 @@ +From 6f27de8a38cc7900bb35a4fac4ec258f50207468 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Thu, 23 Jul 2020 13:49:41 +0200 +Subject: [PATCH] Reload treeinfo repositories on every payload reset + +Remove old repositories before loading new ones. We are changing the logic to +load new ones every time the base repo is changed. + +This will solve problem that additional repositories pointing to an +invalid path. This is happening because we moved source mounting to a +different folders for each source. + +Resolves: rhbz#1851207 +(cherry picked from commit 7b9e6c8ac29d56ed8b5d657ed6729cb5e239d09c) +--- + pyanaconda/payload/base.py | 8 +------- + pyanaconda/payload/dnf/payload.py | 29 +++++++++++++++++++---------- + 2 files changed, 20 insertions(+), 17 deletions(-) + +diff --git a/pyanaconda/payload/base.py b/pyanaconda/payload/base.py +index 285e27e05..5e56dbb29 100644 +--- a/pyanaconda/payload/base.py ++++ b/pyanaconda/payload/base.py +@@ -39,8 +39,6 @@ class Payload(metaclass=ABCMeta): + """ + self.data = data + +- self._first_payload_reset = True +- + # A list of verbose error strings from the subclass + self.verbose_errors = [] + +@@ -67,10 +65,6 @@ class Payload(metaclass=ABCMeta): + """The DBus type of the source.""" + return None + +- @property +- def first_payload_reset(self): +- return self._first_payload_reset +- + def is_ready(self): + """Is the payload ready?""" + return True +@@ -89,7 +83,7 @@ class Payload(metaclass=ABCMeta): + + This method could be overriden. + """ +- self._first_payload_reset = False ++ pass + + def release(self): + """Release any resources in use by this object, but do not do final +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index b693c776d..227d32c82 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -1455,6 +1455,8 @@ class DNFPayload(Payload): + log.info("Configuring the base repo") + self.reset() + ++ self._cleanup_old_treeinfo_repositories() ++ + # Find the source and its type. + source_proxy = self.get_source_proxy() + source_type = source_proxy.Type +@@ -1507,11 +1509,9 @@ class DNFPayload(Payload): + self._refresh_install_tree(data) + self._base.conf.releasever = self._get_release_version(install_tree_url) + base_repo_url = self._get_base_repo_location(install_tree_url) +- +- if self.first_payload_reset: +- self._add_treeinfo_repositories(install_tree_url, base_repo_url) +- + log.debug("releasever from %s is %s", base_repo_url, self._base.conf.releasever) ++ ++ self._load_treeinfo_repositories(base_repo_url) + except configparser.MissingSectionHeaderError as e: + log.error("couldn't set releasever from base repo (%s): %s", source_type, e) + +@@ -1817,12 +1817,11 @@ class DNFPayload(Payload): + log.debug("No base repository found in treeinfo file. Using installation tree root.") + return install_tree_url + +- def _add_treeinfo_repositories(self, install_tree_url, base_repo_url=None): +- """Add all repositories from treeinfo file which are not already loaded. ++ def _load_treeinfo_repositories(self, base_repo_url): ++ """Load new repositories from treeinfo file. + +- :param install_tree_url: Url to the installation tree root. +- :param base_repo_url: Base repository url. This is not saved anywhere when the function +- is called. It will be add to the existing urls if not None. ++ :param base_repo_url: base repository url. This is not saved anywhere when the function ++ is called. It will be add to the existing urls if not None. + """ + if self._install_tree_metadata: + existing_urls = [] +@@ -1843,9 +1842,19 @@ class DNFPayload(Payload): + repo = RepoData(name=repo_md.name, baseurl=repo_md.path, + install=False, enabled=repo_enabled) + repo.treeinfo_origin = True ++ log.debug("Adding new treeinfo repository %s", repo_md.name) + self.add_repo(repo) + +- return install_tree_url ++ def _cleanup_old_treeinfo_repositories(self): ++ """Remove all old treeinfo repositories before loading new ones. ++ ++ Find all repositories added from treeinfo file and remove them. After this step new ++ repositories will be loaded from the new link. ++ """ ++ for ks_repo_name in self.addons: ++ if self.get_addon_repo(ks_repo_name).treeinfo_origin: ++ log.debug("Removing old treeinfo repository %s", ks_repo_name) ++ self.remove_repo(ks_repo_name) + + def _write_dnf_repo(self, repo, repo_path): + """Write a repo object to a DNF repo.conf file. +-- +2.23.0 + diff --git a/bugfix-Remove-treeinfo-repositories-instead-of-disabling.patch b/bugfix-Remove-treeinfo-repositories-instead-of-disabling.patch new file mode 100644 index 0000000..99df0c8 --- /dev/null +++ b/bugfix-Remove-treeinfo-repositories-instead-of-disabling.patch @@ -0,0 +1,128 @@ +From 6f52b733470d5565bc8e9a2a2415997d0ecbba54 Mon Sep 17 00:00:00 2001 +From: Jiri Konecny +Date: Mon, 27 Jul 2020 18:08:30 +0200 +Subject: [PATCH] Remove treeinfo repositories instead of disabling + +We now remove repositories from treeinfo file on each payload reset. In that +case we should not disable these in the source spoke but instead remove them. + +We should ideally also show them back to user when the source is switched back +but that logic to detect if base repo repository have changed is not trivial and +we had to change _update_payload_repos to achieve this. We don't want to +introduce any more regressions and that code change could do that. + +Related: rhbz#1851207 +(cherry picked from commit 8b99a20860a193d2816b53e89e562ba01bb1a825) +--- + .../ui/gui/spokes/installation_source.py | 44 ++++++++++++------- + 1 file changed, 28 insertions(+), 16 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/installation_source.py b/pyanaconda/ui/gui/spokes/installation_source.py +index 5b2f56b80..0bd3b6938 100644 +--- a/pyanaconda/ui/gui/spokes/installation_source.py ++++ b/pyanaconda/ui/gui/spokes/installation_source.py +@@ -429,8 +429,6 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + self._network_module = NETWORK.get_proxy() + self._device_tree = STORAGE.get_proxy(DEVICE_TREE) + +- self._treeinfo_repos_already_disabled = False +- + def apply(self): + source_changed = self._update_payload_source() + repo_changed = self._update_payload_repos() +@@ -1205,7 +1203,7 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + # the newly enabled button as well as the previously enabled (now + # disabled) button. + self._on_source_toggled(button, relatedBox) +- self._disable_treeinfo_repositories() ++ self._remove_treeinfo_repositories() + + def _on_source_toggled(self, button, relatedBox): + enabled = button.get_active() +@@ -1283,7 +1281,7 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + button.set_label(os.path.basename(iso_file)) + button.set_use_underline(False) + self._verify_iso_button.set_sensitive(True) +- self._disable_treeinfo_repositories() ++ self._remove_treeinfo_repositories() + + def on_proxy_clicked(self, button): + dialog = ProxyDialog(self.data, self._proxy_url) +@@ -1331,7 +1329,7 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + + def on_protocol_changed(self, combo): + self._on_protocol_changed() +- self._disable_treeinfo_repositories() ++ self._remove_treeinfo_repositories() + + def _on_protocol_changed(self): + # Only allow the URL entry to be used if we're using an HTTP/FTP +@@ -1431,8 +1429,6 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + self._clear_repo_info() + self._repo_entry_box.set_sensitive(False) + +- self._treeinfo_repos_already_disabled = False +- + def _unique_repo_name(self, name): + """ Return a unique variation of the name if it already + exists in the repo store. +@@ -1491,13 +1487,16 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + self._repo_store[repo_model_path][REPO_ENABLED_COL] = enabled + self._repo_store[repo_model_path][REPO_OBJ].enabled = enabled + +- def _disable_treeinfo_repositories(self): ++ def _remove_treeinfo_repositories(self): + """Disable all repositories loaded from the .treeinfo file""" +- if not self._treeinfo_repos_already_disabled: +- self._treeinfo_repos_already_disabled = True +- for repo_item in self._repo_store: +- if repo_item[REPO_OBJ].treeinfo_origin: +- self._set_repo_enabled(repo_item.path, False) ++ removal_repo_list = [] ++ ++ for repo_item in self._repo_store: ++ if repo_item[REPO_OBJ].treeinfo_origin: ++ removal_repo_list.append(repo_item.path) ++ ++ for path in removal_repo_list: ++ self._remove_repository(path) + + def _clear_repo_info(self): + """ Clear the text from the repo entry fields +@@ -1589,7 +1588,7 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + def on_urlEntry_changed(self, editable, data=None): + # Check for and remove a URL prefix that matches the protocol dropdown + self._on_urlEtry_changed(editable) +- self._disable_treeinfo_repositories() ++ self._remove_treeinfo_repositories() + + def _on_urlEtry_changed(self, editable): + self._remove_url_prefix(editable, self._protocol_combo_box, self.on_urlEntry_changed) +@@ -1619,9 +1618,22 @@ class SourceSpoke(NormalSpoke, GUISpokeInputCheckHandler, SourceSwitchHandler): + self._repo_entry_box.set_sensitive(True) + + def on_removeRepo_clicked(self, button): +- """ Remove the selected repository ++ """Remove the selected repository""" ++ self._remove_repository() ++ ++ def _remove_repository(self, repo_model_path=None): ++ """Remove repository on repo_model_path or current selection. ++ ++ If repo_model_path is not specified then current selection will be used. ++ ++ :param repo_model_path: repo_model_path of what we can remove or None ++ :type repo_model_path: repo_store repo_model_path + """ +- itr = self._repo_selection.get_selected()[1] ++ if repo_model_path is None: ++ itr = self._repo_store[repo_model_path].iter ++ else: ++ itr = self._repo_selection.get_selected()[1] ++ + if not itr: + return + +-- +2.23.0 + diff --git a/bugfix-Reset-the-RAID-level-of-the-device-request-1828092.patch b/bugfix-Reset-the-RAID-level-of-the-device-request-1828092.patch new file mode 100644 index 0000000..77d1da7 --- /dev/null +++ b/bugfix-Reset-the-RAID-level-of-the-device-request-1828092.patch @@ -0,0 +1,31 @@ +From d76c6060ea59215dbb90299b28fc8d59abf8e0fa Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Wed, 13 May 2020 18:59:26 +0200 +Subject: [PATCH] Reset the RAID level of the device request (#1828092) + +In the custom partitioning spoke, always reset the RAID level of the +device request when the device type changes. Otherwise, the new type +doesn't have to support the old RAID level. + +Resolves: rhbz#1828092 +--- + pyanaconda/ui/gui/spokes/custom_storage.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/pyanaconda/ui/gui/spokes/custom_storage.py b/pyanaconda/ui/gui/spokes/custom_storage.py +index 4e174a5f5..f0596263b 100644 +--- a/pyanaconda/ui/gui/spokes/custom_storage.py ++++ b/pyanaconda/ui/gui/spokes/custom_storage.py +@@ -1729,7 +1729,8 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler): + # this has to be done before calling populate_raid since it will need + # the raid level combo to contain the relevant raid levels for the new + # device type +- self._populate_raid() ++ self._request.device_raid_level = get_default_raid_level(new_type) ++ self._populate_raid(self._request.device_raid_level) + + # Generate a new container configuration for the new type. + self._request = DeviceFactoryRequest.from_structure( +-- +2.23.0 + diff --git a/bugfix-Root-password-is-mandatory-if-there-is-not-admin-use.patch b/bugfix-Root-password-is-mandatory-if-there-is-not-admin-use.patch new file mode 100644 index 0000000..8be445c --- /dev/null +++ b/bugfix-Root-password-is-mandatory-if-there-is-not-admin-use.patch @@ -0,0 +1,28 @@ +From 1f05aab7135ee3c5843c24a2a89bb707dcbe0dc5 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Thu, 17 Sep 2020 07:49:54 +0200 +Subject: [PATCH] Root password is mandatory if there is *not* admin user. + +Related: rhbz#1876727 +--- + pyanaconda/ui/tui/spokes/root_password.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/ui/tui/spokes/root_password.py b/pyanaconda/ui/tui/spokes/root_password.py +index 6ebc8f65e..345b5dcfe 100644 +--- a/pyanaconda/ui/tui/spokes/root_password.py ++++ b/pyanaconda/ui/tui/spokes/root_password.py +@@ -61,8 +61,8 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalTUISpoke): + + @property + def mandatory(self): +- """Root password spoke is mandatory if no users with admin rights have been requested.""" +- return self._users_module.CheckAdminUserExists() ++ """Only mandatory if no admin user has been requested.""" ++ return not self._users_module.CheckAdminUserExists() + + @property + def status(self): +-- +2.23.0 + diff --git a/bugfix-Run-actions-of-the-Resize-dialog-in-the-reversed-ord.patch b/bugfix-Run-actions-of-the-Resize-dialog-in-the-reversed-ord.patch new file mode 100644 index 0000000..a3a368b --- /dev/null +++ b/bugfix-Run-actions-of-the-Resize-dialog-in-the-reversed-ord.patch @@ -0,0 +1,86 @@ +From 2ca64adb8effcdfa8a883ee9f8fc2015cbece685 Mon Sep 17 00:00:00 2001 +From: Vendula Poncova +Date: Tue, 28 Jul 2020 11:58:23 +0200 +Subject: [PATCH] Run actions of the Resize dialog in the reversed order + (#1856496) + +If there is a disk with two logical partitions sda5 and sda6 and we remove sda5, +Blivet renames the partition sda6 to sda5, so the actions for sda6 are no longer +valid. Run actions in the reversed order to avoid this situation. + +Resolves: rhbz#1856496 +--- + pyanaconda/ui/gui/spokes/lib/resize.py | 29 +++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py +index 71dcffb05..4695e5332 100644 +--- a/pyanaconda/ui/gui/spokes/lib/resize.py ++++ b/pyanaconda/ui/gui/spokes/lib/resize.py +@@ -19,6 +19,7 @@ + from collections import namedtuple + from blivet.size import Size + ++from pyanaconda.anaconda_loggers import get_module_logger + from pyanaconda.core.i18n import _, C_, N_, P_ + from pyanaconda.modules.common.constants.services import STORAGE + from pyanaconda.modules.common.structures.storage import OSData, DeviceData, DeviceFormatData +@@ -55,6 +56,8 @@ SHRINK = N_("Shrink") + DELETE = N_("Delete") + NOTHING = "" + ++log = get_module_logger(__name__) ++ + + class ResizeDialog(GUIObject): + builderObjects = ["actionStore", "diskStore", "resizeDialog", "resizeAdjustment"] +@@ -521,7 +524,8 @@ class ResizeDialog(GUIObject): + self._update_reclaim_button(self._selected_reclaimable_space) + self._update_action_buttons() + +- def _schedule_actions(self, model, path, itr, *args): ++ def _collect_actionable_rows(self, model, path, itr, rows): ++ """Collect rows that can be transformed into actions.""" + obj = PartStoreRow(*model[itr]) + + if not obj.name: +@@ -530,17 +534,32 @@ class ResizeDialog(GUIObject): + if not obj.editable: + return False + ++ rows.append(obj) ++ return False ++ ++ def _schedule_actions(self, obj): ++ """Schedule actions for the given row object.""" + if obj.action == _(PRESERVE): +- pass ++ log.debug("Preserve %s.", obj.name) + elif obj.action == _(SHRINK): ++ log.debug("Shrink %s to %s.", obj.name, Size(obj.target)) + self._device_tree.ShrinkDevice(obj.name, obj.target) + elif obj.action == _(DELETE): ++ log.debug("Remove %s.", obj.name) + self._device_tree.RemoveDevice(obj.name) + +- return False +- + def on_resize_clicked(self, *args): +- self._disk_store.foreach(self._schedule_actions, None) ++ rows = [] ++ ++ # Collect the rows. ++ self._disk_store.foreach(self._collect_actionable_rows, rows) ++ ++ # Process rows in the reversed order. If there is a disk with ++ # two logical partitions sda5 and sda6 and we remove sda5, Blivet ++ # renames the partition sda6 to sda5, so the actions for sda6 are ++ # no longer valid. See the bug 1856496. ++ for obj in reversed(rows): ++ self._schedule_actions(obj) + + def on_delete_all_clicked(self, button, *args): + if button.get_label() == C_("GUI|Reclaim Dialog", "Delete _all"): +-- +2.23.0 + diff --git a/bugfix-Show-warning-message-when-entered-size-is-not-valid.patch b/bugfix-Show-warning-message-when-entered-size-is-not-valid.patch new file mode 100644 index 0000000..5bfd6b1 --- /dev/null +++ b/bugfix-Show-warning-message-when-entered-size-is-not-valid.patch @@ -0,0 +1,96 @@ +From 4bf4ba6d9a11cfd652ce48cdaea86bd617b6332a Mon Sep 17 00:00:00 2001 +From: Vladimir Slavik +Date: Tue, 28 Apr 2020 14:40:53 +0200 +Subject: [PATCH] Show warning message when entered size is not valid + +Requires also reordering checks such that the identical text test comes later. + +Resolves: rhbz#1809573 +--- + pyanaconda/ui/gui/spokes/custom_storage.py | 31 ++++++++++++++----- + .../gui/spokes/lib/custom_storage_helpers.py | 10 ++++++ + 2 files changed, 33 insertions(+), 8 deletions(-) + +diff --git a/pyanaconda/ui/gui/spokes/custom_storage.py b/pyanaconda/ui/gui/spokes/custom_storage.py +index 08e62cc40..f3755c48c 100644 +--- a/pyanaconda/ui/gui/spokes/custom_storage.py ++++ b/pyanaconda/ui/gui/spokes/custom_storage.py +@@ -63,7 +63,8 @@ from pyanaconda.ui.gui.spokes.lib.custom_storage_helpers import get_size_from_en + get_selected_raid_level, get_default_raid_level, get_container_type, AddDialog,\ + ConfirmDeleteDialog, DisksDialog, ContainerDialog, NOTEBOOK_LABEL_PAGE, NOTEBOOK_DETAILS_PAGE,\ + NOTEBOOK_LUKS_PAGE, NOTEBOOK_UNEDITABLE_PAGE, NOTEBOOK_INCOMPLETE_PAGE, NEW_CONTAINER_TEXT,\ +- CONTAINER_TOOLTIP, get_supported_device_raid_levels, generate_request_description ++ CONTAINER_TOOLTIP, DESIRED_CAPACITY_ERROR, get_supported_device_raid_levels, \ ++ generate_request_description + from pyanaconda.ui.gui.spokes.lib.passphrase import PassphraseDialog + from pyanaconda.ui.gui.spokes.lib.refresh import RefreshDialog + from pyanaconda.ui.gui.spokes.lib.summary import ActionSummaryDialog +@@ -1552,23 +1553,37 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler): + self._request.device_raid_level = get_selected_raid_level(self._raidLevelCombo) + self.on_value_changed() + +- def on_size_changed(self, widget): ++ @timed_action(750, 1500, False) ++ def on_size_changed(self, *args): ++ """Callback for text change in "desired capacity" widget""" + if not self._sizeEntry.get_sensitive(): + return + +- current_size = Size(self._request.device_size) +- displayed_size = current_size.human_readable(max_places=self.MAX_SIZE_PLACES) +- +- if displayed_size == self._sizeEntry.get_text(): +- return +- + size = get_size_from_entry( + self._sizeEntry, + lower_bound=self.MIN_SIZE_ENTRY, + units=SIZE_UNITS_DEFAULT + ) + ++ # Show warning if the size string is invalid. Field self._error is used as a "flag" that ++ # the last error was the same. This is done because this warning can fire on every change, ++ # so it would keep flickering at the bottom as you type. + if size is None: ++ if self._error != DESIRED_CAPACITY_ERROR: ++ self.clear_errors() ++ self.set_detailed_warning( ++ _("Invalid input. Specify the Desired Capacity in whole or decimal numbers, " ++ "with an appropriate unit."), ++ _(DESIRED_CAPACITY_ERROR) ++ ) ++ return ++ elif self._error == DESIRED_CAPACITY_ERROR: ++ self.clear_errors() ++ ++ current_size = Size(self._request.device_size) ++ displayed_size = current_size.human_readable(max_places=self.MAX_SIZE_PLACES) ++ ++ if displayed_size == self._sizeEntry.get_text(): + return + + self._request.device_size = size.get_bytes() +diff --git a/pyanaconda/ui/gui/spokes/lib/custom_storage_helpers.py b/pyanaconda/ui/gui/spokes/lib/custom_storage_helpers.py +index f7ae6cfa3..0dffaf0f7 100644 +--- a/pyanaconda/ui/gui/spokes/lib/custom_storage_helpers.py ++++ b/pyanaconda/ui/gui/spokes/lib/custom_storage_helpers.py +@@ -49,6 +49,16 @@ CONTAINER_TOOLTIP = N_("Create or select %(container_type)s") + CONTAINER_DIALOG_TITLE = N_("CONFIGURE %(container_type)s") + CONTAINER_DIALOG_TEXT = N_("Please create a name for this %(container_type)s " + "and select at least one disk below.") ++DESIRED_CAPACITY_ERROR = N_( ++ "Specify the Desired Capacity in whole or decimal numbers, with an appropriate unit.\n\n" ++ "Spaces separating digit groups are not allowed. Units consist of a decimal or binary " ++ "prefix, and optionally the letter B. Letter case does not matter for units. The default " ++ "unit used when units are left out is MiB.\n\n" ++ "Examples of valid input:\n" ++ "'100 GiB' = 100 gibibytes\n" ++ "'512m' = 512 megabytes\n" ++ "'123456789' = 123 terabytes and a bit less than a half\n" ++) + + ContainerType = namedtuple("ContainerType", ["name", "label"]) + +-- +2.23.0 + diff --git a/bugfix-The-underline-character-should-not-be-displayed.patch b/bugfix-The-underline-character-should-not-be-displayed.patch new file mode 100644 index 0000000..6035f9d --- /dev/null +++ b/bugfix-The-underline-character-should-not-be-displayed.patch @@ -0,0 +1,26 @@ +From 82ec245b104c4cc87f322b8824e04f22961c34d6 Mon Sep 17 00:00:00 2001 +From: Jan Stodola +Date: Mon, 31 Aug 2020 21:59:43 +0200 +Subject: [PATCH] The underline character should not be displayed + +Fix anaconda showing "1 _storage device selected" on the advanced storage spoke. +The call was accidentally? removed in 7b7616f +--- + pyanaconda/ui/gui/spokes/advanced_storage.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pyanaconda/ui/gui/spokes/advanced_storage.py b/pyanaconda/ui/gui/spokes/advanced_storage.py +index 88405894e..e3ad33147 100644 +--- a/pyanaconda/ui/gui/spokes/advanced_storage.py ++++ b/pyanaconda/ui/gui/spokes/advanced_storage.py +@@ -632,6 +632,7 @@ class FilterSpoke(NormalSpoke): + if count > 0: + really_show(summary_button) + label.set_text(summary) ++ label.set_use_underline(True) + else: + really_hide(summary_button) + +-- +2.23.0 + diff --git a/bugfix-network-add-timeout-for-synchronous-activation-of-a-.patch b/bugfix-network-add-timeout-for-synchronous-activation-of-a-.patch new file mode 100644 index 0000000..bcf8896 --- /dev/null +++ b/bugfix-network-add-timeout-for-synchronous-activation-of-a-.patch @@ -0,0 +1,59 @@ +From 7ab2db63f7d5f30035d6db2ec2a86a156c50d2f6 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 19 Aug 2020 13:50:48 +0200 +Subject: [PATCH] network: add timeout for synchronous activation of a + connection + +Related: rhbz#1869323 +--- + pyanaconda/modules/network/constants.py | 1 + + pyanaconda/modules/network/nm_client.py | 13 ++++++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/pyanaconda/modules/network/constants.py b/pyanaconda/modules/network/constants.py +index 33c99d76e..530a8e281 100644 +--- a/pyanaconda/modules/network/constants.py ++++ b/pyanaconda/modules/network/constants.py +@@ -24,6 +24,7 @@ from pyanaconda.core.constants import FIREWALL_DEFAULT, FIREWALL_DISABLED, \ + + + NM_CONNECTION_UUID_LENGTH = 36 ++CONNECTION_ACTIVATION_TIMEOUT = 45 + + + @unique +diff --git a/pyanaconda/modules/network/nm_client.py b/pyanaconda/modules/network/nm_client.py +index 5e1fb854e..2f5703e76 100644 +--- a/pyanaconda/modules/network/nm_client.py ++++ b/pyanaconda/modules/network/nm_client.py +@@ -23,9 +23,10 @@ gi.require_version("NM", "1.0") + from gi.repository import NM + + import socket +-from queue import Queue ++from queue import Queue, Empty + from pykickstart.constants import BIND_TO_MAC +-from pyanaconda.modules.network.constants import NM_CONNECTION_UUID_LENGTH ++from pyanaconda.modules.network.constants import NM_CONNECTION_UUID_LENGTH, \ ++ CONNECTION_ACTIVATION_TIMEOUT + from pyanaconda.modules.network.kickstart import default_ks_vlan_interface_name + from pyanaconda.modules.network.utils import is_s390, get_s390_settings, netmask2prefix, \ + prefix2netmask +@@ -939,7 +940,13 @@ def activate_connection_sync(nm_client, connection, device): + sync_queue + ) + +- return sync_queue.get() ++ try: ++ ret = sync_queue.get(timeout=CONNECTION_ACTIVATION_TIMEOUT) ++ except Empty: ++ log.error("Activation of a connection timed out.") ++ ret = None ++ ++ return ret + + + def get_dracut_arguments_from_connection(nm_client, connection, iface, target_ip, +-- +2.23.0 + diff --git a/bugfix-network-do-not-crash-when-updating-a-connection-with.patch b/bugfix-network-do-not-crash-when-updating-a-connection-with.patch new file mode 100644 index 0000000..5ac9b42 --- /dev/null +++ b/bugfix-network-do-not-crash-when-updating-a-connection-with.patch @@ -0,0 +1,41 @@ +From a3e46c49216f76f73097587b15ded52b253ce3d2 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 26 Aug 2020 09:52:24 +0200 +Subject: [PATCH] network: do not crash when updating a connection without + wired settings + +One of the Anaconda fallouts of NM defaulting to keyfiles. +Hit by team-pre and five other -pre kickstart tests. +--- + pyanaconda/modules/network/initialization.py | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/pyanaconda/modules/network/initialization.py b/pyanaconda/modules/network/initialization.py +index 5e33d0494..b27a46976 100644 +--- a/pyanaconda/modules/network/initialization.py ++++ b/pyanaconda/modules/network/initialization.py +@@ -411,13 +411,14 @@ class DumpMissingIfcfgFilesTask(Task): + s_con.set_property(NM.SETTING_CONNECTION_ID, iface) + s_con.set_property(NM.SETTING_CONNECTION_INTERFACE_NAME, iface) + s_wired = con.get_setting_wired() +- # By default connections are bound to interface name +- s_wired.set_property(NM.SETTING_WIRED_MAC_ADDRESS, None) +- bound_mac = bound_hwaddr_of_device(self._nm_client, iface, self._ifname_option_values) +- if bound_mac: +- s_wired.set_property(NM.SETTING_WIRED_MAC_ADDRESS, bound_mac) +- log.debug("%s: iface %s bound to mac address %s by ifname boot option", +- self.name, iface, bound_mac) ++ if s_wired: ++ # By default connections are bound to interface name ++ s_wired.set_property(NM.SETTING_WIRED_MAC_ADDRESS, None) ++ bound_mac = bound_hwaddr_of_device(self._nm_client, iface, self._ifname_option_values) ++ if bound_mac: ++ s_wired.set_property(NM.SETTING_WIRED_MAC_ADDRESS, bound_mac) ++ log.debug("%s: iface %s bound to mac address %s by ifname boot option", ++ self.name, iface, bound_mac) + + @guard_by_system_configuration(return_value=[]) + def run(self): +-- +2.23.0 + diff --git a/bugfix-network-do-not-try-to-activate-connection-that-has-n.patch b/bugfix-network-do-not-try-to-activate-connection-that-has-n.patch new file mode 100644 index 0000000..cafc43a --- /dev/null +++ b/bugfix-network-do-not-try-to-activate-connection-that-has-n.patch @@ -0,0 +1,30 @@ +From 6ffa54ed7ca56047b26f05cc6b9967820fa5dc21 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 19 Aug 2020 13:51:14 +0200 +Subject: [PATCH] network: do not try to activate connection that has not been + found + +Resolves: rhbz#1869323 +--- + pyanaconda/modules/network/nm_client.py | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/pyanaconda/modules/network/nm_client.py b/pyanaconda/modules/network/nm_client.py +index 2f5703e76..acf6f7858 100644 +--- a/pyanaconda/modules/network/nm_client.py ++++ b/pyanaconda/modules/network/nm_client.py +@@ -785,8 +785,9 @@ def ensure_active_connection_for_device(nm_client, uuid, device_name, only_repla + active_uuid = ac.get_uuid() if ac else None + if uuid != active_uuid: + ifcfg_con = nm_client.get_connection_by_uuid(uuid) +- activate_connection_sync(nm_client, ifcfg_con, None) +- activated = True ++ if ifcfg_con: ++ activate_connection_sync(nm_client, ifcfg_con, None) ++ activated = True + msg = "activated" if activated else "not activated" + log.debug("ensure active ifcfg connection for %s (%s -> %s): %s", + device_name, active_uuid, uuid, msg) +-- +2.23.0 + diff --git a/bugfix-network-fix-configuration-of-virtual-devices-by-boot.patch b/bugfix-network-fix-configuration-of-virtual-devices-by-boot.patch new file mode 100644 index 0000000..0455f8d --- /dev/null +++ b/bugfix-network-fix-configuration-of-virtual-devices-by-boot.patch @@ -0,0 +1,58 @@ +From 787daf49b358fbe2d514012a708c28575fc8122b Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 1 Jul 2020 11:25:37 +0200 +Subject: [PATCH] network: fix configuration of virtual devices by boot options + +The configuration was not passed to installed system via ifcfg files. + +Resolves: rhbz#1851218 +--- + pyanaconda/modules/network/initialization.py | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/pyanaconda/modules/network/initialization.py b/pyanaconda/modules/network/initialization.py +index de1ec851b..5e33d0494 100644 +--- a/pyanaconda/modules/network/initialization.py ++++ b/pyanaconda/modules/network/initialization.py +@@ -26,7 +26,8 @@ from pyanaconda.modules.network.nm_client import get_device_name_from_network_da + update_connection_values, commit_changes_with_autoconnection_blocked, is_ibft_connection + from pyanaconda.modules.network.ifcfg import get_ifcfg_file_of_device, find_ifcfg_uuid_of_device, \ + get_master_slaves_from_ifcfgs +-from pyanaconda.modules.network.device_configuration import supported_wired_device_types ++from pyanaconda.modules.network.device_configuration import supported_wired_device_types, \ ++ virtual_device_types + from pyanaconda.modules.network.utils import guard_by_system_configuration + + log = get_module_logger(__name__) +@@ -431,8 +432,9 @@ class DumpMissingIfcfgFilesTask(Task): + log.debug("%s: No NetworkManager available.", self.name) + return new_ifcfgs + ++ dumped_device_types = supported_wired_device_types + virtual_device_types + for device in self._nm_client.get_devices(): +- if device.get_device_type() not in supported_wired_device_types: ++ if device.get_device_type() not in dumped_device_types: + continue + + iface = device.get_iface() +@@ -446,9 +448,14 @@ class DumpMissingIfcfgFilesTask(Task): + + device_is_slave = any(con.get_setting_connection().get_master() for con in cons) + if device_is_slave: +- log.debug("%s: not creating default connection for slave device %s", +- self.name, iface) +- continue ++ # We have to dump persistent ifcfg files for slaves created in initramfs ++ if n_cons == 1 and self._is_initramfs_connection(cons[0], iface): ++ log.debug("%s: device %s has an initramfs slave connection", ++ self.name, iface) ++ else: ++ log.debug("%s: not creating default connection for slave device %s", ++ self.name, iface) ++ continue + + # Devices activated in initramfs should have ONBOOT=yes + has_initramfs_con = any(self._is_initramfs_connection(con, iface) for con in cons) +-- +2.23.0 + diff --git a/bugfix-network-fix-parsing-of-hostname-from-ip-if-mac-is-de.patch b/bugfix-network-fix-parsing-of-hostname-from-ip-if-mac-is-de.patch new file mode 100644 index 0000000..1420341 --- /dev/null +++ b/bugfix-network-fix-parsing-of-hostname-from-ip-if-mac-is-de.patch @@ -0,0 +1,95 @@ +From 0b4867eba60bbee4b8e1c1bd58966691dd1c2431 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 5 Aug 2020 16:35:34 +0200 +Subject: [PATCH] network: fix parsing of hostname from ip= if mac is defined + in dhcp + +Resolves: rhbz#1852560 +--- + pyanaconda/core/regexes.py | 3 +++ + pyanaconda/network.py | 13 ++++++++----- + tests/nosetests/pyanaconda_tests/network_test.py | 11 ++++++++--- + 3 files changed, 19 insertions(+), 8 deletions(-) + +diff --git a/pyanaconda/core/regexes.py b/pyanaconda/core/regexes.py +index 63ab668c9..ee5cc3765 100644 +--- a/pyanaconda/core/regexes.py ++++ b/pyanaconda/core/regexes.py +@@ -191,3 +191,6 @@ ZFCP_WWPN_NUMBER = re.compile(r'^(?:0x|)[0-9A-Fa-f]{16}$') + + # IPv6 address in dracut IP option (including the square brackets) + IPV6_ADDRESS_IN_DRACUT_IP_OPTION = re.compile(r'\[[^\]]+\]') ++ ++# Octet of MAC address ++MAC_OCTET = re.compile(r'[a-fA-F0-9][a-fA-F0-9]') +diff --git a/pyanaconda/network.py b/pyanaconda/network.py +index c66f35d44..7ba821fe4 100644 +--- a/pyanaconda/network.py ++++ b/pyanaconda/network.py +@@ -32,7 +32,7 @@ from pyanaconda.core import util, constants + from pyanaconda.core.i18n import _ + from pyanaconda.core.kernel import kernel_arguments + from pyanaconda.core.regexes import HOSTNAME_PATTERN_WITHOUT_ANCHORS, \ +- IPV6_ADDRESS_IN_DRACUT_IP_OPTION ++ IPV6_ADDRESS_IN_DRACUT_IP_OPTION, MAC_OCTET + from pyanaconda.core.configuration.anaconda import conf + from pyanaconda.core.constants import TIME_SOURCE_SERVER + from pyanaconda.modules.common.constants.services import NETWORK, TIMEZONE, STORAGE +@@ -209,7 +209,7 @@ def hostname_from_cmdline(kernel_args): + """ + # legacy hostname= option + hostname = kernel_args.get('hostname', "") +- # ip= option ++ # ip= option (man dracut.cmdline) + ipopts = kernel_args.get('ip') + # Example (2 options): + # ens3:dhcp 10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none +@@ -219,10 +219,13 @@ def hostname_from_cmdline(kernel_args): + # Replace ipv6 addresses with empty string, example of ipv6 config: + # [fd00:10:100::84:5]::[fd00:10:100::86:49]:80:myhostname:ens9:none + ipopt = IPV6_ADDRESS_IN_DRACUT_IP_OPTION.sub('', ipopt) +- try: ++ elements = ipopt.split(':') ++ # Hostname can be defined only in option having more than 6 elements. ++ # But filter out auto ip= with mac address set by MAC_OCTET matching, eg: ++ # ip=:dhcp::52:54:00:12:34:56 ++ # where the 4th element is not hostname. ++ if len(elements) > 6 and not re.match(MAC_OCTET, elements[6]): + hostname = ipopt.split(':')[4] +- except IndexError: +- pass + return hostname + + +diff --git a/tests/nosetests/pyanaconda_tests/network_test.py b/tests/nosetests/pyanaconda_tests/network_test.py +index e7ca630a7..161e883ff 100644 +--- a/tests/nosetests/pyanaconda_tests/network_test.py ++++ b/tests/nosetests/pyanaconda_tests/network_test.py +@@ -233,9 +233,11 @@ class NetworkTests(unittest.TestCase): + cmdline = {"ip": "10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none", + "hostname": "hostname_bootopt"} + self.assertEqual(network.hostname_from_cmdline(cmdline), "myhostname") +- cmdline = {"ip": "ens3:dhcp "} ++ cmdline = {"ip": "ens3:dhcp"} + self.assertEqual(network.hostname_from_cmdline(cmdline), "") +- cmdline = {"ip": "ens3:dhcp ", ++ cmdline = {"ip": "ens3:dhcp:1500"} ++ self.assertEqual(network.hostname_from_cmdline(cmdline), "") ++ cmdline = {"ip": "ens3:dhcp", + "hostname": "hostname_bootopt"} + self.assertEqual(network.hostname_from_cmdline(cmdline), "hostname_bootopt") + # two ip configurations +@@ -248,6 +250,9 @@ class NetworkTests(unittest.TestCase): + self.assertEqual(network.hostname_from_cmdline(cmdline), "myhostname") + cmdline = {"ip": "[fd00:10:100::84:5]::[fd00:10:100::86:49]:80::ens50:none"} + self.assertEqual(network.hostname_from_cmdline(cmdline), "") +- cmdline = {"ip": "[fd00:10:100::84:5]::[fd00:10:100::86:49]:80::ens50:none" ++ cmdline = {"ip": "[fd00:10:100::84:5]::[fd00:10:100::86:49]:80::ens50:none " + "ens3:dhcp 10.34.102.244::10.34.102.54:255.255.255.0:myhostname:ens9:none"} + self.assertEqual(network.hostname_from_cmdline(cmdline), "myhostname") ++ # automatic ip= whith MAC address set ++ cmdline = {"ip": "ens3:dhcp::52:54:00:12:34:56"} ++ self.assertEqual(network.hostname_from_cmdline(cmdline), "") +-- +2.23.0 + diff --git a/bugfix-network-get-hwadddr-when-binding-to-mac-more-robustl.patch b/bugfix-network-get-hwadddr-when-binding-to-mac-more-robustl.patch new file mode 100644 index 0000000..d202dd9 --- /dev/null +++ b/bugfix-network-get-hwadddr-when-binding-to-mac-more-robustl.patch @@ -0,0 +1,29 @@ +From 72c5df1cb3ee8636fc6901aaf6192f7e147ed399 Mon Sep 17 00:00:00 2001 +From: Radek Vykydal +Date: Wed, 9 Sep 2020 15:36:35 +0200 +Subject: [PATCH] network: get hwadddr when binding to mac more robustly + +--- + pyanaconda/modules/network/nm_client.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/pyanaconda/modules/network/nm_client.py b/pyanaconda/modules/network/nm_client.py +index 4473c0110..04ae78d90 100644 +--- a/pyanaconda/modules/network/nm_client.py ++++ b/pyanaconda/modules/network/nm_client.py +@@ -695,7 +695,11 @@ def bind_settings_to_mac(nm_client, s_connection, s_wired, device_name=None, bin + return False + device = nm_client.get_device_by_iface(iface) + if device: +- hwaddr = device.get_permanent_hw_address() or device.get_hw_address() ++ try: ++ perm_hwaddr = device.get_permanent_hw_address() ++ except AttributeError: ++ perm_hwaddr = None ++ hwaddr = perm_hwaddr or device.get_hw_address() + s_wired.props.mac_address = hwaddr + log.debug("Bind to mac: bound to %s", hwaddr) + modified = True +-- +2.23.0 +