sync 49 fixbug from github

(cherry picked from commit 0cd8608199f6b9726c451e0e9fe3be4a1dbe7cca)
This commit is contained in:
xuxiaolong 2021-04-02 10:25:06 +08:00 committed by openeuler-sync-bot
parent 9f8c2c1b26
commit 27667a0985
50 changed files with 2687 additions and 2 deletions

View File

@ -1,7 +1,7 @@
%define _empty_manifest_terminate_build 0 %define _empty_manifest_terminate_build 0
Name: anaconda Name: anaconda
Version: 33.19 Version: 33.19
Release: 18 Release: 19
Summary: Graphical system installer Summary: Graphical system installer
License: GPLv2+ and MIT License: GPLv2+ and MIT
URL: http://fedoraproject.org/wiki/Anaconda 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 Patch6020: bugfix-Schedule-timed-actions-with-the-right-selector-18516.patch
Patch6021: bugfix-Reset-the-state-of-the-custom-partitioning-spoke.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 dbusver 1.2.3
%define dnfver 3.6.0 %define dnfver 3.6.0
@ -271,7 +320,13 @@ update-desktop-database &> /dev/null || :
%{_datadir}/gtk-doc %{_datadir}/gtk-doc
%changelog %changelog
* Thu Mar 18 2021 liuxin <liuxin264@huawei.com> - 33.19-18 * Mon Mar 29 2021 xuxiaolong <xuxiaolon23@huawei.com> - 33.19-19
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:sync 50 bugfix commit from github
* Sat Mar 27 2021 zhangrui <zhangrui182@huawei.com> - 33.19-18
- Type:bugfix - Type:bugfix
- ID:NA - ID:NA
- SUG:NA - SUG:NA

View File

@ -0,0 +1,26 @@
From f7398e8ceaa634bff73b1b1cd04ac0aa572d5249 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin@piware.de>
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

View File

@ -0,0 +1,63 @@
From 8437fe761224a97967a076e05143304a225c3e05 Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
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 <omosnace@redhat.com>
---
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

View File

@ -0,0 +1,149 @@
From cf8d3811b89b90211cac0cbd1e5ceb40ea7b641b Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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 <vponcova@redhat.com>
#
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

View File

@ -0,0 +1,32 @@
From d1d43dc872aa05b7273883fe42debd55e11e6df6 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,31 @@
From 9ef262fbd07508a5dd9becb30a0136fded45e792 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,43 @@
From 6326cb3e866027a5862c0fbd0a1f0a2a86b6836b Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,27 @@
From b7258aafb1e55b055bc6bcd18b10c83f5a5feec6 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,53 @@
From 6c8bfa8649e71d4f20eea69b57dc47b514dd498c Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.1 -->
+<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="AnacondaWidgets" version="1.0"/>
@@ -60,10 +60,12 @@
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="valign">end</property>
<property name="margin_bottom">6</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Base Environment</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
<attributes>
<attribute name="font-desc" value="Cantarell 12"/>
<attribute name="weight" value="normal"/>
@@ -78,10 +80,12 @@
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="valign">end</property>
<property name="margin_bottom">6</property>
<property name="hexpand">True</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes">Additional software for Selected Environment</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
<attributes>
<attribute name="font-desc" value="Cantarell 12"/>
<attribute name="weight" value="normal"/>
--
2.23.0

View File

@ -0,0 +1,30 @@
From e05cc18294e67099bf87076e4f23fe5f031fecb5 Mon Sep 17 00:00:00 2001
From: Sundeep Anand <suanand@redhat.com>
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

View File

@ -0,0 +1,66 @@
From 6515d0779a41c1ea902ada86e4e911821cded92e Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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

View File

@ -0,0 +1,34 @@
From 76d20274ea13439bdfa277aa18a99a1ee9a61d1c Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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

View File

@ -0,0 +1,50 @@
From 5cb9170cafc3f81193fd872a21933a0fa2bd5f2c Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,107 @@
From c9857a91ece047c0fc2df3554e625d15b4700818 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,32 @@
From 681285fff08169abd175beafae9e4144735e8cd9 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,98 @@
From e0351e363baedcf788d7ff39fea282885229b4dc Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,37 @@
From 0c3cb13730730da2edcc6567bec8256eee9b1770 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,30 @@
From e0168180824ab04d8ee6d798efb039bf3d5555dc Mon Sep 17 00:00:00 2001
From: Jan Stodola <honza.stodola@gmail.com>
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

View File

@ -0,0 +1,40 @@
From c3dbffacabc60f0149b142a1f6b3f29739e9288b Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,56 @@
From 373da9db5d1c7d138f87abfb69165bd9de413a41 Mon Sep 17 00:00:00 2001
From: Vojtech Trefny <vtrefny@redhat.com>
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

View File

@ -0,0 +1,35 @@
From bc8779761fe60313a1c754a6b24c2861e86a5e62 Mon Sep 17 00:00:00 2001
From: Jan Stodola <honza.stodola@gmail.com>
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

View File

@ -0,0 +1,34 @@
From a57be7d30897ecf301de673e41d1af975b4f593b Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,79 @@
From 6317147760315ebc269470b3fdb3f66eaeefe9b2 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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 <awilliam@redhat.com>
---
.../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

View File

@ -0,0 +1,40 @@
From dac59c13424e403f73e3cad46e7412482b17f92a Mon Sep 17 00:00:00 2001
From: Kai Kang <kai.kang@windriver.com>
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 <kai.kang@windriver.com>
---
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

View File

@ -0,0 +1,32 @@
From 1e873f5084f84e16c5d26b65f29ba401ee7f7f94 Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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

View File

@ -0,0 +1,48 @@
From 1f384563fd5aa4070cd0b75a6bcaee1648884499 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,41 @@
From 9858b6e456630d5bdad5b6084c87e60749964f26 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,40 @@
From 2585d3380ebbd516757a2420486e68e2809961db Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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 @@
<property name="can_focus">False</property>
<property name="halign">start</property>
<items>
- <item id="url" translatable="yes">repository URL</item>
- <item id="mirrorlist" translatable="yes">mirrorlist</item>
- <item id="metalink" translatable="yes">metalink</item>
+ <item id="BASEURL" translatable="yes">repository URL</item>
+ <item id="MIRRORLIST" translatable="yes">mirrorlist</item>
+ <item id="METALINK" translatable="yes">metalink</item>
</items>
<signal name="changed" handler="on_repo_url_type_changed" swapped="no"/>
</object>
--
2.23.0

View File

@ -0,0 +1,41 @@
From 98e011f1f8af900ed6f65432ad7466973d44735a Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,34 @@
From b7ee1291870a0d6689ff6d81e1c50999f38cd6b7 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,36 @@
From 0f9873a2ffbf3a180a236c4f036e54520773f2ca Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,36 @@
From 8ab916a0fe7b46b20c3a51828600b4f7f207717a Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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

View File

@ -0,0 +1,101 @@
From 7982cf9937165ad34fe3c4bdf2cf2155a4f5e7f8 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,101 @@
From b224f888c225d9735abaa82d0156ae5a4c38d4f5 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,40 @@
From 4766a00a9d67bfe93573e1160ac05fe9c8883aa9 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
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 <javierm@redhat.com>
---
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

View File

@ -0,0 +1,32 @@
From ac6010448ba29f8c5b979d11cabeb09a91cf260c Mon Sep 17 00:00:00 2001
From: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
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

View File

@ -0,0 +1,29 @@
From 2acb1357ee8b931662a1353a8956d5a0be176dec Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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

View File

@ -0,0 +1,120 @@
From 6f27de8a38cc7900bb35a4fac4ec258f50207468 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,128 @@
From 6f52b733470d5565bc8e9a2a2415997d0ecbba54 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
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

View File

@ -0,0 +1,31 @@
From d76c6060ea59215dbb90299b28fc8d59abf8e0fa Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,28 @@
From 1f05aab7135ee3c5843c24a2a89bb707dcbe0dc5 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,86 @@
From 2ca64adb8effcdfa8a883ee9f8fc2015cbece685 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
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

View File

@ -0,0 +1,96 @@
From 4bf4ba6d9a11cfd652ce48cdaea86bd617b6332a Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
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

View File

@ -0,0 +1,26 @@
From 82ec245b104c4cc87f322b8824e04f22961c34d6 Mon Sep 17 00:00:00 2001
From: Jan Stodola <honza.stodola@gmail.com>
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

View File

@ -0,0 +1,59 @@
From 7ab2db63f7d5f30035d6db2ec2a86a156c50d2f6 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,41 @@
From a3e46c49216f76f73097587b15ded52b253ce3d2 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,30 @@
From 6ffa54ed7ca56047b26f05cc6b9967820fa5dc21 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,58 @@
From 787daf49b358fbe2d514012a708c28575fc8122b Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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

View File

@ -0,0 +1,95 @@
From 0b4867eba60bbee4b8e1c1bd58966691dd1c2431 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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=<interface>: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

View File

@ -0,0 +1,29 @@
From 72c5df1cb3ee8636fc6901aaf6192f7e147ed399 Mon Sep 17 00:00:00 2001
From: Radek Vykydal <rvykydal@redhat.com>
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