update anaconda to 36.16.5

(cherry picked from commit 2afd0aab87a649bacf1e37e03a2533b4a92b4d7e)
This commit is contained in:
sun_hai_10 2022-11-08 20:26:48 +08:00 committed by openeuler-sync-bot
parent 41c67ec90d
commit 8278796aac
109 changed files with 338 additions and 9455 deletions

View File

@ -1,271 +0,0 @@
From 32a54b5068c082a09683bfa81ac43b1b7b82fb8b Mon Sep 17 00:00:00 2001
From: Wenlong Zhang <zhangwenlong@loongson.cn>
Date: Tue, 18 Oct 2022 18:51:31 +0000
Subject: [PATCH 6/7] install: add loongarch platform support
---
pyanaconda/modules/storage/bootloader/base.py | 9 +-
pyanaconda/modules/storage/bootloader/efi.py | 28 +++++-
.../modules/storage/bootloader/factory.py | 7 ++
.../modules/storage/bootloader/grub2.py | 1 +
pyanaconda/modules/storage/bootloader/pmon.py | 87 +++++++++++++++++++
.../modules/storage/devicetree/fsset.py | 6 +-
pyanaconda/modules/storage/platform.py | 9 ++
7 files changed, 142 insertions(+), 5 deletions(-)
create mode 100644 pyanaconda/modules/storage/bootloader/pmon.py
diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py
index 16a4df3..34bfae2 100644
--- a/pyanaconda/modules/storage/bootloader/base.py
+++ b/pyanaconda/modules/storage/bootloader/base.py
@@ -731,11 +731,14 @@ class BootLoader(object):
swap_devices = storage.fsset.swap_devices
dracut_devices.extend(swap_devices)
- # Add resume= option to enable hibernation on x86.
+ # Add resume= option to enable hibernation on x86 and loongarch.
# Choose the largest swap device for that.
- if blivet.arch.is_x86() and swap_devices:
+ if (blivet.arch.is_x86() or blivet.arch.is_loongarch()) and swap_devices:
resume_device = max(swap_devices, key=lambda x: x.size)
- self.boot_args.add("resume=%s" % resume_device.fstab_spec)
+ if not blivet.arch.is_efi() and blivet.arch.is_loongarch():
+ self.boot_args.add("resume=%s" % resume_device.path)
+ else:
+ self.boot_args.add("resume=%s" % resume_device.fstab_spec)
# Does /usr have its own device? If so, we need to tell dracut
usr_device = storage.mountpoints.get("/usr")
diff --git a/pyanaconda/modules/storage/bootloader/efi.py b/pyanaconda/modules/storage/bootloader/efi.py
index d8b7f10..1aed536 100644
--- a/pyanaconda/modules/storage/bootloader/efi.py
+++ b/pyanaconda/modules/storage/bootloader/efi.py
@@ -28,7 +28,7 @@ from pyanaconda.product import productName
from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
-__all__ = ["EFIBase", "EFIGRUB", "Aarch64EFIGRUB", "ArmEFIGRUB", "MacEFIGRUB"]
+__all__ = ["EFIBase", "EFIGRUB", "Aarch64EFIGRUB", "ArmEFIGRUB", "MacEFIGRUB", "LOONGARCHEFIGRUB"]
class EFIBase(object):
@@ -167,7 +167,33 @@ class Aarch64EFIGRUB(EFIGRUB):
def __init__(self):
super().__init__()
self._packages64 = ["grub2-efi-aa64", "shim-aa64"]
+class LOONGARCHEFIGRUB(EFIGRUB):
+ _efi_binary = "grubloongarch64.efi"
+ stage2_is_valid_stage1 = False
+ stage2_bootable = False
+
+ def __init__(self):
+ super().__init__()
+ self._packages64 = ["grub2-efi-loongarch64"]
+ def remove_efi_boot_target(self):
+ return
+
+ def _add_single_efi_boot_target(self, partition):
+ boot_disk = partition.disk
+ boot_part_num = str(partition.parted_partition.number)
+
+ rc = util.execInSysroot("cp", ["-a", "/boot/efi/EFI/openEuler/" + self._efi_binary, "/boot/efi/EFI/BOOT/" + "BOOTLOONGARCH64.EFI"])
+ if rc:
+ raise BootLoaderError("Failed to set new efi boot target. This is most "
+ "likely a kernel or firmware bug.")
+
+ def add_efi_boot_target(self):
+ if self.stage1_device.type == "partition": # pylint: disable=no-member
+ self._add_single_efi_boot_target(self.stage1_device) # pylint: disable=no-member
+ elif self.stage1_device.type == "mdarray": # pylint: disable=no-member
+ for parent in self.stage1_device.parents: # pylint: disable=no-member
+ self._add_single_efi_boot_target(parent)
class ArmEFIGRUB(EFIGRUB):
_serial_consoles = ["ttyAMA", "ttyS"]
diff --git a/pyanaconda/modules/storage/bootloader/factory.py b/pyanaconda/modules/storage/bootloader/factory.py
index 8aa3afb..b5b8b59 100644
--- a/pyanaconda/modules/storage/bootloader/factory.py
+++ b/pyanaconda/modules/storage/bootloader/factory.py
@@ -137,6 +137,13 @@ class BootLoaderFactory(object):
if platform_class is platform.Aarch64EFI:
from pyanaconda.modules.storage.bootloader.efi import Aarch64EFIGRUB
return Aarch64EFIGRUB
+ if platform_class is platform.LOONGARCHEFI:
+ from pyanaconda.modules.storage.bootloader.efi import LOONGARCHEFIGRUB
+ return LOONGARCHEFIGRUB
+
+ if platform_class is platform.LOONGARCHLEGACY:
+ from pyanaconda.modules.storage.bootloader.pmon import LOONGARCHPMON
+ return LOONGARCHPMON
if platform_class is platform.ARM:
from pyanaconda.modules.storage.bootloader.extlinux import EXTLINUX
diff --git a/pyanaconda/modules/storage/bootloader/grub2.py b/pyanaconda/modules/storage/bootloader/grub2.py
index 51f7c74..57cfd95 100644
--- a/pyanaconda/modules/storage/bootloader/grub2.py
+++ b/pyanaconda/modules/storage/bootloader/grub2.py
@@ -257,6 +257,7 @@ class GRUB2(BootLoader):
defaults.write("GRUB_DISTRIBUTOR=\"$(sed 's, release .*$,,g' /etc/system-release)\"\n")
defaults.write("GRUB_DEFAULT=saved\n")
defaults.write("GRUB_DISABLE_SUBMENU=true\n")
+ defaults.write("GRUB_CMDLINE_LINUX_DEFAULT=' rhgb quiet '\n")
if self.console and self.has_serial_console:
defaults.write("GRUB_TERMINAL=\"serial console\"\n")
defaults.write("GRUB_SERIAL_COMMAND=\"%s\"\n" % self.serial_command)
diff --git a/pyanaconda/modules/storage/bootloader/pmon.py b/pyanaconda/modules/storage/bootloader/pmon.py
new file mode 100644
index 0000000..7e02f61
--- /dev/null
+++ b/pyanaconda/modules/storage/bootloader/pmon.py
@@ -0,0 +1,87 @@
+#
+# Writer: Sun Haiyong (youbest@sina.com)
+#
+import os
+
+from pyanaconda.modules.storage.bootloader.base import BootLoader, Arguments, BootLoaderError
+from pyanaconda.core import util
+from pyanaconda.core.configuration.anaconda import conf
+from pyanaconda.product import productName
+
+from pyanaconda.anaconda_loggers import get_module_logger
+log = get_module_logger(__name__)
+
+__all__ = ["PMON", "LOONGARCHPMON"]
+
+
+class PMON(BootLoader):
+ name = "PMON"
+ _config_file = "boot.cfg"
+ _config_dir = "/boot"
+
+ stage2_format_types = ["ext3", "ext2"]
+ stage2_device_types = ["partition"]
+# stage2_bootable = True
+
+ @property
+ def config_file(self):
+ return "%s/%s" % (self._config_dir, self._config_file)
+
+ @property
+ def boot_prefix(self):
+ """ Prefix, if any, to paths in /boot. """
+ if self.stage2_device.format.mountpoint == "/":
+ prefix = "/boot"
+ else:
+ prefix = ""
+
+ return prefix
+
+ def write_config_console(self, config):
+ if not self.console:
+ return
+
+ console_arg = "console=%s" % self.console
+ if self.console_options:
+ console_arg += ",%s" % self.console_options
+ self.boot_args.add(console_arg)
+
+ def write_config_images(self, config):
+ self.write_config_console(config)
+ for image in self.images:
+ args = Arguments()
+ args.update(["root=%s" % image.device.path, "ro"])
+ args.update(self.boot_args)
+ log.info("bootloader.py: used boot args: %s ", args)
+
+ # extlinux labels cannot have spaces
+ label = "%s(%s)" % (self.image_label(image), image.version)
+ label = label.replace(" ", "")
+ stanza = ("title %(label)s\n"
+ "\tkernel /dev/fs/ext2@wd0%(boot_prefix)s/%(kernel)s\n"
+ "\tinitrd /dev/fs/ext2@wd0%(boot_prefix)s/%(initrd)s\n"
+ "\targs %(args)s\n\n"
+ % {"label": label,
+ "kernel": image.kernel,
+ "initrd": image.initrd,
+ "args": args,
+ "boot_prefix": self.boot_prefix})
+ config.write(stanza)
+
+ def write_config_header(self, config):
+ header = ("timeout %(timeout)d\n"
+ "showmenu 1\n"
+ % {"timeout": self.timeout})
+ config.write(header)
+ if self.default is not None:
+ config.write("default 0\n\n")
+
+ def install(self, args=None):
+ """installation should be a no-op, just writing the config is sufficient for the
+ firmware's bootloader (petitboot)
+ """
+ pass
+
+
+class LOONGARCHPMON(PMON):
+ """ LOONGARCHPMON """
diff --git a/pyanaconda/modules/storage/devicetree/fsset.py b/pyanaconda/modules/storage/devicetree/fsset.py
index 00aef10..ab7cd6f 100644
--- a/pyanaconda/modules/storage/devicetree/fsset.py
+++ b/pyanaconda/modules/storage/devicetree/fsset.py
@@ -24,6 +24,7 @@ import gi
gi.require_version("BlockDev", "2.0")
from gi.repository import BlockDev as blockdev
+from blivet import arch
from blivet.devices import NoDevice, DirectoryDevice, NFSDevice, FileDevice, MDRaidArrayDevice, \
NetworkStorageDevice, OpticalDevice
from blivet.errors import UnrecognizedFSTabEntryError, FSTabTypeMismatchError
@@ -764,7 +765,10 @@ class FSSet(object):
break
if device.encrypted:
options += ",x-systemd.device-timeout=0"
- devspec = device.fstab_spec
+ if not arch.is_efi() and arch.is_loongarch():
+ devspec = device.path
+ else:
+ devspec = device.fstab_spec
dump = device.format.dump
if device.format.check and mountpoint == "/":
passno = 1
diff --git a/pyanaconda/modules/storage/platform.py b/pyanaconda/modules/storage/platform.py
index 1023c93..9b730c1 100644
--- a/pyanaconda/modules/storage/platform.py
+++ b/pyanaconda/modules/storage/platform.py
@@ -181,10 +181,15 @@ class MacEFI(EFI):
class Aarch64EFI(EFI):
_non_linux_format_types = ["vfat", "ntfs"]
+class LOONGARCHEFI(EFI):
+ _non_linux_format_types = ["vfat", "ntfs"]
class ArmEFI(EFI):
_non_linux_format_types = ["vfat", "ntfs"]
+class LOONGARCHLEGACY(Platform):
+ _boot_stage1_device_types = ["partition"]
+ _boot_descriptions = {"partition": Platform._boot_partition_description}
class PPC(Platform):
_ppc_machine = arch.get_ppc_machine()
@@ -288,12 +293,16 @@ def get_platform():
return Aarch64EFI()
elif arch.is_arm():
return ArmEFI()
+ elif arch.is_loongarch():
+ return LOONGARCHEFI()
else:
return EFI()
elif arch.is_x86():
return X86()
elif arch.is_arm():
return ARM()
+ elif arch.is_loongarch():
+ return LOONGARCHLEGACY()
else:
raise SystemError("Could not determine system architecture.")
--
2.27.0

View File

@ -1,27 +0,0 @@
From f4a9c3a8588ec5a6563d76a0a4d319e078912f01 Mon Sep 17 00:00:00 2001
From: sherlock2010 <15151851377@163.com>
Date: Thu, 10 Dec 2020 14:26:12 +0800
Subject: [PATCH] Change length limit of hostname from 255 to 64
---
pyanaconda/network.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py
index 6aab84a..00ccd0a 100644
--- a/pyanaconda/network.py
+++ b/pyanaconda/network.py
@@ -109,8 +109,8 @@ def is_valid_hostname(hostname, local=False):
if not hostname:
return (False, _("Host name cannot be None or an empty string."))
- if len(hostname) > 255:
- return (False, _("Host name must be 255 or fewer characters in length."))
+ if len(hostname) > 64:
+ return (False, _("Host name must be 64 or fewer characters in length."))
if local and hostname[-1] == ".":
return (False, _("Local host name must not end with period '.'."))
--
1.8.3.1

View File

@ -1,24 +0,0 @@
From 407e03ec54d6abbce265d7127bab863602e38720 Mon Sep 17 00:00:00 2001
From: wangce <wangce@uniontech.com>
Date: Tue, 10 Aug 2021 09:36:35 +0600
Subject: [PATCH 2/2] Change sidebar background size
---
data/anaconda-gtk.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/data/anaconda-gtk.css b/data/anaconda-gtk.css
index 85119ea..2f6963d 100644
--- a/data/anaconda-gtk.css
+++ b/data/anaconda-gtk.css
@@ -107,6 +107,7 @@ infobar.error {
background-image: url('/usr/share/anaconda/pixmaps/sidebar-bg.png');
background-color: @product_bg_color;
background-repeat: no-repeat;
+ background-size: 100% 100%;
}
/* Add a logo to the sidebar */
--
2.23.0

View File

@ -1,13 +0,0 @@
diff -uNrp a/data/anaconda-gtk.css b/data/anaconda-gtk.css
--- a/data/anaconda-gtk.css 2019-08-21 18:50:27.188000000 +0800
+++ b/data/anaconda-gtk.css 2019-08-21 18:52:23.172000000 +0800
@@ -112,7 +112,8 @@ levelbar.discrete trough block.filled.hi
AnacondaSpokeWindow #nav-box {
background-color: @product_bg_color;
background-image: url('/usr/share/anaconda/pixmaps/topbar-bg.png');
- background-repeat: repeat;
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
color: white;
}

View File

@ -1,29 +0,0 @@
From 3216e5fc1c39354e66c977f76465303ea2a11859 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Thu, 18 Jun 2020 16:45:27 +0800
Subject: [PATCH] Fix hiding of network device activation switch
---
pyanaconda/ui/gui/spokes/network.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py
index d6c1e4b..1318e17 100644
--- a/pyanaconda/ui/gui/spokes/network.py
+++ b/pyanaconda/ui/gui/spokes/network.py
@@ -1019,8 +1019,10 @@ class NetworkControlBox(GObject.GObject):
switch = self.builder.get_object("device_%s_off_switch" % dev_type_str)
if dev_type_str == "wired":
- switch.set_visible(state not in (NM.DeviceState.UNAVAILABLE,
- NM.DeviceState.UNMANAGED))
+ visible = state not in (NM.DeviceState.UNAVAILABLE, NM.DeviceState.UNMANAGED)
+ switch.set_visible(visible)
+ if not visible:
+ switch.set_no_show_all(True)
self._updating_device = True
switch.set_active(state not in (NM.DeviceState.UNMANAGED,
NM.DeviceState.UNAVAILABLE,
--
2.23.0

View File

@ -1,28 +1,41 @@
From 8f6a97734a9ecb63320d73ec42efd6f4c03eac5b Mon Sep 17 00:00:00 2001 From 65258a808a703de25f790b2cb5aff8e734228ad1 Mon Sep 17 00:00:00 2001
From: Qiumiao Zhang <zhangqiumiao1@huawei.com> From: Qiumiao Zhang <zhangqiumiao1@huawei.com>
Date: Thu, 7 Apr 2022 03:41:52 -0400 Date: Mon, 7 Nov 2022 11:33:53 +0800
Subject: [PATCH] Support configuration of additional boot arguments Subject: [PATCH] Support configuration of additional boot arguments
--- ---
data/anaconda.conf | 3 +++ data/anaconda.conf | 2 ++
pyanaconda/argument_parsing.py | 2 +-
pyanaconda/core/configuration/bootloader.py | 8 ++++++++ pyanaconda/core/configuration/bootloader.py | 8 ++++++++
pyanaconda/modules/storage/bootloader/base.py | 5 +++++ pyanaconda/modules/storage/bootloader/base.py | 5 +++++
3 files changed, 16 insertions(+) 4 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/data/anaconda.conf b/data/anaconda.conf diff --git a/data/anaconda.conf b/data/anaconda.conf
index c622700..3e63c50 100644 index 703114a..b80440e 100644
--- a/data/anaconda.conf --- a/data/anaconda.conf
+++ b/data/anaconda.conf +++ b/data/anaconda.conf
@@ -134,6 +134,9 @@ preserved_arguments = @@ -159,6 +159,8 @@ preserved_arguments =
biosdevname ipv6.disable net.ifnames net.ifnames.prefix biosdevname ipv6.disable net.ifnames net.ifnames.prefix
nosmt nosmt
+# Arguments added by default. +# Arguments added by default.
+additional_arguments = +additional_arguments =
+
[Storage] [Storage]
# Enable dmraid usage during the installation. # Enable dmraid usage during the installation.
diff --git a/pyanaconda/argument_parsing.py b/pyanaconda/argument_parsing.py
index 75f28f4..dd5ecdf 100644
--- a/pyanaconda/argument_parsing.py
+++ b/pyanaconda/argument_parsing.py
@@ -589,7 +589,7 @@ def getArgumentParser(version_string, boot_cmdline=None):
# some defaults change based on cmdline flags
if boot_cmdline is not None:
- if "console" in boot_cmdline:
+ if "console" in boot_cmdline and "inst.text" in boot_cmdline:
ap.set_defaults(display_mode=DisplayModes.TUI)
return ap
diff --git a/pyanaconda/core/configuration/bootloader.py b/pyanaconda/core/configuration/bootloader.py diff --git a/pyanaconda/core/configuration/bootloader.py b/pyanaconda/core/configuration/bootloader.py
index 6746e45..7b782d3 100644 index 6746e45..7b782d3 100644
--- a/pyanaconda/core/configuration/bootloader.py --- a/pyanaconda/core/configuration/bootloader.py
@ -40,18 +53,18 @@ index 6746e45..7b782d3 100644
+ """ + """
+ return self._get_option("additional_arguments", str).split() + return self._get_option("additional_arguments", str).split()
diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py diff --git a/pyanaconda/modules/storage/bootloader/base.py b/pyanaconda/modules/storage/bootloader/base.py
index a45a530..db98693 100644 index be039c4..533d528 100644
--- a/pyanaconda/modules/storage/bootloader/base.py --- a/pyanaconda/modules/storage/bootloader/base.py
+++ b/pyanaconda/modules/storage/bootloader/base.py +++ b/pyanaconda/modules/storage/bootloader/base.py
@@ -707,6 +707,7 @@ class BootLoader(object): @@ -734,6 +734,7 @@ class BootLoader(object):
self._set_extra_boot_args() self._set_extra_boot_args(bootloader_proxy)
self._set_storage_boot_args(storage) self._set_storage_boot_args(storage)
self._preserve_some_boot_args() self._preserve_some_boot_args()
+ self._add_additional_boot_args() + self._add_additional_boot_args()
self._set_graphical_boot_args() self._set_graphical_boot_args()
self._set_security_boot_args() self._set_security_boot_args()
@@ -843,6 +844,10 @@ class BootLoader(object): @@ -908,6 +909,10 @@ class BootLoader(object):
self.boot_args.add(new_arg) self.boot_args.add(new_arg)

View File

@ -1,29 +1,45 @@
From e8ce5155f21af58e119c61e10895fcb5d8c21995 Mon Sep 17 00:00:00 2001 From 3562cad5ea86afc5d2ce0ead649e64cf13e39128 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com> From: sun_hai_10 <sunhai10@huawei.com>
Date: Thu, 18 Jun 2020 17:00:13 +0800 Date: Mon, 7 Nov 2022 14:48:28 +0800
Subject: [PATCH] add passwd policy Subject: [PATCH] add passwd policy
--- ---
data/interactive-defaults.ks | 6 +++--- data/anaconda.conf | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-) pyanaconda/input_checking.py | 4 ++++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/data/interactive-defaults.ks b/data/interactive-defaults.ks diff --git a/data/anaconda.conf b/data/anaconda.conf
index a906c8c..0177cf9 100644 index 703114a..07e500f 100644
--- a/data/interactive-defaults.ks --- a/data/anaconda.conf
+++ b/data/interactive-defaults.ks +++ b/data/anaconda.conf
@@ -4,9 +4,9 @@ firstboot --enable @@ -308,9 +308,9 @@ can_change_users = False
# strict Require the minimum quality.
#
password_policies =
- root (quality 1, length 6)
- user (quality 1, length 6, empty)
- luks (quality 1, length 6)
+ root (quality 1, length 8, strict)
+ user (quality 1, length 8, empty, strict)
+ luks (quality 1, length 8, strict)
%anaconda
# Default password policies [License]
-pwpolicy root --notstrict --minlen=6 --minquality=1 --nochanges --notempty diff --git a/pyanaconda/input_checking.py b/pyanaconda/input_checking.py
-pwpolicy user --notstrict --minlen=6 --minquality=1 --nochanges --emptyok index 4482b26..4bed6c1 100644
-pwpolicy luks --notstrict --minlen=6 --minquality=1 --nochanges --notempty --- a/pyanaconda/input_checking.py
+pwpolicy root --notstrict --minlen=8 --minquality=1 --nochanges --notempty +++ b/pyanaconda/input_checking.py
+pwpolicy user --notstrict --minlen=8 --minquality=1 --nochanges --emptyok @@ -421,6 +421,10 @@ class PasswordValidityCheck(InputCheck):
+pwpolicy luks --notstrict --minlen=8 --minquality=1 --nochanges --notempty pw_score = 4
# NOTE: This applies only to *fully* interactive installations, partial kickstart status_text = _(constants.SecretStatus.STRONG.value)
# installations use defaults specified in pyanaconda/pwpolicy.py.
# Automated kickstart installs simply ignore the password policy as the policy + #disable set password without confirnation
+ if not error_message and not check_request.password_confirmation:
+ error_message = _(constants.SECRET_CONFIRM_ERROR_GUI[check_request.secret_type])
+
# the policy influences the overall success of the check
# - score 0 & strict == True -> success = False
# - score 0 & strict == False -> success = True
-- --
2.23.0 2.23.0

View File

@ -1,124 +0,0 @@
diff -Nuar anaconda-33.19.org/pyanaconda/modules/storage/bootloader/factory.py anaconda-33.19.sw/pyanaconda/modules/storage/bootloader/factory.py
--- anaconda-33.19.org/pyanaconda/modules/storage/bootloader/factory.py 2022-09-07 14:50:46.860000000 +0800
+++ anaconda-33.19.sw/pyanaconda/modules/storage/bootloader/factory.py 2022-09-07 14:50:57.380000000 +0800
@@ -106,6 +106,10 @@
platform_class = platform.platform.__class__
# Get the type of the bootloader.
+ if platform_class is platform.Sw_64:
+ from pyanaconda.modules.storage.bootloader.grub2 import GRUB2
+ return GRUB2
+
if platform_class is platform.X86:
from pyanaconda.modules.storage.bootloader.grub2 import GRUB2
return GRUB2
diff -Nuar anaconda-33.19.org/pyanaconda/modules/storage/bootloader/grub2.py anaconda-33.19.sw/pyanaconda/modules/storage/bootloader/grub2.py
--- anaconda-33.19.org/pyanaconda/modules/storage/bootloader/grub2.py 2022-09-07 14:50:46.860000000 +0800
+++ anaconda-33.19.sw/pyanaconda/modules/storage/bootloader/grub2.py 2022-09-07 14:56:42.550000000 +0800
@@ -101,7 +101,7 @@
name = "GRUB2"
# grub2 is a virtual provides that's provided by grub2-pc, grub2-ppc64le,
# and all of the primary grub components that aren't grub2-efi-${EFIARCH}
- packages = ["grub2", "grub2-tools"]
+ packages = ["grub2-common", "grub2-tools"]
_config_file = "grub.cfg"
_config_dir = "grub2"
_passwd_file = "user.cfg"
@@ -453,16 +453,47 @@
return
try:
- self.write_device_map()
- self.stage2_device.format.sync(root=conf.target.physical_root)
- os.sync()
- self.install()
- os.sync()
- self.stage2_device.format.sync(root=conf.target.physical_root)
+ if os.path.exists("/mnt/sysroot/boot/grub"):
+ FileName="/mnt/sysroot/boot/grub/grub.cfg"
+ f=open(FileName,"w+")
+ f.write("# SW_64 Grub default configurations\n")
+ f.write("set default=0\n")
+ f.write("set timeout=10\n")
+ f.write("\n")
+ f.write("set menu_color_normal=white/black\n")
+ f.write("set menu_color_highlight=light-red/black\n")
+ f.write("\n")
+ f.write("loadfont ${prefix}/fonts/unicode.pf2\n")
+ f.write("insmod efi_gop\n")
+ f.write("set lang=zh_CN\n")
+ f.write("set gfxmode=800x600\n")
+ f.write("set gfxplayload=auto\n")
+ f.write("terminal_output gfxterm\n")
+ f.write("background_color 64,0,64\n")
+ f.write("\n")
+ f.write("menuentry 'openEuler 22.03 LTS SP1' --class gnu-linux --class gnu --class os{\n")
+ f.write("echo \"Loading, please wait for a moment......\"\n")
+ f.write ("set boot=(${root})\n")
+ f.write("echo \"Loading boot\"\n")
+ f.write ("linux.boot ${boot}/initramfs-5.10.0-39.0.0.21.sw_64.img\n")
+ f.write("echo \"Loading vmlinuz\"\n")
+ f.write("linux.vmlinux ${boot}/vmlinuz-5.10.0-39.0.0.21.sw_64 root=/dev/mapper/openeuler-root rootdelay=60 net.ifnames=0 loglevel=0 vga=current rd.systemd.show_status=false rd.udev.log-priority=3 quiet splash video=sm750fb:1280x1024@60 cgroup.memory=nokmem notc\n")
+ f.write("echo \"Booting......\"\n")
+ f.write("boot\n")
+ f.write("}")
+ f.close()
+ else:
+ self.write_device_map()
+ self.stage2_device.format.sync(root=conf.target.physical_root)
+ os.sync()
+ self.install()
+ os.sync()
+ self.stage2_device.format.sync(root=conf.target.physical_root)
finally:
- self.write_config()
- os.sync()
- self.stage2_device.format.sync(root=conf.target.physical_root)
+ pass
+ #self.write_config()
+ #os.sync()
+ #self.stage2_device.format.sync(root=conf.target.physical_root)
def check(self):
"""When installing to the mbr of a disk grub2 needs enough space
diff -Nuar anaconda-33.19.org/pyanaconda/modules/storage/platform.py anaconda-33.19.sw/pyanaconda/modules/storage/platform.py
--- anaconda-33.19.org/pyanaconda/modules/storage/platform.py 2022-09-07 14:50:46.850000000 +0800
+++ anaconda-33.19.sw/pyanaconda/modules/storage/platform.py 2022-09-07 14:50:57.380000000 +0800
@@ -116,6 +116,17 @@
selection fails."""
return self._boot_stage1_missing_error
+class Sw_64(Platform):
+ _boot_stage1_device_types = ["disk"]
+ _boot_mbr_description = N_("Master Boot Record")
+ _boot_descriptions = {"disk": _boot_mbr_description,
+ "partition": Platform._boot_partition_description,
+ "mdarray": Platform._boot_raid_description}
+
+ # XXX hpfs, if reported by blkid/udev, will end up with a type of None
+ _non_linux_format_types = ["vfat", "ntfs", "hpfs"]
+ _boot_stage1_missing_error = N_("You must include at least one MBR- or "
+ "GPT-formatted disk as an install target.")
class X86(Platform):
_boot_stage1_device_types = ["disk"]
@@ -281,6 +292,8 @@
raise SystemError("Unsupported PPC machine type: %s" % ppc_machine)
elif arch.is_s390():
return S390()
+ elif arch.is_sw_64():
+ return Sw_64()
elif arch.is_efi():
if arch.is_mactel():
return MacEFI()
diff -Nuar anaconda-33.19.org/tests/nosetests/pyanaconda_tests/module_bootloader_test.py anaconda-33.19.sw/tests/nosetests/pyanaconda_tests/module_bootloader_test.py
--- anaconda-33.19.org/tests/nosetests/pyanaconda_tests/module_bootloader_test.py 2022-09-07 14:50:46.610000000 +0800
+++ anaconda-33.19.sw/tests/nosetests/pyanaconda_tests/module_bootloader_test.py 2022-09-07 14:50:57.130000000 +0800
@@ -393,6 +393,7 @@
# Test known platforms.
boot_loader_by_platform = {
platform.X86: GRUB2,
+ platform.Sw_64: GRUB2,
platform.EFI: EFIGRUB,
platform.MacEFI: MacEFIGRUB,
platform.PPC: GRUB2,

Binary file not shown.

BIN
anaconda-36.16.5.tar.bz2 Normal file

Binary file not shown.

View File

@ -1,127 +0,0 @@
From 4e699fe30da24771b80ff1fe64d7791bcb444f79 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Tue, 21 Jul 2020 10:57:00 +0200
Subject: [PATCH] Allow to detect devices with the iso9660 file system as
optical media
Test that the DBus method FindOpticalMedia identifies devices with the iso9660 file
system as optical media, so it is able to find NVDIMM devices with iso9660.
The DBus method GetDevicesToIgnore of the NVDIMM module shouldn't return NVDIMM
devices with the iso9660 file system. They can be used as an installation source.
Protect all devices with the iso9660 file system. It will protect, for example, NVDIMM
devices with the iso9660 file system that can be used only as an installation source
anyway.
Related: rhbz#1856264
---
.../modules/storage/devicetree/model.py | 5 ++++
pyanaconda/modules/storage/nvdimm/nvdimm.py | 12 ++++++++-
.../module_device_tree_test.py | 27 ++++++++++++++++---
3 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/modules/storage/devicetree/model.py b/pyanaconda/modules/storage/devicetree/model.py
index 4d0ecdb..cdee5a8 100644
--- a/pyanaconda/modules/storage/devicetree/model.py
+++ b/pyanaconda/modules/storage/devicetree/model.py
@@ -303,6 +303,11 @@ class InstallerStorage(Blivet):
# cdroms, involves unmounting which is undesirable (see bug #1671713).
protected.extend(dev for dev in self.devicetree.devices if dev.type == "cdrom")
+ # Protect also all devices with an iso9660 file system. It will protect
+ # NVDIMM devices that can be used only as an installation source anyway
+ # (see the bug #1856264).
+ protected.extend(dev for dev in self.devicetree.devices if dev.format.type == "iso9660")
+
# Mark the collected devices as protected.
for dev in protected:
log.debug("Marking device %s as protected.", dev.name)
diff --git a/pyanaconda/modules/storage/nvdimm/nvdimm.py b/pyanaconda/modules/storage/nvdimm/nvdimm.py
index 0bbcc6e..4476dd1 100644
--- a/pyanaconda/modules/storage/nvdimm/nvdimm.py
+++ b/pyanaconda/modules/storage/nvdimm/nvdimm.py
@@ -21,6 +21,7 @@ import gi
gi.require_version("BlockDev", "2.0")
from gi.repository import BlockDev as blockdev
+from blivet import udev
from blivet.static_data import nvdimm
from pykickstart.constants import NVDIMM_ACTION_RECONFIGURE, NVDIMM_ACTION_USE
@@ -90,6 +91,9 @@ class NVDIMMModule(KickstartBaseModule):
installation, the device(s) must be specified by nvdimm kickstart
command. Also, only devices in sector mode are allowed.
+ Don't ignore devices that have an iso9660 file system. We might
+ want to use them as an installation source.
+
:return: a set of device names
"""
namespaces_to_use = self.get_namespaces_to_use()
@@ -97,7 +101,13 @@ class NVDIMMModule(KickstartBaseModule):
devices_to_ignore = set()
for ns_name, ns_info in nvdimm.namespaces.items():
- if ns_info.mode != blockdev.NVDIMMNamespaceMode.SECTOR:
+ info = udev.get_device(device_node="/dev/" + ns_info.blockdev)
+
+ if info and udev.device_get_format(info) == "iso9660":
+ log.debug("%s / %s won't be ignored - NVDIMM device has "
+ "an iso9660 file system", ns_name, ns_info.blockdev)
+ continue
+ elif ns_info.mode != blockdev.NVDIMMNamespaceMode.SECTOR:
log.debug("%s / %s will be ignored - NVDIMM device is not "
"in sector mode", ns_name, ns_info.blockdev)
elif ns_name not in namespaces_to_use and ns_info.blockdev not in devices_to_use:
diff --git a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
index 838c70e..5e52843 100644
--- a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
@@ -24,10 +24,10 @@ from unittest.mock import patch, Mock, PropertyMock
from tests.nosetests.pyanaconda_tests import patch_dbus_publish_object, check_task_creation
from blivet.devices import StorageDevice, DiskDevice, DASDDevice, ZFCPDiskDevice, PartitionDevice, \
- LUKSDevice, iScsiDiskDevice, NVDIMMNamespaceDevice, FcoeDiskDevice
+ LUKSDevice, iScsiDiskDevice, NVDIMMNamespaceDevice, FcoeDiskDevice, OpticalDevice
from blivet.errors import StorageError, FSError
from blivet.formats import get_format
-from blivet.formats.fs import FS
+from blivet.formats.fs import FS, Iso9660FS
from blivet.formats.luks import LUKS
from blivet.size import Size
@@ -627,9 +627,28 @@ class DeviceTreeInterfaceTestCase(unittest.TestCase):
str(cm.exception), "Failed to unmount dev1 from /path: Fake error."
)
- def find_install_media_test(self):
+ @patch.object(Iso9660FS, "check_module")
+ def find_install_media_test(self, check_module):
"""Test FindInstallMedia."""
- self.assertEqual(self.interface.FindOpticalMedia(), [])
+ dev1 = OpticalDevice("dev1")
+ dev1.size = Size("2 GiB")
+ dev1.format = get_format("iso9660")
+ dev1.controllable = True
+ self._add_device(dev1)
+
+ dev2 = StorageDevice("dev2")
+ dev2.size = Size("2 GiB")
+ dev2.format = get_format("iso9660")
+ dev2.controllable = True
+ self._add_device(dev2)
+
+ dev3 = StorageDevice("dev3")
+ dev3.size = Size("2 GiB")
+ dev3.format = get_format("ext4")
+ dev3.controllable = True
+ self._add_device(dev3)
+
+ self.assertEqual(self.interface.FindOpticalMedia(), ["dev1", "dev2"])
@patch.object(FS, "update_size_info")
def find_mountable_partitions_test(self, update_size_info):
--
2.23.0

View File

@ -1,642 +0,0 @@
From 5283a20d41050551b54d6d12960ac28e0e5e1648 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Tue, 21 Jul 2020 11:17:40 +0200
Subject: [PATCH] Fix stage2 as default sources
We should prioritize stage2 device as the default source.
This is especially needed for DVD ISO because it is booting
with inst.stage2 instead and we should use the DVD
as the source for the default CDROM.
The situation is even worse thanks to the fact that
DVD ISOs are using inst.stage2=hd:...
Find stage2 device and test this device first during
the auto-discover feature of CDRom source.
Resolves: rhbz#1856264
---
.../modules/payloads/source/cdrom/cdrom.py | 7 +-
.../payloads/source/cdrom/cdrom_interface.py | 7 +-
.../payloads/source/cdrom/initialization.py | 64 +++-
pyanaconda/modules/payloads/source/utils.py | 8 +-
.../modules/storage/devicetree/handler.py | 5 +-
.../storage/devicetree/handler_interface.py | 5 +-
pyanaconda/payload/utils.py | 2 +-
.../module_device_tree_test.py | 23 +-
.../module_source_cdrom_test.py | 286 ++++++++++++++++--
9 files changed, 362 insertions(+), 45 deletions(-)
diff --git a/pyanaconda/modules/payloads/source/cdrom/cdrom.py b/pyanaconda/modules/payloads/source/cdrom/cdrom.py
index 93df362..bb751ae 100644
--- a/pyanaconda/modules/payloads/source/cdrom/cdrom.py
+++ b/pyanaconda/modules/payloads/source/cdrom/cdrom.py
@@ -32,7 +32,12 @@ log = get_module_logger(__name__)
class CdromSourceModule(PayloadSourceBase, MountingSourceMixin, RPMSourceMixin):
- """The CD-ROM source payload module."""
+ """The CD-ROM source payload module.
+
+ This source will try to automatically detect installation source. First it tries to look only
+ stage2 device used to boot the environment then it will use first valid iso9660 media with a
+ valid structure.
+ """
def __init__(self):
super().__init__()
diff --git a/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py b/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py
index 0c5b6d7..74d2f14 100644
--- a/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py
+++ b/pyanaconda/modules/payloads/source/cdrom/cdrom_interface.py
@@ -25,7 +25,12 @@ from pyanaconda.modules.payloads.source.source_base_interface import PayloadSour
@dbus_interface(PAYLOAD_SOURCE_CDROM.interface_name)
class CdromSourceInterface(PayloadSourceBaseInterface):
- """Interface for the payload CD-ROM image source."""
+ """Interface for the payload CD-ROM image source.
+
+ This source will try to automatically detect installation source. First it tries to look only
+ stage2 device used to boot the environment then it will use first valid iso9660 media with a
+ valid structure.
+ """
def connect_signals(self):
super().connect_signals()
diff --git a/pyanaconda/modules/payloads/source/cdrom/initialization.py b/pyanaconda/modules/payloads/source/cdrom/initialization.py
index a182fcd..7fc38fc 100644
--- a/pyanaconda/modules/payloads/source/cdrom/initialization.py
+++ b/pyanaconda/modules/payloads/source/cdrom/initialization.py
@@ -15,13 +15,15 @@
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
+from pyanaconda.core.kernel import kernel_arguments
from pyanaconda.modules.common.constants.objects import DEVICE_TREE
from pyanaconda.modules.common.constants.services import STORAGE
from pyanaconda.modules.common.errors.payload import SourceSetupError
-from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask
from pyanaconda.modules.common.structures.storage import DeviceData
-from pyanaconda.payload.utils import mount, unmount, PayloadSetupError
+from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask
from pyanaconda.modules.payloads.source.utils import is_valid_install_disk
+from pyanaconda.payload.source.factory import SourceFactory, PayloadSourceTypeUnrecognized
+from pyanaconda.payload.utils import mount, unmount, PayloadSetupError
from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
@@ -37,13 +39,62 @@ class SetUpCdromSourceTask(SetUpMountTask):
return "Set up CD-ROM Installation Source"
def _do_mount(self):
- """Run CD-ROM installation source setup."""
- log.debug("Trying to detect CD-ROM automatically")
+ """Run CD-ROM installation source setup.
+ Try to discover installation media and mount that. Device used for booting (inst.stage2)
+ has a priority.
+ """
+ log.debug("Trying to detect CD-ROM automatically")
device_tree = STORAGE.get_proxy(DEVICE_TREE)
+
+ device_candidates = self._get_device_candidate_list(device_tree)
+ device_name = self._choose_installation_device(device_tree, device_candidates)
+
+ if not device_name:
+ raise SourceSetupError("Found no CD-ROM")
+
+ return device_name
+
+ def _get_device_candidate_list(self, device_tree):
+ stage2_device = self._probe_stage2_for_cdrom(device_tree)
+ device_candidates = device_tree.FindOpticalMedia()
+
+ if stage2_device in device_candidates:
+ device_candidates = [stage2_device] + device_candidates
+
+ return device_candidates
+
+ @staticmethod
+ def _probe_stage2_for_cdrom(device_tree):
+ # TODO: This is temporary method which should be moved closer to the inst.repo logic
+ log.debug("Testing if inst.stage2 is a CDROM device")
+ stage2_string = kernel_arguments.get("stage2")
+
+ if not stage2_string:
+ return None
+
+ try:
+ source = SourceFactory.parse_repo_cmdline_string(stage2_string)
+ except PayloadSourceTypeUnrecognized:
+ log.warning("Unknown stage2 method: %s", stage2_string)
+ return None
+
+ # We have HDD here because DVD ISO has inst.stage2=hd:LABEL=....
+ # TODO: Let's return back support of inst.cdrom=<device> which should work based on the
+ # documentation and use that as inst.stage2 parameter for Pungi
+ if not source.is_harddrive:
+ log.debug("Stage2 can't be used as source %s", stage2_string)
+ return None
+
+ # We can ignore source.path here because DVD ISOs are not using that.
+ stage2_device = device_tree.ResolveDevice(source.partition)
+ log.debug("Found possible stage2 default installation source %s", stage2_device)
+ return stage2_device
+
+ def _choose_installation_device(self, device_tree, devices_candidates):
device_name = ""
- for dev_name in device_tree.FindOpticalMedia():
+ for dev_name in devices_candidates:
try:
device_data = DeviceData.from_structure(device_tree.GetDeviceData(dev_name))
mount(device_data.path, self._target_mount, "iso9660", "ro")
@@ -57,7 +108,4 @@ class SetUpCdromSourceTask(SetUpMountTask):
else:
unmount(self._target_mount)
- if not device_name:
- raise SourceSetupError("Found no CD-ROM")
-
return device_name
diff --git a/pyanaconda/modules/payloads/source/utils.py b/pyanaconda/modules/payloads/source/utils.py
index b9642a9..5030fc5 100644
--- a/pyanaconda/modules/payloads/source/utils.py
+++ b/pyanaconda/modules/payloads/source/utils.py
@@ -84,10 +84,10 @@ def find_and_mount_device(device_spec, mount_point):
device_path = "/dev/" + matches[0]
try:
- # FIXME: Add back RO mounting. This was removed because we can't mount one source
- # RW and RO at the same time. This source is also mounted by IsoChooser dialog in the
- # SourceSpoke.
- mount(device_path, mount_point, "auto")
+ mount(device=device_path,
+ mountpoint=mount_point,
+ fstype="auto",
+ options="defaults,ro")
return True
except OSError as e:
log.error("Mount of device failed: %s", e)
diff --git a/pyanaconda/modules/storage/devicetree/handler.py b/pyanaconda/modules/storage/devicetree/handler.py
index 1fca6c0..453f27d 100644
--- a/pyanaconda/modules/storage/devicetree/handler.py
+++ b/pyanaconda/modules/storage/devicetree/handler.py
@@ -82,16 +82,17 @@ class DeviceTreeHandler(ABC):
msg = "Failed to tear down {}: {}".format(device_name, str(e))
raise DeviceSetupError(msg) from None
- def mount_device(self, device_name, mount_point):
+ def mount_device(self, device_name, mount_point, options):
"""Mount a filesystem on the device.
:param device_name: a name of the device
:param mount_point: a path to the mount point
+ :param options: a string with mount options or an empty string to use defaults
:raise: MountFilesystemError if mount fails
"""
device = self._get_device(device_name)
try:
- device.format.mount(mountpoint=mount_point)
+ device.format.mount(mountpoint=mount_point, options=options or None)
except FSError as e:
msg = "Failed to mount {} at {}: {}". format(
device_name,
diff --git a/pyanaconda/modules/storage/devicetree/handler_interface.py b/pyanaconda/modules/storage/devicetree/handler_interface.py
index 3839e17..2a16eb7 100644
--- a/pyanaconda/modules/storage/devicetree/handler_interface.py
+++ b/pyanaconda/modules/storage/devicetree/handler_interface.py
@@ -46,14 +46,15 @@ class DeviceTreeHandlerInterface(InterfaceTemplate):
"""
self.implementation.teardown_device(device_name)
- def MountDevice(self, device_name: Str, mount_point: Str):
+ def MountDevice(self, device_name: Str, mount_point: Str, options: Str):
"""Mount a filesystem on the device.
:param device_name: a name of the device
:param mount_point: a path to the mount point
+ :param options: a string with mount options or an empty string to use defaults
:raise: MountFilesystemError if mount fails
"""
- self.implementation.mount_device(device_name, mount_point)
+ self.implementation.mount_device(device_name, mount_point, options)
def UnmountDevice(self, device_name: Str, mount_point: Str):
"""Unmount a filesystem on the device.
diff --git a/pyanaconda/payload/utils.py b/pyanaconda/payload/utils.py
index e0c7d6c..eb94f79 100644
--- a/pyanaconda/payload/utils.py
+++ b/pyanaconda/payload/utils.py
@@ -71,7 +71,7 @@ def mount_device(device_name, mount_point):
:param str mount_point: a path to the mount point
"""
device_tree = STORAGE.get_proxy(DEVICE_TREE)
- device_tree.MountDevice(device_name, mount_point)
+ device_tree.MountDevice(device_name, mount_point, "ro")
def unmount_device(device_name, mount_point):
diff --git a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
index 33b06e8..838c70e 100644
--- a/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_device_tree_test.py
@@ -582,12 +582,29 @@ class DeviceTreeInterfaceTestCase(unittest.TestCase):
self._add_device(StorageDevice("dev1", fmt=get_format("ext4")))
with tempfile.TemporaryDirectory() as d:
- self.interface.MountDevice("dev1", d)
- mount.assert_called_once_with(mountpoint=d)
+ self.interface.MountDevice("dev1", d, "")
+ mount.assert_called_once_with(mountpoint=d, options=None)
mount.side_effect = FSError("Fake error.")
with self.assertRaises(MountFilesystemError) as cm:
- self.interface.MountDevice("dev1", "/path")
+ self.interface.MountDevice("dev1", "/path", "")
+
+ self.assertEqual(
+ str(cm.exception), "Failed to mount dev1 at /path: Fake error."
+ )
+
+ @patch.object(FS, "mount")
+ def mount_device_with_options_test(self, mount):
+ """Test MountDevice with options specified."""
+ self._add_device(StorageDevice("dev1", fmt=get_format("ext4")))
+
+ with tempfile.TemporaryDirectory() as d:
+ self.interface.MountDevice("dev1", d, "ro,auto")
+ mount.assert_called_once_with(mountpoint=d, options="ro,auto")
+
+ mount.side_effect = FSError("Fake error.")
+ with self.assertRaises(MountFilesystemError) as cm:
+ self.interface.MountDevice("dev1", "/path", "ro,auto")
self.assertEqual(
str(cm.exception), "Failed to mount dev1 at /path: Fake error."
diff --git a/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py b/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py
index 386322d..4c964a7 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_cdrom_test.py
@@ -124,6 +124,8 @@ class CdromSourceTestCase(unittest.TestCase):
class CdromSourceSetupTaskTestCase(unittest.TestCase):
+ # TODO: To avoid so much patching it would be great to split tests to parts and test those
+
mount_location = "/mnt/put-cdrom-here"
def setup_install_source_task_name_test(self):
@@ -156,8 +158,15 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
device_tree.FindOpticalMedia = Mock()
device_tree.FindOpticalMedia.return_value = [dev.name for dev in devices]
+ def _find_device_by_name(name):
+ for dev in devices:
+ if dev.name == name:
+ return DeviceData.to_structure(dev)
+
+ return None
+
device_tree.GetDeviceData = Mock()
- device_tree.GetDeviceData.side_effect = [DeviceData.to_structure(dev) for dev in devices]
+ device_tree.GetDeviceData.side_effect = _find_device_by_name
return device_tree
@@ -172,42 +181,261 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
This matches the logic in tested method.
"""
for n in range(num_called):
- self.assertIn(
- call("test{}".format(n)),
- device_tree_mock.GetDeviceData.mock_calls
- )
- self.assertIn(
- call("/dev/cdrom-test{}".format(n), self.mount_location, "iso9660", "ro"),
- mount_mock.mock_calls
- )
+ self._check_if_device_was_tried(device_tree_mock,
+ mount_mock,
+ "test{}".format(n))
for n in range(num_called, num_called + num_untouched):
- self.assertNotIn(
- call("test{}".format(n)),
- device_tree_mock.GetDeviceData.mock_calls
- )
- self.assertNotIn(
- call("/dev/cdrom-test{}".format(n), self.mount_location, "iso9660", "ro"),
- mount_mock.mock_calls
- )
+ self._check_if_device_was_not_tried(device_tree_mock,
+ mount_mock,
+ "test{}".format(n))
self.assertEqual(device_tree_mock.GetDeviceData.call_count, num_called)
self.assertEqual(mount_mock.call_count, num_called)
+ def _check_if_device_was_tried(self,
+ device_tree_mock,
+ mount_mock,
+ device_name):
+ self.assertIn(
+ call(device_name),
+ device_tree_mock.GetDeviceData.mock_calls
+ )
+
+ self.assertIn(
+ call("/dev/cdrom-{}".format(device_name), self.mount_location, "iso9660", "ro"),
+ mount_mock.mock_calls
+ )
+
+ def _check_if_device_was_not_tried(self,
+ device_tree_mock,
+ mount_mock,
+ device_name):
+ self.assertNotIn(
+ call(device_name),
+ device_tree_mock.GetDeviceData.mock_calls
+ )
+
+ self.assertNotIn(
+ call("/dev/cdrom-{}".format(device_name), self.mount_location, "iso9660", "ro"),
+ mount_mock.mock_calls
+ )
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - prioritize inst.stage2 CD-ROMs.
+
+ Add valid stage2 CDROM device and it has to be tested first.
+ """
+ kernel_arguments_mock.get.return_value = "hd:LABEL=my-cool-dvd"
+ device_tree = self.set_up_device_tree(2)
+ device_tree.ResolveDevice.return_value = "test1"
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ # Only one device was checked
+ device_tree.ResolveDevice.assert_called_once_with("LABEL=my-cool-dvd")
+
+ self._check_if_device_was_tried(device_tree, mount_mock, "test1")
+ self._check_if_device_was_not_tried(device_tree, mount_mock, "test0")
+
+ # First device (stage2 device) is valid one
+ valid_mock.assert_called_once()
+
+ # First device works so no unmount is called here
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test1")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_unrecognized_source_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - unrecognized stage2 source.
+
+ This should not happen but when we have the code there let's check it.
+ """
+ kernel_arguments_mock.get.return_value = "wrong source!"
+ device_tree = self.set_up_device_tree(1)
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ device_tree.ResolveDevice.assert_not_called()
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_not_hdd_source_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - stage2 is not HDD source.
+
+ We are testing HDD because DVD ISOs are created with inst.stage2=hd: . We want to change
+ this behavior on master so let's change this test too then.
+
+ TODO: Change this test when DVD ISOs will use cdrom:<device> instead of inst.stage2=hd:...
+ """
+ kernel_arguments_mock.get.return_value = "nfs:test.org:/super/cool/path"
+ device_tree = self.set_up_device_tree(1)
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ device_tree.ResolveDevice.assert_not_called()
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
@patch_dbus_get_proxy
- def choose_from_multiple_cdroms_test(self, proxy_getter, mount_mock, unmount_mock, valid_mock):
+ def priority_stage2_cant_be_resolved_source_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - can't resolve stage2 device.
+
+ Stage2 device can't be resolved. This should not happen but let's make sure the code works.
+ """
+ kernel_arguments_mock.get.return_value = "hd:LABEL=my-cool-dvd"
+ device_tree = self.set_up_device_tree(1)
+ proxy_getter.return_value = device_tree
+ # When device can't be resolved it returns an empty string.
+ device_tree.ResolveDevice.return_value = ""
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ self._check_if_device_was_not_tried(device_tree, mount_mock, "")
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def priority_stage2_not_optical_media_cdrom_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
+ """Test CD-ROM Source setup installation source task run - stage2 is not optical media.
+
+ We should not pick stage2 device if it is not an optical_media which means type iso9660.
+ """
+ kernel_arguments_mock.get.return_value = "hd:LABEL=correct-device"
+ device_tree = self.set_up_device_tree(1)
+ device_tree.ResolveDevice.return_value = "not-optical-media"
+ proxy_getter.return_value = device_tree
+ valid_mock.return_value = True
+
+ task = SetUpCdromSourceTask(self.mount_location)
+ result = task.run()
+
+ device_tree.ResolveDevice.assert_called_once_with("LABEL=correct-device")
+
+ self._check_if_device_was_not_tried(device_tree, mount_mock, "correct-device")
+
+ # 1/2 devices tried, 1/2 untried
+ self.assert_resolve_and_mount_calls(device_tree, mount_mock, 1, 1)
+
+ # Only first was mounted
+ self.assertEqual(valid_mock.call_count, 1)
+
+ # First device was used no unmount should be called
+ unmount_mock.assert_not_called()
+
+ # Test device name returned
+ self.assertEqual(result, "test0")
+
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
+ @patch_dbus_get_proxy
+ def choose_from_multiple_cdroms_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
"""Test CD-ROM Source setup installation source task run - choice from multiple CD-ROMs.
Fake four CD-ROM devices: First fails to mount, second has nothing useful, third has what
we want so is left mounted, fourth is entirely skipped.
The other two tests below are needed only to test the exit when nothing is found.
"""
+ kernel_arguments_mock.get.return_value = None
device_tree = self.set_up_device_tree(4)
proxy_getter.return_value = device_tree
-
mount_mock.side_effect = \
[PayloadSetupError("Mocked failure"), DEFAULT, DEFAULT, DEFAULT]
@@ -231,18 +459,24 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
# Test device name returned
self.assertEqual(result, "test2")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
@patch_dbus_get_proxy
- def failure_to_mount_test(self, proxy_getter, mount_mock, unmount_mock, valid_mock):
+ def failure_to_mount_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
"""Test CD-ROM Source setup installation source task run - mount failure.
Mocks one disk which fails to mount, expect exception.
"""
+ kernel_arguments_mock.get.return_value = None
device_tree = self.set_up_device_tree(1)
proxy_getter.return_value = device_tree
-
mount_mock.side_effect = PayloadSetupError("Mocked failure")
valid_mock.return_value = True
@@ -258,18 +492,24 @@ class CdromSourceSetupTaskTestCase(unittest.TestCase):
# exception happened due to no disk
self.assertEqual(str(cm.exception), "Found no CD-ROM")
+ @patch("pyanaconda.modules.payloads.source.cdrom.initialization.kernel_arguments")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.is_valid_install_disk")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.unmount")
@patch("pyanaconda.modules.payloads.source.cdrom.initialization.mount")
@patch_dbus_get_proxy
- def no_cdrom_with_valid_source_test(self, proxy_getter, mount_mock, unmount_mock, valid_mock):
+ def no_cdrom_with_valid_source_test(self,
+ proxy_getter,
+ mount_mock,
+ unmount_mock,
+ valid_mock,
+ kernel_arguments_mock):
"""Test CD-ROM Source setup installation source task run - no valid source CD-ROMs.
Mocks one CD-ROM device which has nothing useful, expect exception.
"""
+ kernel_arguments_mock.get.return_value = None
device_tree = self.set_up_device_tree(1)
proxy_getter.return_value = device_tree
-
valid_mock.return_value = False
with self.assertRaises(SourceSetupError) as cm:
--
2.23.0

View File

@ -1,162 +1,55 @@
%define _empty_manifest_terminate_build 0 %define _empty_manifest_terminate_build 0
Name: anaconda Name: anaconda
Version: 33.19 Version: 36.16.5
Release: 49 Release: 1
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
Source0: https://github.com/rhinstaller/anaconda/archive/%{name}-%{version}.tar.bz2 Source0: https://github.com/rhinstaller/%{name}/releases/download/%{name}-%{version}-1/%{name}-%{version}.tar.bz2
Source1: openeuler.conf Source1: openeuler.conf
Source2: euleros.conf Source2: euleros.conf
Source3: hce.conf Source3: hce.conf
Patch6000: Fix-hiding-of-network-device-activation-switch.patch
Patch9000: add-passwd-policy.patch Patch9000: add-passwd-policy.patch
Patch9001: fix-hostname-info.patch Patch9001: bugfix-GUI-nfs-unknown-error.patch
Patch9002: disable-set-passwd-without-confirmation.patch Patch9002: bugfix-set-up-LD_PRELOAD-for-the-Storage-and-Services-module.patch
Patch9003: bugfix-logo-display-in-low-screen-resolution.patch Patch9003: bugfix-Solve-the-problem-that-the-circular-loading-progress-bar-does-not-rotate.patch
Patch9004: make-name-not-force-to-uppercase.patch Patch9004: change-inst-repo-default-value.patch
Patch9005: bugfix-GUI-nfs-unknown-error.patch Patch9005: disable-disk-encryption.patch
Patch9006: hide-help-button.patch Patch9006: disable-ssh-login-checkbox.patch
Patch9007: modify-interface-is-extended-in-Chinese-mode.patch Patch9007: fix-hostname-info.patch
Patch9008: remove-vender-issue-in-netdev.patch Patch9008: hide-help-button.patch
Patch9009: modify-arguments-parsing.patch Patch9009: modify-interface-is-extended-in-Chinese-mode.patch
Patch9011: disable-product-name-in-welcome-is-uppercase.patch Patch9010: modify-timezone-and-delete-datezone-map.patch
Patch9012: modify-default-timezone.patch Patch9011: remove-vender-issue-in-netdev.patch
Patch9013: modify-network-hostname-dot-illegal.patch Patch9012: Support-configuration-of-additional-boot-arguments.patch
Patch9014: disable-ssh-login-checkbox.patch Patch9013: support-use-sm3-crypt-user-password.patch
Patch9016: bugfix-fix-password-policy.patch
Patch9018: disable-disk-encryption.patch
Patch9019: bugfix-set-up-LD_PRELOAD-for-the-Storage-and-Services-module.patch
Patch9020: bugfix-Propagate-a-lazy-proxy-of-the-storage-model.patch
Patch6001: anaconda-Fix-stage2-as-default-sources.patch
Patch6002: anaconda-Allow-to-detect-devices-with-the-iso9660-file-system.patch
Patch6003: bugfix-do-not-test-if-repo-is-valid-based-on-treeinfo-file.patch
Patch6004: bugfix-move-verify-valid-installtree-to-source-module-utils.patch
Patch6005: bugfix-add-tests-for-verify-valid-installtree-function.patch
Patch6006: bugfix-rename-function-for-a-simple-check-for-DNF-repository.patch
Patch9023: bugfix-add-dnf-transaction-timeout.patch
Patch6007: fix-0-storage-devices-selected.patch
Patch6008: fix-remove-unknow-partition-is-sda-failed.patch
Patch6009: use-modinfo-to-check-ko-before-modprobe.patch
Patch6010: ntp-servers-improve-001-Create-a-new-DBus-structure-for-time-sources.patch
Patch6011: ntp-servers-improve-002-Use-the-structure-for-time-sources-in-ntp-py.patch
Patch6012: ntp-servers-improve-003-Use-the-structure-for-time-sources-in-the-Timezone-module.patch
Patch6013: ntp-servers-improve-004-Use-the-structure-for-time-sources-in-anaconda-py.patch
Patch6014: ntp-servers-improve-005-Use-the-structure-for-time-sources-in-network-py.patch
Patch6015: ntp-servers-improve-006-Add-support-for-the-NTP-server-status-cache.patch
Patch6016: ntp-servers-improve-007-Add-support-for-generating-a-summary-of-the-NTP-servers.patch
Patch6017: ntp-servers-improve-008-Use-the-structure-for-time-sources-in-TUI.patch
Patch6018: ntp-servers-improve-009-Use-the-structure-for-time-sources-in-GUI.patch
Patch6019: ntp-servers-improve-010-Add-support-for-the-timesource-kickstart-command.patch
Patch9024: Change-length-limit-of-hostname-from-255-to-64.patch
Patch9025: Change-topbar-background-size.patch
Patch6020: bugfix-Schedule-timed-actions-with-the-right-selector-18516.patch
Patch6021: bugfix-Reset-the-state-of-the-custom-partitioning-spoke.patch
Patch6022: bugfix-Fix-regression-reading-kernel-list-when-collecting-c.patch
Patch6023: bugfix-Fix-more-SElinux-contexts.patch
Patch6024: bugfix-Fix-issue-when-NFS-path-is-pointing-directly-to-ISO-.patch
Patch6025: bugfix-Create-the-initial-storage-model-during-the-initiali.patch
Patch6026: bugfix-Always-specify-the-boot-disk.patch
Patch6027: bugfix-Fix-passing-of-arguments-when-creating-dracut-argume.patch
Patch6028: bugfix-Reconfigure-DNF-payload-after-options-are-set.patch
Patch6029: bugfix-Only-pass-one-initrd-image-to-kexec.patch
Patch6030: bugfix-Fix-creating-cached-LVs-on-encrypted-PVs.patch
Patch6031: bugfix-Run-actions-of-the-Resize-dialog-in-the-reversed-ord.patch
Patch6032: bugfix-Reload-treeinfo-repositories-on-every-payload-reset.patch
Patch6033: bugfix-Remove-treeinfo-repositories-instead-of-disabling.patch
Patch6034: bugfix-Fix-crash-on-first-entering-of-source-spoke.patch
Patch6035: bugfix-Keep-treeinfo-repositories-disabled-after-payload-re.patch
Patch6036: bugfix-Fix-issue-that-treeinfo-repositories-were-never-disa.patch
Patch6037: bugfix-Fix-kickstart-file-error-with-user-groups.patch
Patch6038: bugfix-Create-ssh-user-using-only-existing-fields-1860058.patch
Patch6039: bugfix-Automatically-break-lines-in-labels-in-software-sele.patch
Patch6040: bugfix-Reset-the-RAID-level-of-the-device-request-1828092.patch
Patch6041: bugfix-Change-keyboard-ordering-to-US-layout-first-native-s.patch
Patch6042: bugfix-Handle-exceptions-from-threads-without-new-instances.patch
Patch6043: bugfix-network-fix-configuration-of-virtual-devices-by-boot.patch
Patch6044: bugfix-network-do-not-try-to-activate-connection-that-has-n.patch
Patch6045: bugfix-network-add-timeout-for-synchronous-activation-of-a-.patch
Patch6046: bugfix-Fix-traceback-when-removing-additional-repository.patch
Patch6047: bugfix-network-do-not-crash-when-updating-a-connection-with.patch
Patch6048: bugfix-Do-not-mount-as-RW-in-Dracut.patch
Patch6049: bugfix-The-underline-character-should-not-be-displayed.patch
Patch6050: bugfix-Recognize-systemd.unit-anaconda.target-in-anaconda-g.patch
Patch6051: bugfix-Always-clear-treeinfo-metadata-1872056.patch
Patch6052: bugfix-Apply-onboot-policy-even-when-network-was-configured.patch
Patch6053: bugfix-network-fix-parsing-of-hostname-from-ip-if-mac-is-de.patch
Patch6054: bugfix-Don-t-generate-container-data-for-non-container-devi.patch
Patch6055: bugfix-Differentiate-between-RAID-levels-of-a-device-and-it.patch
Patch6056: bugfix-Show-warning-message-when-entered-size-is-not-valid.patch
Patch6057: bugfix-Add-the-DBus-method-IsDeviceShrinkable-1875677.patch
Patch6058: bugfix-Check-if-original-partitions-are-mounted-too.patch
Patch6059: bugfix-network-get-hwadddr-when-binding-to-mac-more-robustl.patch
Patch6060: bugfix-Fix-the-combo-box-for-an-URL-type-of-additional-repo.patch
Patch6061: bugfix-Never-mount-partitions-on-a-disk-with-the-iso9660-fi.patch
Patch6062: bugfix-Add-missing-make-BuildRequires.patch
Patch6063: bugfix-Allow-to-format-selected-DASDs.patch
Patch6064: bugfix-Add-selinux-0-boot-parameter-when-SELinux-is-set-to-.patch
Patch6065: bugfix-Root-password-is-mandatory-if-there-is-not-admin-use.patch
Patch6066: bugfix-Fix-traceback-when-starting-installation-with-inst.c.patch
Patch6067: bugfix-Fix-checking-ssl-certificate-for-metadata-1745064.patch
Patch6068: bugfix-Fix-error-in-initrd-shift-count-out-of-range.patch
Patch6069: bugfix-Fix-the-logic-for-enabling-latest-updates.patch
Patch6070: bugfix-Don-t-enter-spokes-after-we-leave-the-Summary-hub.patch
Patch6071: bugfix-do-not-mount-dbus-source.patch
Patch6072: fix-xorg-timeout-and-throw-exception.patch
Patch6073: bugfix-Fix-issue-when-ns_info-cannot-be-retrieved-for-NVDim.patch
Patch6074: bugfix-Fix-SECTION-headers-in-docstrings.patch
Patch6075: change-inst-repo-default-value.patch
Patch6076: delete-datezone-map.patch
Patch6077: backport-fix-boot-options-generated-by-dracut-module.patch
Patch9027: bugfix-remove-flatpack-support.patch
Patch9028: Change-sidebar-background-size.patch
Patch6078: bugfix-Cancel-planned-manual-update-of-system-time-on-turni.patch
Patch9029: support-use-sm3-crypt-user-password.patch
Patch6079: backport-remove-authconfig-support.patch
Patch6080: backport-change-the-grub2-user-cfg-permission-from-0700-to-0600.patch
Patch6081: bugfix-change-the-startup-mode-of-do_transaction-sub-proces.patch
Patch6082: Support-configuration-of-additional-boot-arguments.patch
Patch6083: backport-revert-Set-default-entry-to-the-BLS-id-instead-of-th.patch
Patch6084: bugfix-Solve-the-problem-that-the-circular-loading-progress-bar-does-not-rotate.patch
%ifarch sw_64
Patch6085: anaconda-33.19.sw.patch
%endif
%ifarch loongarch64
Patch6086: 0001-add-loongarch-support-for-anaconda-33.19.patch
%endif
%define dasbusver 1.3
%define dbusver 1.2.3 %define dbusver 1.2.3
%define dnfver 3.6.0 %define dnfver 3.6.0
%define dracutver 034-7 %define dracutver 034-7
%define gettextver 0.19.8 %define gettextver 0.19.8
%define gtk3ver 3.22.17 %define gtk3ver 3.22.17
%define isomd5sum 1.0.10 %define isomd5sumver 1.0.10
%define langtablever 0.0.49 %define langtablever 0.0.54
%define libarchivever 3.0.4 %define libarchivever 3.0.4
%define libblockdevver 2.1 %define libblockdevver 2.1
%define libxklavierver 5.4 %define libxklavierver 5.4
%define mehver 0.23-1 %define mehver 0.23-1
%define nmver 1.0 %define nmver 1.0
%define pykickstartver 3.27-1 %define pykickstartver 3.32-1
%define pypartedver 2.5-2 %define pypartedver 2.5-2
%define rpmver 4.10.0 %define pythonblivetver 1:3.4.0-1
%define rpmver 4.15.0
%define simplelinever 1.1-1 %define simplelinever 1.1-1
%define utillinuxver 2.15.1 %define utillinuxver 2.15.1
%define dasbusver 0.4
BuildRequires: python3-pygments BuildRequires: python3-pygments
BuildRequires: audit-libs-devel libtool gettext-devel >= %{gettextver} gtk3-devel >= %{gtk3ver} BuildRequires: audit-libs-devel libtool gettext-devel >= %{gettextver} gtk3-devel >= %{gtk3ver}
BuildRequires: gtk-doc gtk3-devel-docs >= %{gtk3ver} glib2-doc gobject-introspection-devel BuildRequires: gtk-doc gtk3-devel-docs >= %{gtk3ver} glib2-doc gobject-introspection-devel
BuildRequires: glade-devel libgnomekbd-devel libxklavier-devel >= %{libxklavierver} pango-devel BuildRequires: glade-devel libgnomekbd-devel libxklavier-devel >= %{libxklavierver} pango-devel
BuildRequires: make
BuildRequires: python3-kickstart >= %{pykickstartver} python3-devel systemd BuildRequires: python3-kickstart >= %{pykickstartver} python3-devel systemd
BuildRequires: rpm-devel >= %{rpmver} libarchive-devel >= %{libarchivever} gdk-pixbuf2-devel BuildRequires: rpm-devel >= %{rpmver} libarchive-devel >= %{libarchivever} gdk-pixbuf2-devel
BuildRequires: libxml2 BuildRequires: libxml2
@ -164,16 +57,14 @@ BuildRequires: gsettings-desktop-schemas metacity
Requires: anaconda-core = %{version}-%{release} Requires: anaconda-core = %{version}-%{release}
Requires: anaconda-tui = %{version}-%{release} Requires: anaconda-tui = %{version}-%{release}
Requires: libblockdev-plugins-all >= %{libblockdevver} realmd isomd5sum >= %{isomd5sum} Requires: libblockdev-plugins-all >= %{libblockdevver} realmd isomd5sum >= %{isomd5sumver}
Requires: kexec-tools createrepo_c tmux gdb rsync python3-meh-gui >= %{mehver} Requires: kexec-tools createrepo_c tmux gdb rsync python3-meh-gui >= %{mehver}
Requires: adwaita-icon-theme python3-kickstart Requires: adwaita-icon-theme python3-kickstart
Requires: tigervnc-server-minimal libxklavier >= %{libxklavierver} libgnomekbd Requires: tigervnc-server-minimal libxklavier >= %{libxklavierver} libgnomekbd
Requires: nm-connection-editor keybinder3 system-logos Requires: nm-connection-editor keybinder3 system-logos
Requires: python3 Requires: python3
%ifarch %{ix86} x86_64
BuildRequires: desktop-file-utils BuildRequires: desktop-file-utils
Requires: zenity Requires: zenity
%endif
Provides: anaconda-gui = %{version}-%{release} Provides: anaconda-gui = %{version}-%{release}
Obsoletes: anaconda-gui < %{version}-%{release} Obsoletes: anaconda-gui < %{version}-%{release}
@ -189,16 +80,21 @@ The anaconda package is a metapackage for the Anaconda installer.
%package core %package core
Summary: Core of the Anaconda installer Summary: Core of the Anaconda installer
Requires: python3-libs python3-dnf >= %{dnfver} python3-blivet >= 1:3.2.2-1 Requires: python3-libs python3-dnf >= %{dnfver} python3-blivet >= %{pythonblivetver}
Requires: python3-blockdev >= %{libblockdevver} rpm-python3 >= %{rpmver} python3-productmd Requires: python3-blockdev >= %{libblockdevver} rpm-python3 >= %{rpmver} python3-productmd
Requires: libreport-anaconda >= 2.0.21-1 libselinux-python3 python3-meh >= %{mehver} Requires: libreport-anaconda >= 2.0.21-1 libselinux-python3 python3-meh >= %{mehver}
Requires: python3-pyparted >= %{pypartedver} python3-requests python3-requests-file Requires: python3-pyparted >= %{pypartedver} python3-requests python3-requests-file
Requires: python3-requests-ftp python3-kickstart >= %{pykickstartver} Requires: python3-requests-ftp python3-kickstart >= %{pykickstartver}
Requires: python3-langtable >= %{langtablever} util-linux >= %{utillinuxver} python3-gobject-base Requires: python3-langtable >= %{langtablever} util-linux >= %{utillinuxver} python3-gobject-base
Requires: python3-dbus python3-pwquality python3-systemd python3-dasbus >= %{dasbusver} Requires: python3-dbus python3-pwquality python3-systemd python3-dasbus >= %{dasbusver}
Requires: python3-packaging
Requires: cracklib-dicts python3-pytz teamd NetworkManager >= %{nmver} NetworkManager-libnm >= %{nmver} Requires: cracklib-dicts python3-pytz teamd NetworkManager >= %{nmver} NetworkManager-libnm >= %{nmver}
Requires: NetworkManager-team dhclient kbd chrony python3-ntplib systemd python3-pid Requires: NetworkManager-team kbd chrony systemd python3-pid
Requires: python3-ordered-set >= 2.0.0 glibc-langpack-en dbus-daemon Requires: python3-ordered-set >= 2.0.0 glibc-langpack-en dbus-daemon
Requires: systemd-resolved
# Required by the systemd service anaconda-fips.
Requires: crypto-policies
Requires: /usr/bin/update-crypto-policies
# required because of the rescue mode and VNC question # required because of the rescue mode and VNC question
Requires: anaconda-tui = %{version}-%{release} Requires: anaconda-tui = %{version}-%{release}
Provides: anaconda-images = %{version}-%{release} Provides: anaconda-images = %{version}-%{release}
@ -210,10 +106,7 @@ Obsoletes: booty <= 0.107-1
# Ensure it's not possible for a version of grubby to be installed # Ensure it's not possible for a version of grubby to be installed
# that doesn't work with btrfs subvolumes correctly... # that doesn't work with btrfs subvolumes correctly...
Conflicts: grubby < 8.40-10 Conflicts: grubby < 8.40-10
%ifarch %{ix86} x86_64
Requires: usermode Requires: usermode
%endif
%description core %description core
The anaconda-core package contains the program which was used to install your The anaconda-core package contains the program which was used to install your
@ -244,7 +137,6 @@ Requires: dracut-network
Requires: dracut-live Requires: dracut-live
Requires: xz Requires: xz
Requires: python3-kickstart Requires: python3-kickstart
Conflicts: anaconda < %{version}-41
%description dracut %description dracut
The 'anaconda' dracut module handles installer-specific boot tasks and The 'anaconda' dracut module handles installer-specific boot tasks and
@ -275,17 +167,15 @@ sed -i "/^additional_arguments =*/ s/$/ crashkernel=1024M,high smmu.bypassdev=0x
sed -i "/^additional_arguments =*/ s/$/ panic=1 vga=0x317 nohz=off smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15/" %{SOURCE2} sed -i "/^additional_arguments =*/ s/$/ panic=1 vga=0x317 nohz=off smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15/" %{SOURCE2}
sed -i "/^additional_arguments =*/ s/$/ panic=1 vga=0x317 nohz=off smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15/" %{SOURCE3} sed -i "/^additional_arguments =*/ s/$/ panic=1 vga=0x317 nohz=off smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15/" %{SOURCE3}
%endif %endif
install -m 0644 %{SOURCE1} %{buildroot}/%{_sysconfdir}/%{name}/product.d/ install -m 0644 %{SOURCE1} %{buildroot}/%{_sysconfdir}/%{name}/profile.d/
install -m 0644 %{SOURCE2} %{buildroot}/%{_sysconfdir}/%{name}/product.d/ install -m 0644 %{SOURCE2} %{buildroot}/%{_sysconfdir}/%{name}/profile.d/
install -m 0644 %{SOURCE3} %{buildroot}/%{_sysconfdir}/%{name}/product.d/ install -m 0644 %{SOURCE3} %{buildroot}/%{_sysconfdir}/%{name}/profile.d/
# Create an empty directory for addons # Create an empty directory for addons
install -d -m 0755 %{buildroot}%{_datadir}/anaconda/addons install -d -m 0755 %{buildroot}%{_datadir}/anaconda/addons
%ifarch %{ix86} x86_64
desktop-file-install --dir=%{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/liveinst.desktop desktop-file-install --dir=%{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/liveinst.desktop
%endif
# If no langs found, keep going # If no langs found, keep going
%find_lang %{name} || : %find_lang %{name} || :
@ -344,8 +234,8 @@ update-desktop-database &> /dev/null || :
%config %{_sysconfdir}/%{name}/* %config %{_sysconfdir}/%{name}/*
%dir %{_sysconfdir}/%{name}/conf.d %dir %{_sysconfdir}/%{name}/conf.d
%config %{_sysconfdir}/%{name}/conf.d/* %config %{_sysconfdir}/%{name}/conf.d/*
%dir %{_sysconfdir}/%{name}/product.d %dir %{_sysconfdir}/%{name}/profile.d
%config %{_sysconfdir}/%{name}/product.d/* %config %{_sysconfdir}/%{name}/profile.d/*
%{_sbindir}/liveinst %{_sbindir}/liveinst
%{_bindir}/liveinst %{_bindir}/liveinst
%{_libexecdir}/liveinst-setup.sh %{_libexecdir}/liveinst-setup.sh
@ -372,6 +262,11 @@ update-desktop-database &> /dev/null || :
%{_prefix}/libexec/anaconda/dd_* %{_prefix}/libexec/anaconda/dd_*
%changelog %changelog
* Tue Nov 08 2022 sunhai <sunhai10@huawei.com> - 36.16.5-1
- ID:NA
- SUG:NA
- DESC:update anaconda to 36.16.5
* Mon Mar 28 2022 Wenlong Zhang <zhangwenlong@loongson.cn> - 33.19-49 * Mon Mar 28 2022 Wenlong Zhang <zhangwenlong@loongson.cn> - 33.19-49
- ID:NA - ID:NA
- SUG:NA - SUG:NA

View File

@ -1,22 +0,0 @@
From 7db645b89c3c68fbd116dbb8c6e6c1b4ab8eeb07 Mon Sep 17 00:00:00 2001
From: bitcoffee <854182924@qq.com>
Date: Tue, 2 Mar 2021 16:11:35 +0800
Subject: [PATCH] change the grub2 user.cfg permission from 0600 to 0700
---
pyanaconda/modules/storage/bootloader/grub2.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/modules/storage/bootloader/grub2.py b/pyanaconda/modules/storage/bootloader/grub2.py
index add7dc97086..44b08e4dec9 100644
--- a/pyanaconda/modules/storage/bootloader/grub2.py
+++ b/pyanaconda/modules/storage/bootloader/grub2.py
@@ -310,7 +310,7 @@ def write_password_config(self):
return
users_file = "%s%s/%s" % (conf.target.system_root, self.config_dir, self._passwd_file)
- header = util.open_with_perm(users_file, "w", 0o700)
+ header = util.open_with_perm(users_file, "w", 0o600)
# XXX FIXME: document somewhere that the username is "root"
self._encrypt_password()
password_line = "GRUB2_PASSWORD=" + self.encrypted_password

View File

@ -1,56 +0,0 @@
From a807e0095d7c89e47735cd9caa1a19a1489165c4 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Fri, 29 Oct 2021 15:36:40 +0800
Subject: [PATCH] fix boot options generated by dracut module
Add the inst. prefix to the anaconda boot options
---
dracut/parse-kickstart | 4 ++--
tests/nosetests/dracut_tests/parse-kickstart_test.py | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dracut/parse-kickstart b/dracut/parse-kickstart
index 9b55ad6..63e71de 100755
--- a/dracut/parse-kickstart
+++ b/dracut/parse-kickstart
@@ -171,7 +171,7 @@ class DracutURL(Url, DracutArgsMixin):
if self.noverifyssl:
args.append("rd.noverifyssl")
if self.proxy:
- args.append("proxy=%s" % self.proxy)
+ args.append("inst.proxy=%s" % self.proxy)
return "\n".join(args)
@@ -267,7 +267,7 @@ class DracutDisplayMode(DisplayMode, DracutArgsMixin):
class DracutBootloader(Bootloader, DracutArgsMixin):
def dracut_args(self, args, lineno, obj):
if self.extlinux:
- return "extlinux"
+ return "inst.extlinux"
# FUTURE: keymap, lang... device? selinux?
diff --git a/tests/nosetests/dracut_tests/parse-kickstart_test.py b/tests/nosetests/dracut_tests/parse-kickstart_test.py
index 9a5cdcd..4dd37c7 100644
--- a/tests/nosetests/dracut_tests/parse-kickstart_test.py
+++ b/tests/nosetests/dracut_tests/parse-kickstart_test.py
@@ -94,7 +94,7 @@ class ParseKickstartTestCase(BaseTestCase):
self.assertEqual(len(lines), 3, lines)
self.assertEqual(lines[0], "inst.repo=https://host.at.foo.com/path/to/tree", lines)
self.assertEqual(lines[1], "rd.noverifyssl", lines)
- self.assertEqual(lines[2], "proxy=http://localhost:8123", lines)
+ self.assertEqual(lines[2], "inst.proxy=http://localhost:8123", lines)
def updates_test(self):
with tempfile.NamedTemporaryFile(mode="w+t") as ks_file:
@@ -344,4 +344,4 @@ network --device=lo --vlanid=171 --interfacename=vlan171
ks_file.flush()
lines = self.execParseKickstart(ks_file.name)
- self.assertEqual(lines[0], "extlinux", lines)
+ self.assertEqual(lines[0], "inst.extlinux", lines)
--
2.23.0

View File

@ -1,423 +0,0 @@
From 17b8e2e895448aeae990b419036448011b6eb105 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 9 Jul 2021 12:51:07 +0200
Subject: [PATCH] remove authconfig support
Authconfig compatibility tool (from authselect-compat) will be removed from Fedora 35:
https://fedoraproject.org/wiki/Changes/RemoveAuthselectCompatPackage
---
pyanaconda/core/kickstart/commands.py | 1 -
pyanaconda/modules/security/installation.py | 35 +-------
pyanaconda/modules/security/kickstart.py | 2 -
pyanaconda/modules/security/security.py | 44 +--------
.../modules/security/security_interface.py | 23 -----
.../modules/security/test_module_security.py | 89 +------------------
6 files changed, 6 insertions(+), 188 deletions(-)
diff --git a/pyanaconda/core/kickstart/commands.py b/pyanaconda/core/kickstart/commands.py
index 3c3eed0..b3fbdff 100644
--- a/pyanaconda/core/kickstart/commands.py
+++ b/pyanaconda/core/kickstart/commands.py
@@ -22,7 +22,6 @@
# pylint:disable=unused-import
# Supported kickstart commands.
-from pykickstart.commands.authconfig import F28_Authconfig as Authconfig
from pykickstart.commands.authselect import F28_Authselect as Authselect
from pykickstart.commands.autopart import F29_AutoPart as AutoPart
from pykickstart.commands.autostep import FC3_AutoStep as AutoStep
diff --git a/pyanaconda/modules/security/installation.py b/pyanaconda/modules/security/installation.py
index 03badc1678..9d3369f737 100644
--- a/pyanaconda/modules/security/installation.py
+++ b/pyanaconda/modules/security/installation.py
@@ -33,7 +33,6 @@
REALM_TOOL_NAME = "realm"
AUTHSELECT_TOOL_PATH = "/usr/bin/authselect"
-AUTHCONFIG_TOOL_PATH = "/usr/sbin/authconfig"
PAM_SO_PATH = "/lib/security/pam_fprintd.so"
PAM_SO_64_PATH = "/lib64/security/pam_fprintd.so"
@@ -356,7 +355,7 @@ def run(self):
def run_auth_tool(cmd, args, root, required=True):
"""Run an authentication related tool.
- This generally means either authselect or the legacy authconfig tool.
+ This generally means authselect.
:param str cmd: path to the tool to be run
:param list(str) args: list of arguments passed to the tool
:param str root: a path to the root in which the tool should be run
@@ -443,35 +442,3 @@ def run(self):
self._authselect_options + ["--force"],
self._sysroot
)
-
-
-class ConfigureAuthconfigTask(Task):
- """Installation task for Authconfig configuration.
-
- NOTE: Authconfig is deprecated, this is present temporarily
- as long as we want to provide backward compatibility
- for the authconfig command in kickstart.
- """
-
- def __init__(self, sysroot, authconfig_options):
- """Create a new Authconfig configuration task.
-
- :param str sysroot: a path to the root of the target system
- :param list authconfig_options: options for authconfig
- """
- super().__init__()
- self._sysroot = sysroot
- self._authconfig_options = authconfig_options
-
- @property
- def name(self):
- return "Authconfig configuration"
-
- def run(self):
- # Apply the authconfig options from the kickstart file (deprecated).
- if self._authconfig_options:
- run_auth_tool(
- AUTHCONFIG_TOOL_PATH,
- ["--update", "--nostart"] + self._authconfig_options,
- self._sysroot
- )
diff --git a/pyanaconda/modules/security/kickstart.py b/pyanaconda/modules/security/kickstart.py
index 1adbc72934..24cbb03253 100644
--- a/pyanaconda/modules/security/kickstart.py
+++ b/pyanaconda/modules/security/kickstart.py
@@ -23,8 +23,6 @@
class SecurityKickstartSpecification(KickstartSpecification):
commands = {
- "auth": COMMANDS.Authconfig,
- "authconfig": COMMANDS.Authconfig,
"authselect": COMMANDS.Authselect,
"selinux": COMMANDS.SELinux,
"realm": COMMANDS.Realm
diff --git a/pyanaconda/modules/security/security.py b/pyanaconda/modules/security/security.py
index b4e9f3f..de1b7f1 100644
--- a/pyanaconda/modules/security/security.py
+++ b/pyanaconda/modules/security/security.py
@@ -32,7 +32,7 @@ from pyanaconda.modules.security.kickstart import SecurityKickstartSpecification
from pyanaconda.modules.security.security_interface import SecurityInterface
from pyanaconda.modules.security.installation import ConfigureSELinuxTask, \
RealmDiscoverTask, RealmJoinTask, ConfigureAuthselectTask, \
- ConfigureAuthconfigTask, ConfigureFingerprintAuthTask
+ ConfigureFingerprintAuthTask
from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
@@ -50,9 +50,6 @@ class SecurityService(KickstartService):
self.authselect_changed = Signal()
self._authselect_args = []
- self.authconfig_changed = Signal()
- self._authconfig_args = []
-
self.fingerprint_auth_enabled_changed = Signal()
self._fingerprint_auth_enabled = False
@@ -78,9 +75,6 @@ class SecurityService(KickstartService):
if data.authselect.authselect:
self.set_authselect(shlex.split(data.authselect.authselect))
- if data.authconfig.authconfig:
- self.set_authconfig(shlex.split(data.authconfig.authconfig))
-
if data.realm.join_realm:
realm = RealmData()
realm.name = data.realm.join_realm
@@ -97,9 +91,6 @@ class SecurityService(KickstartService):
if self.authselect:
data.authselect.authselect = " ".join(self.authselect)
- if self.authconfig:
- data.authconfig.authconfig = " ".join(self.authconfig)
-
if self.realm.name:
data.realm.join_realm = self.realm.name
data.realm.discover_options = self.realm.discover_options
@@ -139,27 +130,6 @@ class SecurityService(KickstartService):
self.authselect_changed.emit()
log.debug("Authselect is set to %s.", args)
- @property
- def authconfig(self):
- """Arguments for the authconfig tool.
-
- Authconfig is deprecated, use authselect.
-
- :return: a list of arguments
- """
- return self._authconfig_args
-
- def set_authconfig(self, args):
- """Set the arguments for the authconfig tool.
-
- Authconfig is deprecated, use authselect.
-
- :param args: a list of arguments
- """
- self._authconfig_args = args
- self.authconfig_changed.emit()
- log.debug("Authconfig is set to %s.", args)
-
@property
def fingerprint_auth_enabled(self):
"""Specifies if fingerprint authentication should be enabled.
@@ -216,7 +186,7 @@ class SecurityService(KickstartService):
for name in self.realm.required_packages:
requirements.append(Requirement.for_package(name, reason="Needed to join a realm."))
- # Add authselect / authconfig requirements
+ # Add authselect requirements
if self.authselect or self.fingerprint_auth_enabled:
# we need the authselect package in two cases:
# - autselect command is used in kickstart
@@ -227,12 +197,6 @@ class SecurityService(KickstartService):
"for fingerprint authentication support."
))
- if self.authconfig:
- requirements.append(Requirement.for_package(
- "authselect-compat",
- reason="Needed to support legacy authconfig kickstart command."
- ))
-
return requirements
def discover_realm_with_task(self):
@@ -271,9 +235,5 @@ class SecurityService(KickstartService):
ConfigureAuthselectTask(
sysroot=conf.target.system_root,
authselect_options=self.authselect
- ),
- ConfigureAuthconfigTask(
- sysroot=conf.target.system_root,
- authconfig_options=self.authconfig
)
]
diff --git a/pyanaconda/modules/security/security_interface.py b/pyanaconda/modules/security/security_interface.py
index 5191b39..537b972 100644
--- a/pyanaconda/modules/security/security_interface.py
+++ b/pyanaconda/modules/security/security_interface.py
@@ -35,7 +35,6 @@ class SecurityInterface(KickstartModuleInterface):
super().connect_signals()
self.watch_property("SELinux", self.implementation.selinux_changed)
self.watch_property("Authselect", self.implementation.authselect_changed)
- self.watch_property("Authconfig", self.implementation.authconfig_changed)
self.watch_property(
"FingerprintAuthEnabled", self.implementation.fingerprint_auth_enabled_changed
)
@@ -83,28 +82,6 @@ class SecurityInterface(KickstartModuleInterface):
"""
self.implementation.set_authselect(args)
- @property
- def Authconfig(self) -> List[Str]:
- """Arguments for the authconfig tool.
-
- Authconfig is deprecated, use authselect.
-
- :return: a list of arguments
- """
- return self.implementation.authconfig
-
- @emits_properties_changed
- def SetAuthconfig(self, args: List[Str]):
- """Set the arguments for the authconfig tool.
-
- Authconfig is deprecated, use authselect.
-
- Example: ['--passalgo=sha512', '--useshadow']
-
- :param args: a list of arguments
- """
- self.implementation.set_authconfig(args)
-
@property
def Realm(self) -> Structure:
"""Specification of the enrollment in a realm.
diff --git a/tests/nosetests/pyanaconda_tests/module_security_test.py b/tests/nosetests/pyanaconda_tests/module_security_test.py
index 9ea41ec..9fe23e9 100644
--- a/tests/nosetests/pyanaconda_tests/module_security_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_security_test.py
@@ -33,8 +33,8 @@ from pyanaconda.modules.security.security_interface import SecurityInterface
from pyanaconda.modules.security.constants import SELinuxMode
from pyanaconda.modules.security.installation import ConfigureSELinuxTask, \
RealmDiscoverTask, RealmJoinTask, ConfigureFingerprintAuthTask, \
- ConfigureAuthselectTask, ConfigureAuthconfigTask, AUTHSELECT_TOOL_PATH, \
- AUTHCONFIG_TOOL_PATH, PAM_SO_64_PATH, PAM_SO_PATH
+ ConfigureAuthselectTask, AUTHSELECT_TOOL_PATH, \
+ PAM_SO_64_PATH, PAM_SO_PATH
from tests.nosetests.pyanaconda_tests import patch_dbus_publish_object, check_kickstart_interface, \
check_task_creation, check_task_creation_list, PropertiesChangedCallback, check_dbus_property
from pyanaconda.modules.common.structures.requirement import Requirement
@@ -64,7 +64,7 @@ class SecurityInterfaceTestCase(unittest.TestCase):
def kickstart_properties_test(self):
"""Test kickstart properties."""
self.assertEqual(self.security_interface.KickstartCommands,
- ["auth", "authconfig", "authselect", "selinux", "realm"])
+ ["authselect", "selinux", "realm"])
self.assertEqual(self.security_interface.KickstartSections, [])
self.assertEqual(self.security_interface.KickstartAddons, [])
self.callback.assert_not_called()
@@ -83,13 +83,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
["sssd", "with-mkhomedir"]
)
- def authconfig_property_test(self):
- """Test the authconfig property."""
- self._check_dbus_property(
- "Authconfig",
- ["--passalgo=sha512", "--useshadow"]
- )
-
def fingerprint_auth_enabled_test(self):
"""Test the fingerprint_auth_enabled property."""
self._check_dbus_property(
@@ -137,28 +130,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
"""
self._test_kickstart(ks_in, ks_out)
- def auth_kickstart_test(self):
- """Test the auth command."""
- ks_in = """
- auth --passalgo=sha512 --useshadow
- """
- ks_out = """
- # System authorization information
- auth --passalgo=sha512 --useshadow
- """
- self._test_kickstart(ks_in, ks_out)
-
- def authconfig_kickstart_test(self):
- """Test the authconfig command."""
- ks_in = """
- authconfig --passalgo=sha512 --useshadow
- """
- ks_out = """
- # System authorization information
- auth --passalgo=sha512 --useshadow
- """
- self._test_kickstart(ks_in, ks_out)
-
def authselect_kickstart_test(self):
"""Test the authselect command."""
ks_in = """
@@ -210,7 +181,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
ConfigureSELinuxTask,
ConfigureFingerprintAuthTask,
ConfigureAuthselectTask,
- ConfigureAuthconfigTask,
]
task_paths = self.security_interface.InstallWithTasks()
task_objs = check_task_creation_list(self, task_paths, publisher, task_classes)
@@ -224,9 +194,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
# ConfigureAuthselectTask
obj = task_objs[2]
self.assertEqual(obj.implementation._authselect_options, [])
- # ConfigureAuthconfigTask
- obj = task_objs[3]
- self.assertEqual(obj.implementation._authconfig_options, [])
@patch_dbus_publish_object
def realm_join_default_test(self, publisher):
@@ -247,20 +214,17 @@ class SecurityInterfaceTestCase(unittest.TestCase):
realm.discovered = True
authselect = ['select', 'sssd']
- authconfig = ['--passalgo=sha512', '--useshadow']
fingerprint = True
self.security_interface.SetRealm(RealmData.to_structure(realm))
self.security_interface.SetSELinux(SELINUX_PERMISSIVE)
self.security_interface.SetAuthselect(authselect)
- self.security_interface.SetAuthconfig(authconfig)
self.security_interface.SetFingerprintAuthEnabled(fingerprint)
task_classes = [
ConfigureSELinuxTask,
ConfigureFingerprintAuthTask,
ConfigureAuthselectTask,
- ConfigureAuthconfigTask,
]
task_paths = self.security_interface.InstallWithTasks()
task_objs = check_task_creation_list(self, task_paths, publisher, task_classes)
@@ -274,9 +238,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
# ConfigureAuthselectTask
obj = task_objs[2]
self.assertEqual(obj.implementation._authselect_options, authselect)
- # ConfigureAuthconfigTask
- obj = task_objs[3]
- self.assertEqual(obj.implementation._authconfig_options, authconfig)
@patch_dbus_publish_object
def realm_join_configured_test(self, publisher):
@@ -366,15 +327,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
def authselect_requirements_test(self):
"""Test that package requirements for authselect propagate correctly."""
- self.security_interface.SetAuthconfig(['--passalgo=sha512', '--useshadow'])
- requirements = Requirement.from_structure_list(
- self.security_interface.CollectRequirements()
- )
- self.assertEqual(len(requirements), 1)
- self.assertEqual(requirements[0].type, "package")
- self.assertEqual(requirements[0].name, "authselect-compat")
-
- self.security_interface.SetAuthconfig([])
self.security_interface.SetAuthselect(['select', 'sssd'])
requirements = Requirement.from_structure_list(
self.security_interface.CollectRequirements()
@@ -383,7 +335,6 @@ class SecurityInterfaceTestCase(unittest.TestCase):
self.assertEqual(requirements[0].type, "package")
self.assertEqual(requirements[0].name, "authselect")
- self.security_interface.SetAuthconfig([])
self.security_interface.SetAuthselect([])
self.security_interface.SetFingerprintAuthEnabled(True)
requirements = Requirement.from_structure_list(
@@ -860,37 +811,3 @@ class SecurityTasksTestCase(unittest.TestCase):
root=sysroot
)
os.remove(authselect_path)
-
- @patch('pyanaconda.core.util.execWithRedirect')
- def configure_authconfig_task_test(self, execWithRedirect):
- """Test the configure authconfig task."""
- with tempfile.TemporaryDirectory() as sysroot:
-
- authconfig_dir = os.path.normpath(sysroot + os.path.dirname(AUTHCONFIG_TOOL_PATH))
- authconfig_path = os.path.normpath(sysroot + AUTHCONFIG_TOOL_PATH)
- os.makedirs(authconfig_dir)
-
- # The authconfig command is missing
- execWithRedirect.reset_mock()
- task = ConfigureAuthconfigTask(
- sysroot=sysroot,
- authconfig_options=["--passalgo=sha512", "--useshadow"]
- )
- with self.assertRaises(SecurityInstallationError):
- task.run()
- execWithRedirect.assert_not_called()
-
- # The authconfig command is there
- execWithRedirect.reset_mock()
- os.mknod(authconfig_path)
- task = ConfigureAuthconfigTask(
- sysroot=sysroot,
- authconfig_options=["--passalgo=sha512", "--useshadow"]
- )
- task.run()
- execWithRedirect.assert_called_once_with(
- AUTHCONFIG_TOOL_PATH,
- ["--update", "--nostart", "--passalgo=sha512", "--useshadow"],
- root=sysroot
- )
- os.remove(authconfig_path)
--
2.27.0

View File

@ -1,47 +0,0 @@
From 018ab707bd2af446f6e6bd1c8e9384178333c0b9 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Thu, 4 Aug 2022 19:33:40 +0800
Subject: [PATCH] revert "Set default entry to the BLS id instead of the entry index"
revert the patch of "Set default entry to the BLS id instead of the entry index"
Reference:https://github.com/rhinstaller/anaconda/commit/a252e4424bd51d6236d3b7b8e3840d8ca0af90a2
Conflict:https://github.com/rhinstaller/anaconda/commit/a252e4424bd51d6236d3b7b8e3840d8ca0af90a2
---
.../modules/storage/bootloader/grub2.py | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/pyanaconda/modules/storage/bootloader/grub2.py b/pyanaconda/modules/storage/bootloader/grub2.py
index 3209ab7..6a6441b 100644
--- a/pyanaconda/modules/storage/bootloader/grub2.py
+++ b/pyanaconda/modules/storage/bootloader/grub2.py
@@ -335,16 +335,16 @@ class GRUB2(BootLoader):
# make sure the default entry is the OS we are installing
if self.default is not None:
- machine_id_path = conf.target.system_root + "/etc/machine-id"
- if not os.access(machine_id_path, os.R_OK):
- log.error("failed to read machine-id, default entry not set")
- return
-
- with open(machine_id_path, "r") as fd:
- machine_id = fd.readline().strip()
-
- default_entry = "%s-%s" % (machine_id, self.default.version)
- rc = util.execInSysroot("grub2-set-default", [default_entry])
+ # find the index of the default image
+ try:
+ default_index = self.images.index(self.default)
+ except ValueError:
+ # pylint: disable=no-member
+ log.warning("Failed to find default image (%s), defaulting to 0",
+ self.default.label)
+ default_index = 0
+
+ rc = util.execInSysroot("grub2-set-default", [str(default_index)])
if rc:
log.error("failed to set default menu entry to %s", productName)
--
2.27.0

View File

@ -1,26 +0,0 @@
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

@ -1,63 +0,0 @@
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

@ -1,149 +0,0 @@
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

@ -1,32 +0,0 @@
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

@ -1,31 +0,0 @@
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

@ -1,43 +0,0 @@
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

@ -1,27 +0,0 @@
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

@ -1,53 +0,0 @@
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

@ -1,39 +0,0 @@
From ab1ec03e4b6ae7cfc492d330233b63f344f5fee8 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Fri, 31 Dec 2021 19:01:08 +0800
Subject: [PATCH 1/2] init
---
pyanaconda/ui/gui/spokes/datetime_spoke.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
index 09deabb..8ebc5bb 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -1059,8 +1059,22 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
def _show_no_ntp_server_warning(self):
self.set_warning(_("You have no working NTP server configured"))
+ def _cancel_planned_update(self):
+ """Cancel system time update planned by manual setting"""
+ # cancel system time update
+ if self._start_updating_timer:
+ self._start_updating_timer.cancel()
+ self._start_updating_timer = None
+ # re-enable UI update because it will not be done by the
+ # system time update we've just cancelled
+ if not self._update_datetime_timer:
+ self._update_datetime_timer = Timer()
+ self._update_datetime_timer.timeout_sec(1, self._update_datetime)
+
def on_ntp_switched(self, switch, *args):
if switch.get_active():
+ self._cancel_planned_update()
+
#turned ON
if not conf.system.can_set_time_synchronization:
#cannot touch runtime system, not much to do here
--
2.27.0

View File

@ -1,30 +0,0 @@
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

@ -1,66 +0,0 @@
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

@ -1,34 +0,0 @@
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

@ -1,50 +0,0 @@
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

@ -1,107 +0,0 @@
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

@ -1,32 +0,0 @@
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

@ -1,98 +0,0 @@
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

@ -1,37 +0,0 @@
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

@ -1,149 +0,0 @@
From 5d81a7faa67bc065a6e309561865d1682abbcee4 Mon Sep 17 00:00:00 2001
From: Martin Pitt <mpitt@redhat.com>
Date: Wed, 7 Oct 2020 07:26:18 +0200
Subject: [PATCH] Fix SECTION headers in docstrings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Make them coincide with the class names. The missing "Anaconda" prefix
causes a build failure with gobject-introspection ≥ 1.61.1 due to [1]:
Namespace conflict: DocSection('BaseWindow')
See https://bugzilla.redhat.com/show_bug.cgi?id=1885825 for some
details.
[1] https://gitlab.gnome.org/GNOME/gobject-introspection/-/commit/346c0690fe62f614ecb1f55857ea72939d9c0f83
---
widgets/src/BaseStandalone.c | 2 +-
widgets/src/BaseWindow.c | 2 +-
widgets/src/DiskOverview.c | 2 +-
widgets/src/HubWindow.c | 2 +-
widgets/src/LayoutIndicator.c | 2 +-
widgets/src/MountpointSelector.c | 2 +-
widgets/src/SpokeSelector.c | 2 +-
widgets/src/SpokeWindow.c | 2 +-
widgets/src/StandaloneWindow.c | 2 +-
9 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/widgets/src/BaseStandalone.c b/widgets/src/BaseStandalone.c
index 361f94d..ae84bfc 100644
--- a/widgets/src/BaseStandalone.c
+++ b/widgets/src/BaseStandalone.c
@@ -22,7 +22,7 @@
#include "intl.h"
/**
- * SECTION: BaseStandalone
+ * SECTION: AnacondaBaseStandalone
* @title: AnacondaBaseStandalone
* @short_description: Abstract base class for standalone Anaconda windows.
*
diff --git a/widgets/src/BaseWindow.c b/widgets/src/BaseWindow.c
index 203d4a7..35a8fe0 100644
--- a/widgets/src/BaseWindow.c
+++ b/widgets/src/BaseWindow.c
@@ -30,7 +30,7 @@
#include <atk/atk.h>
/**
- * SECTION: BaseWindow
+ * SECTION: AnacondaBaseWindow
* @title: AnacondaBaseWindow
* @short_description: Top-level, non-resizeable window
*
diff --git a/widgets/src/DiskOverview.c b/widgets/src/DiskOverview.c
index c9e6e0b..2d5aec4 100644
--- a/widgets/src/DiskOverview.c
+++ b/widgets/src/DiskOverview.c
@@ -27,7 +27,7 @@
#include "widgets-common.h"
/**
- * SECTION: DiskOverview
+ * SECTION: AnacondaDiskOverview
* @title: AnacondaDiskOverview
* @short_description: A widget that displays basic information about a disk
*
diff --git a/widgets/src/HubWindow.c b/widgets/src/HubWindow.c
index 77d89e8..02ecde4 100644
--- a/widgets/src/HubWindow.c
+++ b/widgets/src/HubWindow.c
@@ -22,7 +22,7 @@
#include "intl.h"
/**
- * SECTION: HubWindow
+ * SECTION: AnacondaHubWindow
* @title: AnacondaHubWindow
* @short_description: Window for displaying a Hub
*
diff --git a/widgets/src/LayoutIndicator.c b/widgets/src/LayoutIndicator.c
index 6e83edd..9fcd983 100644
--- a/widgets/src/LayoutIndicator.c
+++ b/widgets/src/LayoutIndicator.c
@@ -36,7 +36,7 @@
#define DEFAULT_LABEL_MAX_CHAR_WIDTH 8
/**
- * SECTION: LayoutIndicator
+ * SECTION: AnacondaLayoutIndicator
* @title: AnacondaLayoutIndicator
* @short_description: An indicator of currently activated X layout
*
diff --git a/widgets/src/MountpointSelector.c b/widgets/src/MountpointSelector.c
index e87ba6b..e4b1ad3 100644
--- a/widgets/src/MountpointSelector.c
+++ b/widgets/src/MountpointSelector.c
@@ -29,7 +29,7 @@
#include "widgets-common.h"
/**
- * SECTION: MountpointSelector
+ * SECTION: AnacondaMountpointSelector
* @title: AnacondaMountpointSelector
* @short_description: A graphical way to select a mount point.
*
diff --git a/widgets/src/SpokeSelector.c b/widgets/src/SpokeSelector.c
index 56db102..a6c680a 100644
--- a/widgets/src/SpokeSelector.c
+++ b/widgets/src/SpokeSelector.c
@@ -28,7 +28,7 @@
#include "widgets-common.h"
/**
- * SECTION: SpokeSelector
+ * SECTION: AnacondaSpokeSelector
* @title: AnacondaSpokeSelector
* @short_description: A graphical way to enter a configuration spoke
*
diff --git a/widgets/src/SpokeWindow.c b/widgets/src/SpokeWindow.c
index 226eb2c..7a958c6 100644
--- a/widgets/src/SpokeWindow.c
+++ b/widgets/src/SpokeWindow.c
@@ -25,7 +25,7 @@
#include <gdk/gdkkeysyms.h>
/**
- * SECTION: SpokeWindow
+ * SECTION: AnacondaSpokeWindow
* @title: AnacondaSpokeWindow
* @short_description: Window for displaying single spokes
*
diff --git a/widgets/src/StandaloneWindow.c b/widgets/src/StandaloneWindow.c
index 8a92e7b..cc31547 100644
--- a/widgets/src/StandaloneWindow.c
+++ b/widgets/src/StandaloneWindow.c
@@ -25,7 +25,7 @@
#include <gdk/gdkkeysyms.h>
/**
- * SECTION: StandaloneWindow
+ * SECTION: AnacondaStandaloneWindow
* @title: AnacondaStandaloneWindow
* @short_description: Window for displaying standalone spokes
*
--
2.27.0

View File

@ -1,30 +0,0 @@
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

@ -1,40 +0,0 @@
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

@ -1,56 +0,0 @@
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

@ -1,35 +0,0 @@
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

@ -1,34 +0,0 @@
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

@ -1,79 +0,0 @@
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

@ -1,48 +0,0 @@
From 49f6e0e64accb5a1e6590bb08f7986fe7eaec2de Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Thu, 29 Oct 2020 10:08:09 +0100
Subject: [PATCH] Fix issue when ns_info cannot be retrieved for NVDimm
namespace
If we don't skip this part the uncaught exception will raise because we
are
trying to concatenate string and None types.
This is happening when NVDIMM namespace is set to DEVDAX mode. In this
mode
there is no device to be returned so we will got None from blivet.
Resolves: rhbz#1891827
(cherry picked from commit 6afc375b164a802e26802ec4ba54d3446c078091)
---
pyanaconda/modules/storage/nvdimm/nvdimm.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/modules/storage/nvdimm/nvdimm.py b/pyanaconda/modules/storage/nvdimm/nvdimm.py
index 4476dd1..5b9c9dc 100644
--- a/pyanaconda/modules/storage/nvdimm/nvdimm.py
+++ b/pyanaconda/modules/storage/nvdimm/nvdimm.py
@@ -101,6 +101,12 @@ class NVDIMMModule(KickstartBaseModule):
devices_to_ignore = set()
for ns_name, ns_info in nvdimm.namespaces.items():
+ # this is happening when namespace is set to DEVDAX mode - block device is not present
+ if ns_info.blockdev is None:
+ log.debug("%s will be skipped - NVDIMM namespace block device information "
+ "can't be retrieved", ns_name)
+ continue
+
info = udev.get_device(device_node="/dev/" + ns_info.blockdev)
if info and udev.device_get_format(info) == "iso9660":
@@ -116,8 +122,7 @@ class NVDIMMModule(KickstartBaseModule):
else:
continue
- if ns_info.blockdev:
- devices_to_ignore.add(ns_info.blockdev)
+ devices_to_ignore.add(ns_info.blockdev)
return devices_to_ignore

View File

@ -1,40 +0,0 @@
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

@ -1,32 +0,0 @@
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

@ -1,48 +0,0 @@
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

@ -1,41 +0,0 @@
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

@ -1,40 +0,0 @@
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

@ -1,41 +0,0 @@
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

@ -1,34 +0,0 @@
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

@ -1,36 +0,0 @@
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

@ -1,36 +0,0 @@
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

@ -1,101 +0,0 @@
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

@ -1,101 +0,0 @@
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

@ -1,40 +0,0 @@
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

@ -1,291 +0,0 @@
From 39d3a894411e3069cdb14354509153028a48e6c5 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Wed, 2 Sep 2020 13:40:36 +0200
Subject: [PATCH] Propagate a lazy proxy of the storage model
The storage model for the partitioning modules should be always created lazily.
When we reset the partitioning, the new model shouldn't be created until we try
to work with it. Then we create a new copy of the storage model, hide disks that
are not selected and possibly initialize empty disks.
There is a problem with modules that need to be able to work with the same copy
of the storage model as the partitioning modules. At this moment, it is only the
device tree module. The suggested solution is to propagate a lazy proxy of the
storage model. It will not trigger the creation of the copy until we try to
access the attributes of the storage model.
Basically, the device tree module always gets the storage model on demand from
the storage property of the partitioning module.
Related: rhbz#1868577
---
pyanaconda/core/util.py | 37 +++++++
.../modules/storage/partitioning/base.py | 28 ++++--
.../module_part_interactive_test.py | 18 ++++
tests/nosetests/pyanaconda_tests/util_test.py | 97 ++++++++++++++++++-
4 files changed, 170 insertions(+), 10 deletions(-)
diff --git a/pyanaconda/core/util.py b/pyanaconda/core/util.py
index 4615f9fd8..60b6ff310 100644
--- a/pyanaconda/core/util.py
+++ b/pyanaconda/core/util.py
@@ -1431,3 +1431,40 @@ def is_smt_enabled():
except (IOError, ValueError):
log.warning("Failed to detect SMT.")
return False
+
+
+class LazyObject(object):
+ """The lazy object."""
+
+ def __init__(self, getter):
+ """Create a proxy of an object.
+
+ The object might not exist until we call the given
+ function. The function is called only when we try
+ to access the attributes of the object.
+
+ The returned object is not cached in this class.
+ We call the function every time.
+
+ :param getter: a function that returns the object
+ """
+ self._getter = getter
+
+ @property
+ def _object(self):
+ return self._getter()
+
+ def __eq__(self, other):
+ return self._object == other
+
+ def __hash__(self):
+ return self._object.__hash__()
+
+ def __getattr__(self, name):
+ return getattr(self._object, name)
+
+ def __setattr__(self, name, value):
+ if name in ("_getter", ):
+ return super().__setattr__(name, value)
+
+ return setattr(self._object, name, value)
diff --git a/pyanaconda/modules/storage/partitioning/base.py b/pyanaconda/modules/storage/partitioning/base.py
index 989fa0a7b..c8b4b95ac 100644
--- a/pyanaconda/modules/storage/partitioning/base.py
+++ b/pyanaconda/modules/storage/partitioning/base.py
@@ -17,12 +17,13 @@
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
-from abc import abstractmethod, abstractproperty
+from abc import abstractmethod
from blivet.devices import PartitionDevice, TmpFSDevice, LVMLogicalVolumeDevice, \
LVMVolumeGroupDevice, MDRaidArrayDevice, BTRFSDevice
from dasbus.server.publishable import Publishable
+from pyanaconda.core.util import LazyObject
from pyanaconda.modules.common.base.base import KickstartBaseModule
from pyanaconda.modules.common.errors.storage import UnavailableStorageError
from pyanaconda.anaconda_loggers import get_module_logger
@@ -45,7 +46,8 @@ class PartitioningModule(KickstartBaseModule, Publishable):
self._selected_disks = []
self._device_tree_module = None
- @abstractproperty
+ @property
+ @abstractmethod
def partitioning_method(self):
"""Type of the partitioning method."""
return None
@@ -67,8 +69,22 @@ class PartitioningModule(KickstartBaseModule, Publishable):
return self._storage_playground
+ @property
+ def lazy_storage(self):
+ """The lazy storage model.
+
+ Provides a lazy access to the storage model. This property will not
+ trigger a creation of the storage playground. The playground will be
+ created on the first access of the storage attributes.
+ """
+ return LazyObject(lambda: self.storage)
+
def _create_storage_playground(self):
"""Prepare the current storage model for partitioning."""
+ log.debug(
+ "Creating a new storage playground for %s with "
+ "selected disks %s.", self, self._selected_disks
+ )
storage = self._current_storage.copy()
storage.select_disks(self._selected_disks)
return storage
@@ -77,16 +93,10 @@ class PartitioningModule(KickstartBaseModule, Publishable):
"""Update the current storage."""
self._current_storage = storage
- if self._device_tree_module:
- self._device_tree_module.on_storage_changed(self.storage)
-
def on_partitioning_reset(self):
"""Drop the storage playground."""
self._storage_playground = None
- if self._device_tree_module:
- self._device_tree_module.on_storage_changed(self.storage)
-
def on_selected_disks_changed(self, selection):
"""Keep the current disk selection."""
self._selected_disks = selection
@@ -100,7 +110,7 @@ class PartitioningModule(KickstartBaseModule, Publishable):
if not module:
module = self._create_device_tree()
- module.on_storage_changed(self.storage)
+ module.on_storage_changed(self.lazy_storage)
self._device_tree_module = module
return module
diff --git a/tests/nosetests/pyanaconda_tests/module_part_interactive_test.py b/tests/nosetests/pyanaconda_tests/module_part_interactive_test.py
index 13d33feab..32fe589b7 100644
--- a/tests/nosetests/pyanaconda_tests/module_part_interactive_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_part_interactive_test.py
@@ -71,6 +71,24 @@ class InteractivePartitioningInterfaceTestCase(unittest.TestCase):
"""Test Method property."""
self.assertEqual(self.interface.PartitioningMethod, PARTITIONING_METHOD_INTERACTIVE)
+ @patch_dbus_publish_object
+ def lazy_storage_test(self, publisher):
+ """Make sure that the storage playground is created lazily."""
+ self.module.on_storage_changed(create_storage())
+
+ device_tree_module = self.module.get_device_tree()
+ self.assertIsNone(self.module._storage_playground)
+
+ device_tree_module.get_disks()
+ self.assertIsNotNone(self.module._storage_playground)
+
+ self.module.on_partitioning_reset()
+ self.module.on_storage_changed(create_storage())
+ self.assertIsNone(self.module._storage_playground)
+
+ device_tree_module.get_actions()
+ self.assertIsNotNone(self.module._storage_playground)
+
@patch_dbus_publish_object
def get_device_tree_test(self, publisher):
"""Test GetDeviceTree."""
diff --git a/tests/nosetests/pyanaconda_tests/util_test.py b/tests/nosetests/pyanaconda_tests/util_test.py
index 1da8362dc..76f1c4465 100644
--- a/tests/nosetests/pyanaconda_tests/util_test.py
+++ b/tests/nosetests/pyanaconda_tests/util_test.py
@@ -29,7 +29,7 @@ from unittest.mock import Mock, patch
from pyanaconda.errors import ExitError
from pyanaconda.core.process_watchers import WatchProcesses
from pyanaconda.core import util
-from pyanaconda.core.util import synchronized
+from pyanaconda.core.util import synchronized, LazyObject
from pyanaconda.core.configuration.anaconda import conf
from timer import timer
@@ -829,3 +829,98 @@ class MiscTests(unittest.TestCase):
)
self.assertEqual(get_anaconda_version_string(), "1.0")
self.assertEqual(get_anaconda_version_string(build_time_version=True), "1.0-1")
+
+
+class LazyObjectTestCase(unittest.TestCase):
+
+ class Object(object):
+
+ def __init__(self):
+ self._x = 0
+
+ @property
+ def x(self):
+ return self._x
+
+ @x.setter
+ def x(self, value):
+ self._x = value
+
+ def f(self, value):
+ self._x += value
+
+ def setUp(self):
+ self._obj = None
+
+ @property
+ def obj(self):
+ if not self._obj:
+ self._obj = self.Object()
+
+ return self._obj
+
+ @property
+ def lazy_obj(self):
+ return LazyObject(lambda: self.obj)
+
+ def get_set_test(self):
+ self.assertIsNotNone(self.lazy_obj)
+ self.assertIsNone(self._obj)
+
+ self.assertEqual(self.lazy_obj.x, 0)
+ self.assertIsNotNone(self._obj)
+
+ self.obj.x = -10
+ self.assertEqual(self.obj.x, -10)
+ self.assertEqual(self.lazy_obj.x, -10)
+
+ self.lazy_obj.x = 10
+ self.assertEqual(self.obj.x, 10)
+ self.assertEqual(self.lazy_obj.x, 10)
+
+ self.lazy_obj.f(90)
+ self.assertEqual(self.obj.x, 100)
+ self.assertEqual(self.lazy_obj.x, 100)
+
+ def eq_test(self):
+ a = object()
+ lazy_a1 = LazyObject(lambda: a)
+ lazy_a2 = LazyObject(lambda: a)
+
+ self.assertEqual(a, lazy_a1)
+ self.assertEqual(lazy_a1, a)
+
+ self.assertEqual(a, lazy_a2)
+ self.assertEqual(lazy_a2, a)
+
+ self.assertEqual(lazy_a1, lazy_a2)
+ self.assertEqual(lazy_a2, lazy_a1)
+
+ self.assertEqual(lazy_a1, lazy_a1)
+ self.assertEqual(lazy_a2, lazy_a2)
+
+ def neq_test(self):
+ a = object()
+ lazy_a = LazyObject(lambda: a)
+
+ b = object()
+ lazy_b = LazyObject(lambda: b)
+
+ self.assertNotEqual(b, lazy_a)
+ self.assertNotEqual(lazy_a, b)
+
+ self.assertNotEqual(lazy_a, lazy_b)
+ self.assertNotEqual(lazy_b, lazy_a)
+
+ def hash_test(self):
+ a = object()
+ lazy_a1 = LazyObject(lambda: a)
+ lazy_a2 = LazyObject(lambda: a)
+
+ b = object()
+ lazy_b1 = LazyObject(lambda: b)
+ lazy_b2 = LazyObject(lambda: b)
+
+ self.assertEqual({a, lazy_a1, lazy_a2}, {a})
+ self.assertEqual({b, lazy_b1, lazy_b2}, {b})
+ self.assertEqual({lazy_a1, lazy_b2}, {a, b})

View File

@ -1,32 +0,0 @@
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

@ -1,29 +0,0 @@
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

@ -1,120 +0,0 @@
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

@ -1,128 +0,0 @@
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

@ -1,31 +0,0 @@
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

@ -1,134 +0,0 @@
From 8032e0a9eae5093e1246af4d3906ad65d5aade12 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Wed, 12 Aug 2020 12:38:27 +0200
Subject: [PATCH] Reset the state of the custom partitioning spoke
We should reset the state of the custom partitioning spoke after every user
interaction. If we don't reset the _back_already_clicked attribute, the final
check of the storage configuration might be skipped and the status of the
storage spoke might show an error from the previously failed check.
(cherry picked from commit 0aa3abfb6fb137746a393588ff9315807a65f7b9)
---
pyanaconda/ui/gui/spokes/custom_storage.py | 28 +++++++++++-----------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom_storage.py b/pyanaconda/ui/gui/spokes/custom_storage.py
index a5e568f..6c9f6f6 100644
--- a/pyanaconda/ui/gui/spokes/custom_storage.py
+++ b/pyanaconda/ui/gui/spokes/custom_storage.py
@@ -280,7 +280,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
self._storage_module.ResetPartitioning()
def refresh(self):
- self.clear_errors()
+ self.reset_state()
NormalSpoke.refresh(self)
# Make sure the storage spoke execute method has finished before we
@@ -294,8 +294,6 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
self._partitioning = create_partitioning(PARTITIONING_METHOD_INTERACTIVE)
self._device_tree = STORAGE.get_proxy(self._partitioning.GetDeviceTree())
- self._back_already_clicked = False
-
# Get the name of the new installation.
self._os_name = self._device_tree.GenerateSystemName()
@@ -554,8 +552,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
# just-removed device
return
- self.clear_errors()
- self._back_already_clicked = False
+ self.reset_state()
log.debug("Saving the right side for device: %s", device_name)
@@ -979,7 +976,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
def on_add_clicked(self, button):
# Clear any existing errors
- self.clear_errors()
+ self.reset_state()
# Save anything from the currently displayed mount point.
self._save_right_side(self._accordion.current_selector)
@@ -996,8 +993,6 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
dialog.window.destroy()
return
- self._back_already_clicked = False
-
# Gather data about the added mount point.
request = DeviceFactoryRequest()
request.mount_point = dialog.mount_point
@@ -1006,7 +1001,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
request.disks = self._selected_disks
# Clear errors and try to add the mountpoint/device.
- self.clear_errors()
+ self.reset_state()
try:
self._device_tree.AddDevice(
@@ -1065,7 +1060,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
return
# Remove selected items.
- self.clear_errors()
+ self.reset_state()
try:
self._remove_selected_devices()
@@ -1187,7 +1182,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
# disk set management happens through container edit on RHS
return
- self.clear_errors()
+ self.reset_state()
dialog = DisksDialog(
self.data,
@@ -1448,7 +1443,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
Note: There are never any non-existent devices around when this runs.
"""
- self.clear_errors()
+ self.reset_state()
# Create the partitioning request.
request = PartitioningRequest()
@@ -1762,6 +1757,10 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
self._error = None
self.clear_info()
+ def reset_state(self):
+ self.clear_errors()
+ self._back_already_clicked = False
+
# This callback is for the button that just resets the UI to anaconda's
# current understanding of the disk layout.
def on_reset_clicked(self, *args):
@@ -1846,7 +1845,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
return
# Clear any existing errors
- self.clear_errors()
+ self.reset_state()
# Save anything from the currently displayed mount point.
self._save_right_side(selector)
@@ -1861,7 +1860,8 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
if not selector:
return
- self.clear_errors()
+ self.reset_state()
+
device_name = selector.device_name
passphrase = self._passphraseEntry.get_text()
--
2.23.0

View File

@ -1,28 +0,0 @@
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

@ -1,86 +0,0 @@
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

@ -1,59 +0,0 @@
From 65b176260404087f625132697c1e299db0b0163e Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Wed, 8 Jul 2020 19:07:54 +0200
Subject: [PATCH] Schedule timed actions with the right selector (#1851647)
The timed actions of the Custom Partitioning spoke should be scheduled with
the specified selector. Otherwise, the action will use the current selector
that might be different.
Resolves: rhbz#1851647
---
pyanaconda/ui/gui/spokes/custom_storage.py | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom_storage.py b/pyanaconda/ui/gui/spokes/custom_storage.py
index b89866c..a5e568f 100644
--- a/pyanaconda/ui/gui/spokes/custom_storage.py
+++ b/pyanaconda/ui/gui/spokes/custom_storage.py
@@ -1836,21 +1836,33 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
dlg.run()
dlg.destroy()
- @timed_action(delay=50, threshold=100)
def on_update_settings_clicked(self, button):
+ self._update_settings(self._accordion.current_selector)
+
+ @timed_action(delay=50, threshold=100)
+ def _update_settings(self, selector):
""" call _save_right_side, then, perhaps, populate_right_side. """
+ if not selector:
+ return
+
# Clear any existing errors
self.clear_errors()
# Save anything from the currently displayed mount point.
- self._save_right_side(self._accordion.current_selector)
+ self._save_right_side(selector)
self._applyButton.set_sensitive(False)
- @timed_action(delay=50, threshold=100)
def on_unlock_clicked(self, *args):
+ self._unlock_device(self._accordion.current_selector)
+
+ @timed_action(delay=50, threshold=100)
+ def _unlock_device(self, selector):
""" try to open the luks device, populate, then call _do_refresh. """
+ if not selector:
+ return
+
self.clear_errors()
- device_name = self._accordion.current_selector.device_name
+ device_name = selector.device_name
passphrase = self._passphraseEntry.get_text()
log.info("Trying to unlock device %s.", device_name)
--
2.23.0

View File

@ -1,96 +0,0 @@
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

@ -1,26 +0,0 @@
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

@ -1,52 +0,0 @@
From d1bb8d1d49de9668e8afc697aef8166d6c5bfabe Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Fri, 25 Sep 2020 23:16:04 +0800
Subject: [PATCH] add dnf transaction timeout
---
pyanaconda/core/constants.py | 3 +++
pyanaconda/payload/dnf/payload.py | 7 ++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/core/constants.py b/pyanaconda/core/constants.py
index 0e4cc15..607f96c 100644
--- a/pyanaconda/core/constants.py
+++ b/pyanaconda/core/constants.py
@@ -448,6 +448,9 @@ URL_TYPE_BASEURL = "BASEURL"
URL_TYPE_MIRRORLIST = "MIRRORLIST"
URL_TYPE_METALINK = "METALINK"
+#DNF trasactions timeout
+DNF_TRANSACTIONS_TIMEOUT = 1800
+
# The default source for the DNF payload.
DNF_DEFAULT_SOURCE_TYPE = SOURCE_TYPE_CLOSEST_MIRROR
diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py
index f927208..08963cc 100644
--- a/pyanaconda/payload/dnf/payload.py
+++ b/pyanaconda/payload/dnf/payload.py
@@ -19,6 +19,7 @@
import configparser
import functools
import multiprocessing
+import queue
import os
import shutil
import sys
@@ -1356,7 +1357,11 @@ class DNFPayload(Payload):
if errors.errorHandler.cb(exc) == errors.ERROR_RAISE:
log.error("Installation failed: %r", exc)
go_to_failure_limbo()
- (token, msg) = queue_instance.get()
+ try:
+ (token, msg) = queue_instance.get(True, constants.DNF_TRANSACTIONS_TIMEOUT)
+ except queue.Empty:
+ msg = ("Payload error - DNF installation has timeouted")
+ raise PayloadError(msg)
process.join()
# Don't close the mother base here, because we still need it.
--
2.23.0

View File

@ -1,58 +0,0 @@
From 5dc9b2ee4dde7b6deb477b581759c5f76dcb87b5 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Fri, 19 Jun 2020 15:57:57 +0200
Subject: [PATCH] Add tests for verify_valid_installtree function (#1844287)
It's testing if repodata/repomd.xml file exists.
Related: rhbz#1844287
Related: rhbz#1849093
---
.../module_source_base_test.py | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/tests/nosetests/pyanaconda_tests/module_source_base_test.py b/tests/nosetests/pyanaconda_tests/module_source_base_test.py
index f58e2b1639..3ba40edf4c 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_base_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_base_test.py
@@ -16,6 +16,8 @@
# Red Hat, Inc.
#
import unittest
+from pathlib import Path
+from tempfile import TemporaryDirectory
from unittest.mock import patch
from pyanaconda.core.constants import INSTALL_TREE
@@ -23,7 +25,8 @@
from pyanaconda.modules.payloads.constants import SourceType
from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask, TearDownMountTask
from pyanaconda.modules.payloads.source.source_base import MountingSourceMixin
-from pyanaconda.modules.payloads.source.utils import find_and_mount_iso_image
+from pyanaconda.modules.payloads.source.utils import find_and_mount_iso_image, \
+ verify_valid_installtree
mount_location = "/some/dir"
@@ -184,3 +187,21 @@ def find_and_mount_iso_image_fail_mount_test(self,
)
self.assertEqual(iso_name, "")
+
+ def verify_valid_installtree_success_test(self):
+ """Test verify_valid_installtree functionality success."""
+ with TemporaryDirectory() as tmp:
+ repodir_path = Path(tmp, "repodata")
+ repodir_path.mkdir()
+ repomd_path = Path(repodir_path, "repomd.xml")
+ repomd_path.write_text("This is a cool repomd file!")
+
+ self.assertTrue(verify_valid_installtree(tmp))
+
+ def verify_valid_installtree_failed_test(self):
+ """Test verify_valid_installtree functionality failed."""
+ with TemporaryDirectory() as tmp:
+ repodir_path = Path(tmp, "repodata")
+ repodir_path.mkdir()
+
+ self.assertFalse(verify_valid_installtree(tmp))

View File

@ -1,165 +0,0 @@
From d7398bef83d12281fe95a7964b990b07bc56003b Mon Sep 17 00:00:00 2001
From: Qiumiao Zhang <zhangqiumiao1@huawei.com>
Date: Tue, 23 Aug 2022 17:32:01 +0800
Subject: [PATCH] change the startup mode of do_transaction sub proces
---
pyanaconda/payload/dnf/payload.py | 39 +++++++++++++++++++--
pyanaconda/payload/dnf/utils.py | 58 ++++++++++++++++++++++++++++++-
2 files changed, 93 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py
index 45003da..e473a68 100644
--- a/pyanaconda/payload/dnf/payload.py
+++ b/pyanaconda/payload/dnf/payload.py
@@ -89,6 +89,9 @@ log = get_packaging_logger()
USER_AGENT = "%s (anaconda)/%s" % (productName, productVersion)
+g_include_list = []
+g_exclude_list = []
+
__all__ = ["DNFPayload"]
@@ -530,6 +533,10 @@ class DNFPayload(Payload):
log.debug("transaction exclude list")
log.debug(exclude_list)
+ global g_include_list, g_exclude_list
+ g_include_list.extend(include_list)
+ g_exclude_list.extend(exclude_list)
+
# feed it to DNF
try:
# FIXME: Remove self._base.conf.strict workaround when bz1761518 is fixed
@@ -1327,9 +1334,35 @@ class DNFPayload(Payload):
pre_msg = (N_("Preparing transaction from installation source"))
progress_message(pre_msg)
- queue_instance = multiprocessing.Queue()
- process = multiprocessing.Process(target=do_transaction,
- args=(self._base, queue_instance))
+ repos = dict()
+ for repo in self._base.repos.iter_enabled():
+ t_repo = dict()
+ repo_agrs = dict()
+ t_repo['baseurl'] = list(repo.baseurl)
+ repo_agrs['sslverify'] = repo.sslverify
+ repo_agrs['proxy'] = repo.proxy
+ t_repo['repo_agrs'] = repo_agrs
+ repos[repo.id] = t_repo
+
+ global g_include_list, g_exclude_list
+
+ ctx = multiprocessing.get_context('spawn')
+ queue_instance = ctx.Queue()
+ process = ctx.Process(target=do_transaction,
+ args=(queue_instance, repos,
+ self._base.conf.releasever,
+ self._base.conf.installroot,
+ self._base.conf.substitutions,
+ self._base.conf.multilib_policy,
+ self._base.conf.timeout,
+ self._base.conf.retries,
+ self._download_location,
+ self._base.conf.proxy,
+ self._base.conf.proxy_username,
+ self._base.conf.proxy_password,
+ g_include_list,
+ g_exclude_list))
+
process.start()
(token, msg) = queue_instance.get()
# When the installation works correctly it will get 'install' updates
diff --git a/pyanaconda/payload/dnf/utils.py b/pyanaconda/payload/dnf/utils.py
index dfac5c9..23a11fd 100644
--- a/pyanaconda/payload/dnf/utils.py
+++ b/pyanaconda/payload/dnf/utils.py
@@ -18,6 +18,7 @@
import os
import operator
import time
+import dnf
from blivet.size import Size
@@ -27,6 +28,7 @@ from pyanaconda.progress import progressQ
from pyanaconda.core import util
from pyanaconda.core.configuration.anaconda import conf
from pyanaconda.product import productName, productVersion
+from pyanaconda.flags import flags
log = get_packaging_logger()
@@ -121,12 +123,66 @@ def pick_mount_point(df, download_size, install_size, download_only):
return sorted_mpoints[0][0]
-def do_transaction(base, queue_instance):
+def update_conf(conf, substitutions, releasever, installroot, multilib_policy, timeout, retries):
+ conf.cachedir = DNF_CACHE_DIR
+ conf.pluginconfpath = DNF_PLUGINCONF_DIR
+ conf.logdir = '/tmp/'
+ # enable depsolver debugging if in debug mode
+ conf.debug_solver = flags.debug
+
+ conf.substitutions = substitutions
+ conf.releasever = releasever
+ conf.installroot = installroot
+ conf.prepend_installroot('persistdir')
+ conf.multilib_policy = multilib_policy
+ conf.timeout = timeout
+ conf.retries = retries
+
+ conf.substitutions.update_from_etc(conf.installroot)
+
+ conf.reposdir = REPO_DIRS
+
+
+def update_proxy(conf, proxy, proxy_username, proxy_password):
+ conf.proxy = proxy
+ conf.proxy_username = proxy_username
+ conf.proxy_password = proxy_password
+
+
+def update_depdency(base, include_list, exclude_list):
+ base.fill_sack()
+ base.read_comps()
+ base.install_specs(install=include_list, exclude=exclude_list)
+ base.resolve()
+
+
+def do_transaction(queue_instance, repos, releasever, installroot, substitutions,
+ multilib_policy, timeout, retries, pkgdir, proxy,
+ proxy_username, proxy_password, include_list, exclude_list):
# Execute the DNF transaction and catch any errors. An error doesn't
# always raise a BaseException, so presence of 'quit' without a preceeding
# 'post' message also indicates a problem.
try:
display = TransactionProgress(queue_instance)
+ # We create new dnf base obj, and update it from parent process
+ base = dnf.Base()
+ conf = base.conf
+
+ update_conf(conf, substitutions, releasever, installroot, multilib_policy, timeout, retries)
+ update_proxy(conf, proxy, proxy_username, proxy_password)
+
+ queue_instance.put(('log', 'start to setup repo.'))
+ for (key, repo) in repos.items():
+ base.repos.add_new_repo(key, conf, repo['baseurl'], **repo['repo_agrs'])
+ base.repos[key].enable()
+
+ for repo in base.repos.iter_enabled():
+ repo.pkgdir = pkgdir
+
+ queue_instance.put(('log', 'start to update depdency.'))
+ update_depdency(base, include_list, exclude_list)
+
+ queue_instance.put(('log', 'start to transaction.'))
base.do_transaction(display=display)
exit_reason = "DNF quit"
except BaseException as e: # pylint: disable=broad-except
--
2.27.0

View File

@ -1,84 +0,0 @@
From 5be52e7c3122634a1d7b011922356788315e22ec Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Sun, 25 Apr 2021 22:27:18 +0800
Subject: [PATCH] patch
---
pyanaconda/core/constants.py | 1 +
pyanaconda/modules/payloads/source/cdrom/initialization.py | 3 ++-
pyanaconda/modules/payloads/source/utils.py | 4 ++--
tests/nosetests/pyanaconda_tests/module_source_base_test.py | 3 +--
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/core/constants.py b/pyanaconda/core/constants.py
index 4fc4b80..4724dc1 100644
--- a/pyanaconda/core/constants.py
+++ b/pyanaconda/core/constants.py
@@ -53,6 +53,7 @@ DRACUT_ISODIR = "/run/install/source"
ISO_DIR = MOUNT_DIR + "/isodir"
IMAGE_DIR = MOUNT_DIR + "/image"
INSTALL_TREE = MOUNT_DIR + "/source"
+SOURCES_DIR = MOUNT_DIR + "/sources"
BASE_REPO_NAME = "anaconda"
# Get list of repo names witch should be used as base repo
diff --git a/pyanaconda/modules/payloads/source/cdrom/initialization.py b/pyanaconda/modules/payloads/source/cdrom/initialization.py
index 7fc38fc..95303ea 100644
--- a/pyanaconda/modules/payloads/source/cdrom/initialization.py
+++ b/pyanaconda/modules/payloads/source/cdrom/initialization.py
@@ -98,7 +98,8 @@ class SetUpCdromSourceTask(SetUpMountTask):
try:
device_data = DeviceData.from_structure(device_tree.GetDeviceData(dev_name))
mount(device_data.path, self._target_mount, "iso9660", "ro")
- except PayloadSetupError:
+ except PayloadSetupError as e:
+ log.debug("Failed to mount %s: %s", dev_name, str(e))
continue
if is_valid_install_disk(self._target_mount):
diff --git a/pyanaconda/modules/payloads/source/utils.py b/pyanaconda/modules/payloads/source/utils.py
index a8e2f49..2dc4062 100644
--- a/pyanaconda/modules/payloads/source/utils.py
+++ b/pyanaconda/modules/payloads/source/utils.py
@@ -20,7 +20,7 @@ import os.path
from blivet.arch import get_arch
from blivet.util import mount
-from pyanaconda.core.constants import INSTALL_TREE
+from pyanaconda.core.constants import SOURCES_DIR
from pyanaconda.core.storage import device_matches
from pyanaconda.core.util import join_paths
from pyanaconda.payload.image import find_first_iso_image
@@ -177,7 +177,7 @@ class MountPointGenerator:
:rtype: str
"""
path = "{}/mount-{:0>4}-{}".format(
- INSTALL_TREE,
+ SOURCES_DIR,
cls._counter,
suffix
)
diff --git a/tests/nosetests/pyanaconda_tests/module_source_base_test.py b/tests/nosetests/pyanaconda_tests/module_source_base_test.py
index c9f00fa..2d1a1da 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_base_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_base_test.py
@@ -20,7 +20,6 @@ from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import patch
-from pyanaconda.core.constants import INSTALL_TREE
from pyanaconda.modules.common.errors.payload import SourceSetupError, SourceTearDownError
from pyanaconda.modules.payloads.constants import SourceType
from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask, TearDownMountTask
@@ -55,7 +54,7 @@ class MountingSourceMixinTestCase(unittest.TestCase):
def counter_test(self):
"""Mount path in mount source base gets incremental numbers."""
module = DummyMountingSourceSubclass()
- self.assertTrue(module.mount_point.startswith(INSTALL_TREE + "/mount-"))
+ self.assertTrue(module.mount_point.startswith("/run/install/sources/mount-"))
first_counter = int(module.mount_point.split("-")[1])
module = DummyMountingSourceSubclass()
--
2.27.0

View File

@ -1,54 +0,0 @@
From 6cee8e5a59a9c424d2bc79b5474a749c4f786b40 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Fri, 19 Jun 2020 14:12:21 +0200
Subject: [PATCH] Do not test if repo is valid based on .treeinfo file
(#1844287)
Not all repositories need to have .treeinfo file. When it is not a compose but
only a third party repo it's probably created by just running createrepo_c which
does not create this file. We do not want to disable these repositories.
So instead check that repodata/repomd.xml file is present. Based on my
discussion with DNF/RPM developers it seems like the best approach.
Resolves: rhbz#1844287
Resolves: rhbz#1849093
Reported-by: Adam Williamson <awilliam@redhat.com>
---
pyanaconda/payload/image.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/pyanaconda/payload/image.py b/pyanaconda/payload/image.py
index b76b33db40..4b6d0c7bb9 100644
--- a/pyanaconda/payload/image.py
+++ b/pyanaconda/payload/image.py
@@ -28,6 +28,7 @@
from blivet.size import Size
from pyanaconda import isys
+from pyanaconda.core.util import join_paths
from pyanaconda.errors import errorHandler, ERROR_RAISE, InvalidImageSizeError, MissingImageError
from pyanaconda.modules.common.constants.objects import DEVICE_TREE
from pyanaconda.modules.common.constants.services import STORAGE
@@ -129,16 +130,15 @@ def find_first_iso_image(path, mount_path="/mnt/install/cdimage"):
def verify_valid_installtree(path):
- """Check if the given path is a valid installtree repository
+ """Check if the given path is a valid installtree repository.
:param str path: install tree path
:returns: True if repository is valid false otherwise
:rtype: bool
"""
- # TODO: This can be enhanced to check for repodata folder.
- if os.path.exists(os.path.join(path, ".treeinfo")):
- return True
- elif os.path.exists(os.path.join(path, "treeinfo")):
+ repomd_path = join_paths(path, "repodata/repomd.xml")
+
+ if os.path.exists(repomd_path) and os.path.isfile(repomd_path):
return True
return False

View File

@ -1,29 +0,0 @@
From 19264b192083d5cf38750a9cef0ec0a55eea3cfe Mon Sep 17 00:00:00 2001
From: zhangqiumiao <zhangqiumiao1@huawei.com>
Date: Thu, 10 Sep 2020 14:59:14 +0800
Subject: [PATCH] bugfix fix password policy
---
data/interactive-defaults.ks | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/data/interactive-defaults.ks b/data/interactive-defaults.ks
index 0177cf9..7e43a39 100644
--- a/data/interactive-defaults.ks
+++ b/data/interactive-defaults.ks
@@ -4,9 +4,9 @@ firstboot --enable
%anaconda
# Default password policies
-pwpolicy root --notstrict --minlen=8 --minquality=1 --nochanges --notempty
-pwpolicy user --notstrict --minlen=8 --minquality=1 --nochanges --emptyok
-pwpolicy luks --notstrict --minlen=8 --minquality=1 --nochanges --notempty
+pwpolicy root --strict --minlen=8 --minquality=1 --nochanges --notempty
+pwpolicy user --strict --minlen=8 --minquality=1 --nochanges --emptyok
+pwpolicy luks --strict --minlen=8 --minquality=1 --nochanges --notempty
# NOTE: This applies only to *fully* interactive installations, partial kickstart
# installations use defaults specified in pyanaconda/pwpolicy.py.
# Automated kickstart installs simply ignore the password policy as the policy
--
1.8.3.1

View File

@ -1,24 +0,0 @@
From 3e4a2bd7fd23c458a96b387c4df9f4abb984d59f Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Thu, 18 Jun 2020 22:30:28 +0800
Subject: [PATCH] bugfix logo display in low screen resolution
---
data/anaconda-gtk.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/data/anaconda-gtk.css b/data/anaconda-gtk.css
index c47bb87..7b7166b 100644
--- a/data/anaconda-gtk.css
+++ b/data/anaconda-gtk.css
@@ -113,6 +113,7 @@ infobar.error {
.logo {
background-image: url('/usr/share/anaconda/pixmaps/sidebar-logo.png');
background-position: 50% 20px;
+ background-size: 90%;
background-repeat: no-repeat;
background-color: transparent;
}
--
2.23.0

View File

@ -1,107 +0,0 @@
From fea8f2db7594482457f1a7f7aebb7ccac4505fa5 Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Fri, 19 Jun 2020 15:36:37 +0200
Subject: [PATCH] Move verify_valid_installtree to source module utils
(#1844287)
It's used only by modules now. We can safely move it.
Related: rhbz#1844287
Related: rhbz#1849093
---
.../payloads/source/harddrive/initialization.py | 3 +--
.../payloads/source/nfs/initialization.py | 4 ++--
pyanaconda/modules/payloads/source/utils.py | 15 +++++++++++++++
pyanaconda/payload/image.py | 16 ----------------
4 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/pyanaconda/modules/payloads/source/harddrive/initialization.py b/pyanaconda/modules/payloads/source/harddrive/initialization.py
index 38d777adca..ed77db6bc9 100644
--- a/pyanaconda/modules/payloads/source/harddrive/initialization.py
+++ b/pyanaconda/modules/payloads/source/harddrive/initialization.py
@@ -22,8 +22,7 @@
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_device, \
- find_and_mount_iso_image
-from pyanaconda.payload.image import verify_valid_installtree
+ find_and_mount_iso_image, verify_valid_installtree
from pyanaconda.payload.utils import unmount
from pyanaconda.anaconda_loggers import get_module_logger
diff --git a/pyanaconda/modules/payloads/source/nfs/initialization.py b/pyanaconda/modules/payloads/source/nfs/initialization.py
index 00112c3ecb..56e95060c6 100644
--- a/pyanaconda/modules/payloads/source/nfs/initialization.py
+++ b/pyanaconda/modules/payloads/source/nfs/initialization.py
@@ -21,9 +21,9 @@
from pyanaconda.core.payload import parse_nfs_url
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
+from pyanaconda.modules.payloads.source.utils import find_and_mount_iso_image, \
+ verify_valid_installtree
from pyanaconda.payload.errors import PayloadSetupError
-from pyanaconda.payload.image import verify_valid_installtree
from pyanaconda.payload.utils import mount, unmount
log = get_module_logger(__name__)
diff --git a/pyanaconda/modules/payloads/source/utils.py b/pyanaconda/modules/payloads/source/utils.py
index b9642a945c..ed9e5da49b 100644
--- a/pyanaconda/modules/payloads/source/utils.py
+++ b/pyanaconda/modules/payloads/source/utils.py
@@ -148,6 +148,21 @@ def _create_iso_path(path, iso_name):
return path
+def verify_valid_installtree(path):
+ """Check if the given path is a valid installtree repository.
+
+ :param str path: install tree path
+ :returns: True if repository is valid false otherwise
+ :rtype: bool
+ """
+ repomd_path = join_paths(path, "repodata/repomd.xml")
+
+ if os.path.exists(repomd_path) and os.path.isfile(repomd_path):
+ return True
+
+ return False
+
+
class MountPointGenerator:
_counter = 0
diff --git a/pyanaconda/payload/image.py b/pyanaconda/payload/image.py
index 4b6d0c7bb9..9401e29388 100644
--- a/pyanaconda/payload/image.py
+++ b/pyanaconda/payload/image.py
@@ -28,7 +28,6 @@
from blivet.size import Size
from pyanaconda import isys
-from pyanaconda.core.util import join_paths
from pyanaconda.errors import errorHandler, ERROR_RAISE, InvalidImageSizeError, MissingImageError
from pyanaconda.modules.common.constants.objects import DEVICE_TREE
from pyanaconda.modules.common.constants.services import STORAGE
@@ -129,21 +128,6 @@ def find_first_iso_image(path, mount_path="/mnt/install/cdimage"):
return None
-def verify_valid_installtree(path):
- """Check if the given path is a valid installtree repository.
-
- :param str path: install tree path
- :returns: True if repository is valid false otherwise
- :rtype: bool
- """
- repomd_path = join_paths(path, "repodata/repomd.xml")
-
- if os.path.exists(repomd_path) and os.path.isfile(repomd_path):
- return True
-
- return False
-
-
def _check_repodata(mount_path):
install_tree_meta = InstallTreeMetadata()
if not install_tree_meta.load_file(mount_path):

View File

@ -1,59 +0,0 @@
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

@ -1,41 +0,0 @@
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

@ -1,30 +0,0 @@
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

@ -1,58 +0,0 @@
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

@ -1,95 +0,0 @@
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

@ -1,29 +0,0 @@
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

View File

@ -1,38 +0,0 @@
From 1c7eed3607410d62324e368cc4fe9fb3f541cc48 Mon Sep 17 00:00:00 2001
From: eaglegai <eaglegai@163.com>
Date: Thu, 13 Jan 2022 18:49:29 +0800
Subject: [PATCH] remove flatpack support
---
pyanaconda/anaconda.py | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/pyanaconda/anaconda.py b/pyanaconda/anaconda.py
index 8c54011..c1108f2 100644
--- a/pyanaconda/anaconda.py
+++ b/pyanaconda/anaconda.py
@@ -28,7 +28,6 @@ from pyanaconda.core.constants import DisplayModes
from pyanaconda.core import constants
from pyanaconda.core.startup.dbus_launcher import AnacondaDBusLauncher
from pyanaconda.payload.source import SourceFactory, PayloadSourceTypeUnrecognized
-from pyanaconda.payload.flatpak import FlatpakPayload
from pyanaconda.anaconda_loggers import get_stdout_logger
stdoutLog = get_stdout_logger()
@@ -79,12 +78,8 @@ class Anaconda(object):
# class. If it doesn't give us one, fall back to the default.
if not self._payload:
if self.ksdata.ostreesetup.seen:
- if FlatpakPayload.is_available():
- from pyanaconda.payload.rpmostreepayload import RPMOSTreePayloadWithFlatpaks
- klass = RPMOSTreePayloadWithFlatpaks
- else:
- from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload
- klass = RPMOSTreePayload
+ from pyanaconda.payload.rpmostreepayload import RPMOSTreePayload
+ klass = RPMOSTreePayload
elif self.opts.liveinst:
from pyanaconda.payload.live import LiveOSPayload
klass = LiveOSPayload
--
2.30.0

View File

@ -1,228 +0,0 @@
From 92d8d9d3e39eae8e268e3aeff096105b441bbeae Mon Sep 17 00:00:00 2001
From: Jiri Konecny <jkonecny@redhat.com>
Date: Mon, 22 Jun 2020 13:12:53 +0200
Subject: [PATCH] Rename function for a simple check for DNF repository
It's more clear to use repository in the name than installtree.
Related: rhbz#1844287
Related: rhbz#1849093
---
.../payloads/source/harddrive/initialization.py | 4 ++--
.../modules/payloads/source/nfs/initialization.py | 4 ++--
pyanaconda/modules/payloads/source/utils.py | 6 +++---
.../pyanaconda_tests/module_source_base_test.py | 14 +++++++-------
.../module_source_harddrive_test.py | 12 ++++++------
.../pyanaconda_tests/module_source_nfs_test.py | 12 ++++++------
6 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/pyanaconda/modules/payloads/source/harddrive/initialization.py b/pyanaconda/modules/payloads/source/harddrive/initialization.py
index ed77db6bc9..004df4f034 100644
--- a/pyanaconda/modules/payloads/source/harddrive/initialization.py
+++ b/pyanaconda/modules/payloads/source/harddrive/initialization.py
@@ -22,7 +22,7 @@
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_device, \
- find_and_mount_iso_image, verify_valid_installtree
+ find_and_mount_iso_image, verify_valid_repository
from pyanaconda.payload.utils import unmount
from pyanaconda.anaconda_loggers import get_module_logger
@@ -82,7 +82,7 @@ def run(self):
log.debug("Using the ISO '%s' mounted at '%s'.", iso_name, self._iso_mount)
return SetupHardDriveResult(self._iso_mount, iso_name)
- if verify_valid_installtree(full_path_on_mounted_device):
+ if verify_valid_repository(full_path_on_mounted_device):
log.debug("Using the directory at '%s'.", full_path_on_mounted_device)
return SetupHardDriveResult(full_path_on_mounted_device, "")
diff --git a/pyanaconda/modules/payloads/source/nfs/initialization.py b/pyanaconda/modules/payloads/source/nfs/initialization.py
index 56e95060c6..99601bf325 100644
--- a/pyanaconda/modules/payloads/source/nfs/initialization.py
+++ b/pyanaconda/modules/payloads/source/nfs/initialization.py
@@ -22,7 +22,7 @@
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, \
- verify_valid_installtree
+ verify_valid_repository
from pyanaconda.payload.errors import PayloadSetupError
from pyanaconda.payload.utils import mount, unmount
@@ -65,7 +65,7 @@ def run(self):
log.debug("Using the ISO '%s' mounted at '%s'.", iso_name, self._iso_mount)
return self._iso_mount
- if verify_valid_installtree(self._device_mount):
+ if verify_valid_repository(self._device_mount):
log.debug("Using the directory at '%s'.", self._device_mount)
return self._device_mount
diff --git a/pyanaconda/modules/payloads/source/utils.py b/pyanaconda/modules/payloads/source/utils.py
index ed9e5da49b..84cdd33ca8 100644
--- a/pyanaconda/modules/payloads/source/utils.py
+++ b/pyanaconda/modules/payloads/source/utils.py
@@ -148,10 +148,10 @@ def _create_iso_path(path, iso_name):
return path
-def verify_valid_installtree(path):
- """Check if the given path is a valid installtree repository.
+def verify_valid_repository(path):
+ """Check if the given path is a valid repository.
- :param str path: install tree path
+ :param str path: path to the repository
:returns: True if repository is valid false otherwise
:rtype: bool
"""
diff --git a/tests/nosetests/pyanaconda_tests/module_source_base_test.py b/tests/nosetests/pyanaconda_tests/module_source_base_test.py
index 3ba40edf4c..c9f00fa4f5 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_base_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_base_test.py
@@ -26,7 +26,7 @@
from pyanaconda.modules.payloads.source.mount_tasks import SetUpMountTask, TearDownMountTask
from pyanaconda.modules.payloads.source.source_base import MountingSourceMixin
from pyanaconda.modules.payloads.source.utils import find_and_mount_iso_image, \
- verify_valid_installtree
+ verify_valid_repository
mount_location = "/some/dir"
@@ -188,20 +188,20 @@ def find_and_mount_iso_image_fail_mount_test(self,
self.assertEqual(iso_name, "")
- def verify_valid_installtree_success_test(self):
- """Test verify_valid_installtree functionality success."""
+ def verify_valid_repository_success_test(self):
+ """Test verify_valid_repository functionality success."""
with TemporaryDirectory() as tmp:
repodir_path = Path(tmp, "repodata")
repodir_path.mkdir()
repomd_path = Path(repodir_path, "repomd.xml")
repomd_path.write_text("This is a cool repomd file!")
- self.assertTrue(verify_valid_installtree(tmp))
+ self.assertTrue(verify_valid_repository(tmp))
- def verify_valid_installtree_failed_test(self):
- """Test verify_valid_installtree functionality failed."""
+ def verify_valid_repository_failed_test(self):
+ """Test verify_valid_repository functionality failed."""
with TemporaryDirectory() as tmp:
repodir_path = Path(tmp, "repodata")
repodir_path.mkdir()
- self.assertFalse(verify_valid_installtree(tmp))
+ self.assertFalse(verify_valid_repository(tmp))
diff --git a/tests/nosetests/pyanaconda_tests/module_source_harddrive_test.py b/tests/nosetests/pyanaconda_tests/module_source_harddrive_test.py
index dff84b6d19..99be32fa1f 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_harddrive_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_harddrive_test.py
@@ -211,10 +211,10 @@ def success_find_iso_test(self,
return_value=True)
@patch("pyanaconda.modules.payloads.source.harddrive.initialization.find_and_mount_iso_image",
return_value="")
- @patch("pyanaconda.modules.payloads.source.harddrive.initialization.verify_valid_installtree",
+ @patch("pyanaconda.modules.payloads.source.harddrive.initialization.verify_valid_repository",
return_value=True)
def success_find_dir_test(self,
- verify_valid_installtree_mock,
+ verify_valid_repository_mock,
find_and_mount_iso_image_mock,
find_and_mount_device_mock):
"""Hard drive source setup dir found."""
@@ -228,7 +228,7 @@ def success_find_dir_test(self,
find_and_mount_iso_image_mock.assert_called_once_with(
device_mount_location + path_on_device, iso_mount_location
)
- verify_valid_installtree_mock.assert_called_once_with(
+ verify_valid_repository_mock.assert_called_once_with(
device_mount_location + path_on_device
)
self.assertEqual(result, SetupHardDriveResult(device_mount_location + path_on_device, ""))
@@ -237,12 +237,12 @@ def success_find_dir_test(self,
return_value=True)
@patch("pyanaconda.modules.payloads.source.harddrive.initialization.find_and_mount_iso_image",
return_value="")
- @patch("pyanaconda.modules.payloads.source.harddrive.initialization.verify_valid_installtree",
+ @patch("pyanaconda.modules.payloads.source.harddrive.initialization.verify_valid_repository",
return_value=False)
@patch("pyanaconda.modules.payloads.source.harddrive.initialization.unmount")
def failure_to_find_anything_test(self,
unmount_mock,
- verify_valid_installtree_mock,
+ verify_valid_repository_mock,
find_and_mount_iso_image_mock,
find_and_mount_device_mock):
"""Hard drive source setup failure to find anything."""
@@ -257,7 +257,7 @@ def failure_to_find_anything_test(self,
find_and_mount_iso_image_mock.assert_called_once_with(
device_mount_location + path_on_device, iso_mount_location
)
- verify_valid_installtree_mock.assert_called_once_with(
+ verify_valid_repository_mock.assert_called_once_with(
device_mount_location + path_on_device
)
unmount_mock.assert_called_once_with(
diff --git a/tests/nosetests/pyanaconda_tests/module_source_nfs_test.py b/tests/nosetests/pyanaconda_tests/module_source_nfs_test.py
index eb331dec10..d33796a469 100644
--- a/tests/nosetests/pyanaconda_tests/module_source_nfs_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_source_nfs_test.py
@@ -180,7 +180,7 @@ def success_find_iso_test(self,
self.assertEqual(result, iso_mount_location)
- @patch("pyanaconda.modules.payloads.source.nfs.initialization.verify_valid_installtree",
+ @patch("pyanaconda.modules.payloads.source.nfs.initialization.verify_valid_repository",
return_value=True)
@patch("pyanaconda.modules.payloads.source.nfs.initialization.find_and_mount_iso_image",
return_value="")
@@ -188,7 +188,7 @@ def success_find_iso_test(self,
def success_find_dir_test(self,
mount_mock,
find_and_mount_iso_image_mock,
- verify_valid_installtree_mock):
+ verify_valid_repository_mock):
"""Test NFS source setup find installation tree success"""
task = _create_setup_task()
result = task.run()
@@ -201,7 +201,7 @@ def success_find_dir_test(self,
find_and_mount_iso_image_mock.assert_called_once_with(device_mount_location,
iso_mount_location)
- verify_valid_installtree_mock.assert_called_once_with(device_mount_location)
+ verify_valid_repository_mock.assert_called_once_with(device_mount_location)
self.assertEqual(result, device_mount_location)
@@ -252,7 +252,7 @@ def setup_install_source_task_mount_failure_test(self, mount_mock):
options="nolock")
@patch("pyanaconda.modules.payloads.source.nfs.initialization.unmount")
- @patch("pyanaconda.modules.payloads.source.nfs.initialization.verify_valid_installtree",
+ @patch("pyanaconda.modules.payloads.source.nfs.initialization.verify_valid_repository",
return_value=False)
@patch("pyanaconda.modules.payloads.source.nfs.initialization.find_and_mount_iso_image",
return_value="")
@@ -260,7 +260,7 @@ def setup_install_source_task_mount_failure_test(self, mount_mock):
def setup_install_source_task_find_anything_failure_test(self,
mount_mock,
find_and_mount_iso_image_mock,
- verify_valid_installtree_mock,
+ verify_valid_repository_mock,
unmount_mock):
"""Test NFS can't find anything to install from"""
task = SetUpNFSSourceTask(device_mount_location, iso_mount_location, nfs_url)
@@ -274,7 +274,7 @@ def setup_install_source_task_find_anything_failure_test(self,
find_and_mount_iso_image_mock.assert_called_once_with(device_mount_location,
iso_mount_location)
- verify_valid_installtree_mock.assert_called_once_with(device_mount_location)
+ verify_valid_repository_mock.assert_called_once_with(device_mount_location)
unmount_mock.assert_called_once_with(
device_mount_location

View File

@ -15,7 +15,7 @@ index 1abdeb2..44b573c 100755
@@ -263,6 +263,8 @@ if __name__ == "__main__": @@ -263,6 +263,8 @@ if __name__ == "__main__":
from pyanaconda.flags import flags from pyanaconda.flags import flags
from pyanaconda.core.kernel import kernel_arguments from pyanaconda.core.kernel import kernel_arguments
(opts, depr) = parse_arguments(boot_cmdline=kernel_arguments) (opts, removed_no_inst_args) = parse_arguments(boot_cmdline=kernel_arguments)
+ if not opts.method: + if not opts.method:
+ opts.method = opts.stage2 + opts.method = opts.stage2

View File

@ -1,25 +0,0 @@
From e1d294331217ec7380f7f186d7a6837e72770432 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Fri, 19 Jun 2020 11:42:23 +0800
Subject: [PATCH] disable-product-name-in-welcome-is-uppercase
---
pyanaconda/ui/gui/spokes/welcome.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index 3373f1d..639fdcd 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -251,7 +251,7 @@ class WelcomeLanguageSpoke(StandaloneSpoke, LangLocaleHandler):
languageEntry.set_placeholder_text(_(self._origStrings[languageEntry]))
# And of course, don't forget the underlying window.
- self.window.set_property("distribution", distributionText().upper())
+ self.window.set_property("distribution", distributionText())
self.window.retranslate()
# Retranslate the window title text
--
2.23.0

View File

@ -1,27 +0,0 @@
From a51168ce9ab849f857efd96eae66cff5247a45a4 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Thu, 18 Jun 2020 17:35:01 +0800
Subject: [PATCH] disable set passwd without confirmation
---
pyanaconda/input_checking.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/pyanaconda/input_checking.py b/pyanaconda/input_checking.py
index 9efbd7b..b0fd605 100644
--- a/pyanaconda/input_checking.py
+++ b/pyanaconda/input_checking.py
@@ -412,6 +412,10 @@ class PasswordValidityCheck(InputCheck):
pw_score = 4
status_text = _(constants.SecretStatus.STRONG.value)
+ #disable set password without confirnation
+ if not error_message and not check_request.password_confirmation:
+ error_message = _(constants.SECRET_CONFIRM_ERROR_GUI[check_request.secret_type])
+
# the policy influences the overall success of the check
# - score 0 & strict == True -> success = False
# - score 0 & strict == False -> success = True
--
2.23.0

View File

@ -1,36 +1,36 @@
From 6920ff7aa9c0215a032e00a5406b943737903c72 Mon Sep 17 00:00:00 2001 From 4229601e2c53c2e002436a0132663f83a89e6e47 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com> From: t_feng <fengtao40@huawei.com>
Date: Wed, 1 Jul 2020 18:08:35 +0800 Date: Wed, 1 Jul 2020 18:08:35 +0800
Subject: [PATCH] disable ssh login checkbox Subject: [PATCH] disable ssh login checkbox
--- ---
pyanaconda/ui/gui/spokes/root_password.py | 8 +++++--- pyanaconda/ui/gui/spokes/root_password.py | 8 ++++----
1 file changed, 5 insertions(+), 3 deletions(-) 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/root_password.py b/pyanaconda/ui/gui/spokes/root_password.py diff --git a/pyanaconda/ui/gui/spokes/root_password.py b/pyanaconda/ui/gui/spokes/root_password.py
index 313ba0f..2af9111 100644 index 1d19380..f2e389d 100644
--- a/pyanaconda/ui/gui/spokes/root_password.py --- a/pyanaconda/ui/gui/spokes/root_password.py
+++ b/pyanaconda/ui/gui/spokes/root_password.py +++ b/pyanaconda/ui/gui/spokes/root_password.py
@@ -72,6 +72,8 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler) @@ -79,7 +79,8 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
self._password_label = self.builder.get_object("password_label") self._password_label = self.builder.get_object("password_label")
self._lock = self.builder.get_object("lock") self._enable_root_radio = self.builder.get_object("enable_root_radio")
self._root_password_ssh_login_override = self.builder.get_object("root_password_ssh_login_override") self._disable_root_radio = self.builder.get_object("disable_root_radio")
- self._root_password_ssh_login_override = self.builder.get_object("root_password_ssh_login_override")
+ self._root_password_ssh_login_override.set_visible(False) + self._root_password_ssh_login_override.set_visible(False)
+ self._root_password_ssh_login_override.set_no_show_all(True) + self._root_password_ssh_login_override.set_no_show_all(True)
self._revealer = self.builder.get_object("password_revealer")
# Install the password checks: # Install the password checks:
# - Has a password been specified? @@ -159,9 +160,8 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler)
@@ -147,9 +149,9 @@ class PasswordSpoke(FirstbootSpokeMixIn, NormalSpoke, GUISpokeInputCheckHandler) control.set_active(True)
# we use the _refresh_running atribute to differentiate self.on_root_enabled_changed(control)
# it from "real" clicks
self._lock.set_active(self._users_module.IsRootAccountLocked)
- self._root_password_ssh_login_override.set_active( - self._root_password_ssh_login_override.set_active(
- self._users_module.RootPasswordSSHLoginAllowed - self._users_module.RootPasswordSSHLoginAllowed
- ) - )
+ self._root_password_ssh_login_override.set_visible(False) + self._root_password_ssh_login_override.set_visible(False)
+ self._root_password_ssh_login_override.set_no_show_all(True) + self._root_password_ssh_login_override.set_no_show_all(True)
+ if self.root_enabled:
if not self._lock.get_active():
# rerun checks so that we have a correct status message, if any # rerun checks so that we have a correct status message, if any
self.checker.run_checks() self.checker.run_checks()
-- --

View File

@ -1,40 +0,0 @@
From aa819ebee288aa307dc204337228c402189fd5e5 Mon Sep 17 00:00:00 2001
From: "Qr.Xia" <69908158+xqrustc2020@users.noreply.github.com>
Date: Mon, 12 Oct 2020 11:04:27 +0800
Subject: [PATCH] fix 0 storage devices selected
"0 storage devices selected" is printed because the format_type of sda
is "ext4" rather than "disklabel", and disk 'sda' is filtered by
filter_disks_by_names(partitioned_devices, selected_disks).
Resolves: rhbz#1878661
---
pyanaconda/ui/gui/spokes/custom_storage.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom_storage.py b/pyanaconda/ui/gui/spokes/custom_storage.py
index d72e315..b89866c 100644
--- a/pyanaconda/ui/gui/spokes/custom_storage.py
+++ b/pyanaconda/ui/gui/spokes/custom_storage.py
@@ -47,7 +47,7 @@ from pyanaconda.modules.common.structures.partitioning import PartitioningReques
from pyanaconda.modules.common.structures.device_factory import DeviceFactoryRequest, \
DeviceFactoryPermissions
from pyanaconda.product import productName, productVersion
-from pyanaconda.ui.lib.storage import reset_bootloader, create_partitioning, filter_disks_by_names
+from pyanaconda.ui.lib.storage import reset_bootloader, create_partitioning
from pyanaconda.core.storage import DEVICE_TYPE_UNSUPPORTED, DEVICE_TEXT_MAP, \
MOUNTPOINT_DESCRIPTIONS, NAMED_DEVICE_TYPES, CONTAINER_DEVICE_TYPES, device_type_from_autopart, \
PROTECTED_FORMAT_TYPES, DEVICE_TYPE_BTRFS, DEVICE_TYPE_MD, Size
@@ -303,9 +303,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageCheckHandler):
self._default_file_system = self._device_tree.GetDefaultFileSystem()
# Initialize the selected disks.
- selected_disks = self._disk_selection.SelectedDisks
- partitioned_devices = self._device_tree.GetPartitioned()
- self._selected_disks = filter_disks_by_names(partitioned_devices, selected_disks)
+ self._selected_disks = self._disk_selection.SelectedDisks
# Update the UI elements.
self._do_refresh(init_expanded_pages=True)
--
2.23.0

View File

@ -1,44 +1,56 @@
From 8ecae3e85d9eeedb131dbc026dcdf5bba95cdb15 Mon Sep 17 00:00:00 2001 From cc1706cdbcabab80ab867c2a8f5a517884faa048 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com> From: t_feng <fengtao40@huawei.com>
Date: Thu, 18 Jun 2020 17:13:47 +0800 Date: Thu, 18 Jun 2020 17:13:47 +0800
Subject: [PATCH] fix hostname info Subject: [PATCH] fix hostname info
--- ---
po/zh_CN.po | 6 +++--- po/zh_CN.po | 5 +++--
pyanaconda/network.py | 4 ++-- pyanaconda/core/regexes.py | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-) pyanaconda/network.py | 3 ++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/po/zh_CN.po b/po/zh_CN.po diff --git a/po/zh_CN.po b/po/zh_CN.po
index 0a4d1cd..be8cefe 100644 index e31f0b2..c02ce1e 100644
--- a/po/zh_CN.po --- a/po/zh_CN.po
+++ b/po/zh_CN.po +++ b/po/zh_CN.po
@@ -2365,11 +2365,11 @@ msgstr "本地主机名绝不能以句号\".\"结尾。" @@ -4090,10 +4090,11 @@ msgstr "本地主机名不能以英文句号“.”结尾。"
#: pyanaconda/network.py:119
msgid "" msgid ""
"Host names can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.', " "Host names can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.', "
-"parts between periods must contain something and cannot start or end with " "parts between periods must contain something and cannot start or end with "
-"'-'." -"'-'."
+"parts between periods must contain something being 63 or fewer " +"parts between periods must contain something being 63 or fewer "
+"characters and cannot start or end with '-'." +"characters and cannot start or end with '.' and '-'."
msgstr "" msgstr ""
"主机名只能包含 'a-z', 'A-Z', '0-9', '-'(英文减号), 或者 '.'(英文点号),其" "主机名只能包含 'a-z'、'A-Z'、 '0-9'、 '-'(英文减号),或者 '.'(英文点号),"
-"中两个点号中不能为空且不能以'-'开头或结尾。" -"中两个点号中不能为空且不能以 '-' 开头或结尾。"
+"中两个点号中不能为空必须少于64个字符且不能以'-'开头或结尾。" +"中两个点号中不能为空必须少于64个字符且不能以'.'和'-'开头或结尾。"
#: pyanaconda/network.py:465 #: pyanaconda/network.py:457
msgid "Status not available" msgid "Status not available"
diff --git a/pyanaconda/core/regexes.py b/pyanaconda/core/regexes.py
index cc00702..388d1ff 100644
--- a/pyanaconda/core/regexes.py
+++ b/pyanaconda/core/regexes.py
@@ -103,7 +103,7 @@ IPV4_NETMASK_WITH_ANCHORS = re.compile("^" + IPV4_NETMASK_WITHOUT_ANCHORS + "$")
# with a period, but it can end with one.
# This regex uses negative lookahead and lookback assertions to enforce the
# hyphen rules and make it way more confusing
-HOSTNAME_PATTERN_WITHOUT_ANCHORS = r'(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*\.?)'
+HOSTNAME_PATTERN_WITHOUT_ANCHORS = r'(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*)'
# URL Hostname
# This matches any hostname, IPv4 literal or properly encased IPv6 literal
diff --git a/pyanaconda/network.py b/pyanaconda/network.py diff --git a/pyanaconda/network.py b/pyanaconda/network.py
index f8e9b19..127a1bd 100644 index 38fe957..c52cf1d 100644
--- a/pyanaconda/network.py --- a/pyanaconda/network.py
+++ b/pyanaconda/network.py +++ b/pyanaconda/network.py
@@ -118,8 +118,8 @@ def is_valid_hostname(hostname, local=False): @@ -115,7 +115,8 @@ def is_valid_hostname(hostname, local=False):
if not re.match('^' + HOSTNAME_PATTERN_WITHOUT_ANCHORS + '$', hostname):
return (False, _("Host names can only contain the characters 'a-z', " return (False, _("Host names can only contain the characters 'a-z', "
"'A-Z', '0-9', '-', or '.', parts between periods " "'A-Z', '0-9', '-', or '.', parts between periods "
- "must contain something and cannot start or end with " "must contain something and cannot start or end with "
- "'-'.")) - "'-'."))
+ "must contain something being 63 or fewer " + "must contain something being 63 or fewer "
+ "characters and cannot start or end with '-'.")) + "characters and cannot start or end with '.' and '-'."))
return (True, "") return (True, "")

View File

@ -1,46 +0,0 @@
From ad48d3ab850c9dd40908a51eae3580fcc148e171 Mon Sep 17 00:00:00 2001
From: xqrustc2020 <69908158+xqrustc2020@users.noreply.github.com>
Date: Tue, 29 Sep 2020 13:16:43 +0800
Subject: [PATCH] fix remove unkown partition in sda failed
fix: cannot create partition when sda exists a ext4 filesystem.
When you clicked the "-" button, only the format on sda should be
destroyed without removing sda from the device tree, but sda
was also destroyed. As a result, sda cannot be found during disk
initialization and an error was reported.
Resolves: rhbz#1878661
---
.../modules/storage/partitioning/interactive/utils.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/pyanaconda/modules/storage/partitioning/interactive/utils.py b/pyanaconda/modules/storage/partitioning/interactive/utils.py
index b52876a..fe7bd59 100644
--- a/pyanaconda/modules/storage/partitioning/interactive/utils.py
+++ b/pyanaconda/modules/storage/partitioning/interactive/utils.py
@@ -1046,8 +1046,10 @@ def _destroy_device(storage, device):
:param device: an instance of a device
"""
# Remove the device.
- if device.is_disk and device.partitioned and not device.format.supported:
- storage.recursive_remove(device)
+ if device.is_disk:
+ if device.partitioned and not device.format.supported:
+ storage.recursive_remove(device)
+ storage.initialize_disk(device)
elif device.direct and not device.isleaf:
# We shouldn't call this method for with non-leaf devices
# except for those which are also directly accessible like
@@ -1057,10 +1059,6 @@ def _destroy_device(storage, device):
else:
storage.destroy_device(device)
- # Initialize the disk.
- if device.is_disk:
- storage.initialize_disk(device)
-
# Remove empty extended partitions.
if getattr(device, "is_logical", False):
storage.remove_empty_extended_partitions()
--
2.23.0

View File

@ -1,207 +0,0 @@
From 0b851a3f25d6e2ac7e6d06e342d0823c206ee25a Mon Sep 17 00:00:00 2001
From: Vladimir Slavik <vslavik@redhat.com>
Date: Wed, 21 Apr 2021 20:00:54 +0200
Subject: [PATCH] Another attempt at the X thing. This gives up the exception
handler test temporarily, and solves almost everything.
The main problem of other solutions is that once X starts,
it steals the screen by going to tty6. If the exception handler
test-invoking handler is not returned back immediately,
an "after-timeout" handler can be installed instead, which switches back to tty1.
With that in place, it's also safe to terminate Xorg once
it's clear it's not coming in time. The termination will happen later,
but that does not matter any more.
Finally, with the termination happening,
it is also safe to return the crash report text handler.
Resolves: rhbz#1918702
Previous work: #3107, #3132, #3141, #3295. Thanks to @bitcoffeeiux and @poncovka.
The one avenue left unexplored is using the -displayfd option.
---
pyanaconda/core/util.py | 62 ++++++++++++++++++++++++++++++++---------
pyanaconda/display.py | 29 +++++++++++++++++--
2 files changed, 75 insertions(+), 16 deletions(-)
diff --git a/pyanaconda/core/util.py b/pyanaconda/core/util.py
index b7a1731..3013cd8 100644
--- a/pyanaconda/core/util.py
+++ b/pyanaconda/core/util.py
@@ -47,7 +47,7 @@ from pyanaconda.core.constants import DRACUT_SHUTDOWN_EJECT, TRANSLATIONS_UPDATE
IPMI_ABORTED, X_TIMEOUT, TAINT_HARDWARE_UNSUPPORTED, TAINT_SUPPORT_REMOVED, \
WARNING_HARDWARE_UNSUPPORTED, WARNING_SUPPORT_REMOVED
from pyanaconda.core.constants import SCREENSHOTS_DIRECTORY, SCREENSHOTS_TARGET_DIRECTORY
-from pyanaconda.errors import RemovedModuleError, ExitError
+from pyanaconda.errors import RemovedModuleError
from pyanaconda.anaconda_logging import program_log_lock
from pyanaconda.anaconda_loggers import get_module_logger, get_program_logger
@@ -204,6 +204,19 @@ def startProgram(argv, root='/', stdin=None, stdout=subprocess.PIPE, stderr=subp
preexec_fn=preexec, cwd=root, env=env, **kwargs)
+class X11Status:
+ """Status of Xorg launch.
+
+ Values of an instance can be modified from the handler functions.
+ """
+ def __init__(self):
+ self.started = False
+ self.timed_out = False
+
+ def needs_waiting(self):
+ return not (self.started or self.timed_out)
+
+
def startX(argv, output_redirect=None, timeout=X_TIMEOUT):
""" Start X and return once X is ready to accept connections.
@@ -217,28 +230,36 @@ def startX(argv, output_redirect=None, timeout=X_TIMEOUT):
:param output_redirect: file or file descriptor to redirect stdout and stderr to
:param timeout: Number of seconds to timing out.
"""
- # Use a list so the value can be modified from the handler function
- x11_started = [False]
+ x11_status = X11Status()
- def sigusr1_handler(num, frame):
+ # Handle successful start before timeout
+ def sigusr1_success_handler(num, frame):
log.debug("X server has signalled a successful start.")
- x11_started[0] = True
+ x11_status.started = True
# Fail after, let's say a minute, in case something weird happens
# and we don't receive SIGUSR1
def sigalrm_handler(num, frame):
# Check that it didn't make it under the wire
- if x11_started[0]:
+ if x11_status.started:
return
+ x11_status.timed_out = True
log.error("Timeout trying to start %s", argv[0])
- raise ExitError("Timeout trying to start %s" % argv[0])
- # preexec_fn to add the SIGUSR1 handler in the child
+ # Handle delayed start after timeout
+ def sigusr1_too_late_handler(num, frame):
+ if x11_status.timed_out:
+ log.debug("SIGUSR1 received after X server timeout. Switching back to tty1. "
+ "SIGUSR1 now again initiates test of exception reporting.")
+ signal.signal(signal.SIGUSR1, old_sigusr1_handler)
+
+ # preexec_fn to add the SIGUSR1 handler in the child we are starting
+ # see man page XServer(1), section "signals"
def sigusr1_preexec():
signal.signal(signal.SIGUSR1, signal.SIG_IGN)
try:
- old_sigusr1_handler = signal.signal(signal.SIGUSR1, sigusr1_handler)
+ old_sigusr1_handler = signal.signal(signal.SIGUSR1, sigusr1_success_handler)
old_sigalrm_handler = signal.signal(signal.SIGALRM, sigalrm_handler)
# Start the timer
@@ -249,16 +270,31 @@ def startX(argv, output_redirect=None, timeout=X_TIMEOUT):
preexec_fn=sigusr1_preexec)
WatchProcesses.watch_process(childproc, argv[0])
- # Wait for SIGUSR1
- while not x11_started[0]:
+ # Wait for SIGUSR1 or SIGALRM
+ while x11_status.needs_waiting():
signal.pause()
finally:
- # Put everything back where it was
+ # Stop the timer
signal.alarm(0)
- signal.signal(signal.SIGUSR1, old_sigusr1_handler)
signal.signal(signal.SIGALRM, old_sigalrm_handler)
+ # Handle outcome of X start attempt
+ if x11_status.started:
+ signal.signal(signal.SIGUSR1, old_sigusr1_handler)
+ elif x11_status.timed_out:
+ signal.signal(signal.SIGUSR1, sigusr1_too_late_handler)
+ # Kill Xorg because from now on we will not use it. It will exit only after sending
+ # the signal, but at least we don't have to track that.
+ WatchProcesses.unwatch_process(childproc)
+ childproc.terminate()
+ log.debug("Exception handler test suspended to prevent accidental activation by "
+ "delayed Xorg start. Next SIGUSR1 will be handled as delayed Xorg start.")
+ # Raise an exception to notify the caller that things went wrong. This affects
+ # particularly pyanaconda.display.do_startup_x11_actions(), where the window manager
+ # is started immediately after this. The WM would just wait forever.
+ raise TimeoutError("Timeout trying to start %s" % argv[0])
+
def _run_program(argv, root='/', stdin=None, stdout=None, env_prune=None, log_output=True,
binary_output=False, filter_stderr=False):
diff --git a/pyanaconda/display.py b/pyanaconda/display.py
index 8379d9c..b577eb8 100644
--- a/pyanaconda/display.py
+++ b/pyanaconda/display.py
@@ -22,6 +22,7 @@
import os
import subprocess
import time
+import textwrap
import pkgutil
from pyanaconda.core.configuration.anaconda import conf
@@ -49,6 +50,14 @@ from pyanaconda.anaconda_loggers import get_module_logger, get_stdout_logger
log = get_module_logger(__name__)
stdout_log = get_stdout_logger()
+X_TIMEOUT_ADVICE = \
+ "Do not load the stage2 image over a slow network link.\n" \
+ "Wait longer for the X server startup with the inst.xtimeout=<SECONDS> boot option." \
+ "The default is 60 seconds.\n" \
+ "Load the stage2 image into memory with the rd.live.ram boot option to decrease access " \
+ "time.\n" \
+ "Enforce text mode when installing from remote media with the inst.text boot option."
+# on RHEL also: "Use the customer portal download URL in ilo/drac devices for greater speed."
# Spice
@@ -78,7 +87,7 @@ def ask_vnc_question(anaconda, vnc_server, message):
App.initialize()
loop = App.get_event_loop()
loop.set_quit_callback(tui_quit_callback)
- spoke = AskVNCSpoke(anaconda.ksdata, message)
+ spoke = AskVNCSpoke(anaconda.ksdata, message=message)
ScreenHandler.schedule_screen(spoke)
App.run()
@@ -314,9 +323,23 @@ def setup_display(anaconda, options):
try:
start_x11(xtimeout)
do_startup_x11_actions()
- except (OSError, RuntimeError) as e:
+ except TimeoutError as e:
log.warning("X startup failed: %s", e)
- stdout_log.warning("X startup failed, falling back to text mode")
+ print("\nX did not start in the expected time, falling back to text mode. There are "
+ "multiple ways to avoid this issue:")
+ wrapper = textwrap.TextWrapper(initial_indent=" * ", subsequent_indent=" ",
+ width=os.get_terminal_size().columns - 3)
+ for line in X_TIMEOUT_ADVICE.split("\n"):
+ print(wrapper.fill(line))
+ util.vtActivate(1)
+ anaconda.display_mode = constants.DisplayModes.TUI
+ anaconda.gui_startup_failed = True
+ time.sleep(2)
+
+ except (OSError, RuntimeError) as e:
+ log.warning("X or window manager startup failed: %s", e)
+ print("\nX or window manager startup failed, falling back to text mode.")
+ util.vtActivate(1)
anaconda.display_mode = constants.DisplayModes.TUI
anaconda.gui_startup_failed = True
time.sleep(2)
--
2.23.0

View File

@ -22,8 +22,8 @@ index 87c9cb7..63240f7 100644
set-option -s exit-unattached off set-option -s exit-unattached off
set-option -g base-index 1 set-option -g base-index 1
@@ -25,7 +24,7 @@ set-option -g history-limit 10000 @@ -25,7 +24,7 @@ set-option -g history-limit 10000
# rhbz#1722181 # then re-attach to it in the tmux service run on the console tty.
new-session -d -s anaconda -n main "LD_PRELOAD=libgomp.so.1 anaconda" new-session -d -s anaconda -n main anaconda
-set-option status-right '#[fg=blue]#(echo -n "Switch tab: Alt+Tab | Help: F1 ")' -set-option status-right '#[fg=blue]#(echo -n "Switch tab: Alt+Tab | Help: F1 ")'
+set-option status-right '#[fg=blue]#(echo -n "Switch tab: Alt+Tab ")' +set-option status-right '#[fg=blue]#(echo -n "Switch tab: Alt+Tab ")'

View File

@ -1,62 +0,0 @@
From 853c4c8307c7427e5ee4fb57a2ffdcad1ce9d7f6 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Thu, 18 Jun 2020 22:39:12 +0800
Subject: [PATCH] make name not force to uppercase
---
pyanaconda/ui/gui/__init__.py | 4 ++--
pyanaconda/ui/gui/hubs/__init__.py | 2 +-
pyanaconda/ui/gui/spokes/welcome.py | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index 8c20423..06373d9 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -839,7 +839,7 @@ class GraphicalUserInterface(UserInterface):
self._currentAction.refresh()
self._currentAction.window.set_beta(not self._isFinal)
- self._currentAction.window.set_property("distribution", self._distributionText().upper())
+ self._currentAction.window.set_property("distribution", self._distributionText())
# Set some program-wide settings.
settings = Gtk.Settings.get_default()
@@ -1005,7 +1005,7 @@ class GraphicalUserInterface(UserInterface):
nextAction.initialize()
nextAction.window.set_beta(self._currentAction.window.get_beta())
- nextAction.window.set_property("distribution", self._distributionText().upper())
+ nextAction.window.set_property("distribution", self._distributionText())
if not nextAction.showable:
self._currentAction.window.hide()
diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py
index 062e04e..a99e438 100644
--- a/pyanaconda/ui/gui/hubs/__init__.py
+++ b/pyanaconda/ui/gui/hubs/__init__.py
@@ -145,7 +145,7 @@ class Hub(GUIObject, common.Hub):
# From here on, this Spoke will always exist.
spoke = spokeClass(self.data, self.storage, self.payload)
spoke.window.set_beta(self.window.get_beta())
- spoke.window.set_property("distribution", distributionText().upper())
+ spoke.window.set_property("distribution", distributionText())
# If a spoke is not showable, it is unreachable in the UI. We
# might as well get rid of it.
diff --git a/pyanaconda/ui/gui/spokes/welcome.py b/pyanaconda/ui/gui/spokes/welcome.py
index 4f1bfbc..3373f1d 100644
--- a/pyanaconda/ui/gui/spokes/welcome.py
+++ b/pyanaconda/ui/gui/spokes/welcome.py
@@ -241,7 +241,7 @@ class WelcomeLanguageSpoke(StandaloneSpoke, LangLocaleHandler):
welcomeLabel = self.builder.get_object("welcomeLabel")
welcomeLabel.set_text(_("WELCOME TO %(name)s %(version)s.") %
- {"name" : productName.upper(), "version" : productVersion}) # pylint: disable=no-member
+ {"name" : productName, "version" : productVersion}) # pylint: disable=no-member
# Retranslate the language (filtering) entry's placeholder text
languageEntry = self.builder.get_object("languageEntry")
--
2.23.0

View File

@ -1,25 +0,0 @@
From aa21df647d18390124379026dbaf99741d336875 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Fri, 19 Jun 2020 10:43:24 +0800
Subject: [PATCH] modify arguments parsing
---
pyanaconda/argument_parsing.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/argument_parsing.py b/pyanaconda/argument_parsing.py
index 6b2f40f..ce29587 100644
--- a/pyanaconda/argument_parsing.py
+++ b/pyanaconda/argument_parsing.py
@@ -592,7 +592,7 @@ def getArgumentParser(version_string, boot_cmdline=None):
# some defaults change based on cmdline flags
if boot_cmdline is not None:
- if "console" in boot_cmdline:
+ if "console" in boot_cmdline and "inst.text" in boot_cmdline:
ap.set_defaults(display_mode=DisplayModes.TUI)
return ap
--
2.23.0

View File

@ -1,55 +0,0 @@
From 59a4b9b04388e327e135f3ab9893698e2b3f5a5d Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Fri, 19 Jun 2020 11:44:31 +0800
Subject: [PATCH] modify default timezone
---
pyanaconda/modules/timezone/installation.py | 4 ++--
pyanaconda/modules/timezone/timezone.py | 2 +-
pyanaconda/ui/gui/spokes/datetime_spoke.py | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/modules/timezone/installation.py b/pyanaconda/modules/timezone/installation.py
index 6383df1..9c6ae40 100644
--- a/pyanaconda/modules/timezone/installation.py
+++ b/pyanaconda/modules/timezone/installation.py
@@ -63,8 +63,8 @@ class ConfigureTimezoneTask(Task):
if not is_valid_timezone(self._timezone):
# this should never happen, but for pity's sake
log.warning("Timezone %s set in kickstart is not valid, "
- "falling back to default (America/New_York).", self._timezone)
- self._timezone = "America/New_York"
+ "falling back to default (Asia/Shanghai).", self._timezone)
+ self._timezone = "Asia/Shanghai"
def _make_timezone_symlink(self):
"""Create the symlink that actually defines timezone."""
diff --git a/pyanaconda/modules/timezone/timezone.py b/pyanaconda/modules/timezone/timezone.py
index 0678072..db1cd18 100644
--- a/pyanaconda/modules/timezone/timezone.py
+++ b/pyanaconda/modules/timezone/timezone.py
@@ -40,7 +40,7 @@ class TimezoneService(KickstartService):
def __init__(self):
super().__init__()
self.timezone_changed = Signal()
- self._timezone = "America/New_York"
+ self._timezone = "Asia/Shanghai"
self.is_utc_changed = Signal()
self._is_utc = False
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
index 00b1bd9..f01d245 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -65,7 +65,7 @@ SERVER_POOL = 1
SERVER_WORKING = 2
SERVER_USE = 3
-DEFAULT_TZ = "America/New_York"
+DEFAULT_TZ = "Asia/Shanghai"
SPLIT_NUMBER_SUFFIX_RE = re.compile(r'([^0-9]*)([-+])([0-9]+)')
--
2.23.0

View File

@ -1,6 +1,6 @@
From 1999c1bd693ee187cc699fd1f1d4ac77086373b9 Mon Sep 17 00:00:00 2001 From ae056f86eca56a76ae9736d7f199d73548a7574b Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com> From: t_feng <fengtao40@huawei.com>
Date: Fri, 19 Jun 2020 09:26:00 +0800 Date: Mon, 7 Nov 2022 20:03:39 +0800
Subject: [PATCH] modify interface is extended in Chinese mode Subject: [PATCH] modify interface is extended in Chinese mode
--- ---
@ -8,14 +8,14 @@ Subject: [PATCH] modify interface is extended in Chinese mode
1 file changed, 1 insertion(+), 1 deletion(-) 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/po/zh_CN.po b/po/zh_CN.po diff --git a/po/zh_CN.po b/po/zh_CN.po
index be8cefe..7ee5511 100644 index 8f48aad..18b0925 100644
--- a/po/zh_CN.po --- a/po/zh_CN.po
+++ b/po/zh_CN.po +++ b/po/zh_CN.po
@@ -6429,7 +6429,7 @@ msgstr "搜索方式(_B)" @@ -4433,7 +4433,7 @@ msgstr "搜索方式(_B)"
#: pyanaconda/ui/gui/spokes/advanced_storage.glade:153 #: pyanaconda/ui/gui/spokes/advanced_storage.glade:153
msgid "Port / Target / LUN #" msgid "Port / Target / LUN #"
-msgstr "端口 / 目标 / 逻辑单位数标示符 (LUN #) " -msgstr "端口 / 目标 / 逻辑单位数标示符 (LUN #)"
+msgstr "端口 / 目标 / LUN # " +msgstr "端口 / 目标 / LUN # "
#: pyanaconda/ui/gui/spokes/advanced_storage.glade:154 #: pyanaconda/ui/gui/spokes/advanced_storage.glade:154

View File

@ -1,39 +0,0 @@
From 343751258b3a4b3e21cf52add5a9ddf600065835 Mon Sep 17 00:00:00 2001
From: t_feng <fengtao40@huawei.com>
Date: Fri, 19 Jun 2020 11:48:25 +0800
Subject: [PATCH] modify network hostname dot illegal
---
pyanaconda/core/regexes.py | 2 +-
pyanaconda/network.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyanaconda/core/regexes.py b/pyanaconda/core/regexes.py
index 63ab668..f86e403 100644
--- a/pyanaconda/core/regexes.py
+++ b/pyanaconda/core/regexes.py
@@ -103,7 +103,7 @@ IPV4_NETMASK_WITH_ANCHORS = re.compile("^" + IPV4_NETMASK_WITHOUT_ANCHORS + "$")
# with a period, but it can end with one.
# This regex uses negative lookahead and lookback assertions to enforce the
# hyphen rules and make it way more confusing
-HOSTNAME_PATTERN_WITHOUT_ANCHORS = r'(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*\.?)'
+HOSTNAME_PATTERN_WITHOUT_ANCHORS = r'(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*)'
# URL Hostname
# This matches any hostname, IPv4 literal or properly encased IPv6 literal
diff --git a/pyanaconda/network.py b/pyanaconda/network.py
index 127a1bd..30cf2af 100644
--- a/pyanaconda/network.py
+++ b/pyanaconda/network.py
@@ -119,7 +119,7 @@ def is_valid_hostname(hostname, local=False):
return (False, _("Host names can only contain the characters 'a-z', "
"'A-Z', '0-9', '-', or '.', parts between periods "
"must contain something being 63 or fewer "
- "characters and cannot start or end with '-'."))
+ "characters and cannot start or end with '.' and '-'."))
return (True, "")
--
2.23.0

View File

@ -1,18 +1,60 @@
diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.glade anaconda-33.19/pyanaconda/ui/gui/spokes/datetime_spoke.glade From 303b072992542dfa9a7e2b2a9dc99120564a3f07 Mon Sep 17 00:00:00 2001
--- anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.glade 2021-08-07 16:25:21.547621965 +0800 From: sun_hai_10 <sunhai10@huawei.com>
+++ anaconda-33.19/pyanaconda/ui/gui/spokes/datetime_spoke.glade 2021-08-07 16:26:20.137758256 +0800 Date: Mon, 7 Nov 2022 14:23:04 +0800
Subject: [PATCH] modify timezone and delete datezone map
---
pyanaconda/modules/timezone/installation.py | 4 +-
pyanaconda/modules/timezone/timezone.py | 2 +-
pyanaconda/ui/gui/spokes/datetime_spoke.glade | 14 -------
pyanaconda/ui/gui/spokes/datetime_spoke.py | 38 +++----------------
4 files changed, 8 insertions(+), 50 deletions(-)
diff --git a/pyanaconda/modules/timezone/installation.py b/pyanaconda/modules/timezone/installation.py
index 08e24c0..f11874f 100644
--- a/pyanaconda/modules/timezone/installation.py
+++ b/pyanaconda/modules/timezone/installation.py
@@ -63,8 +63,8 @@ class ConfigureTimezoneTask(Task):
if not is_valid_timezone(self._timezone):
# this should never happen, but for pity's sake
log.warning("Timezone %s set in kickstart is not valid, "
- "falling back to default (America/New_York).", self._timezone)
- self._timezone = "America/New_York"
+ "falling back to default (Asia/Shanghai).", self._timezone)
+ self._timezone = "Asia/Shanghai"
def _make_timezone_symlink(self):
"""Create the symlink that actually defines timezone."""
diff --git a/pyanaconda/modules/timezone/timezone.py b/pyanaconda/modules/timezone/timezone.py
index b5d5f7b..2a328a3 100644
--- a/pyanaconda/modules/timezone/timezone.py
+++ b/pyanaconda/modules/timezone/timezone.py
@@ -44,7 +44,7 @@ class TimezoneService(KickstartService):
def __init__(self):
super().__init__()
self.timezone_changed = Signal()
- self._timezone = "America/New_York"
+ self._timezone = "Asia/Shanghai"
self.is_utc_changed = Signal()
self._is_utc = False
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.glade b/pyanaconda/ui/gui/spokes/datetime_spoke.glade
index 188f93b..aa468d9 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.glade
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.glade
@@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
<interface> <interface>
<requires lib="gtk+" version="3.12"/> <requires lib="gtk+" version="3.12"/>
<requires lib="AnacondaWidgets" version="1.0"/> <requires lib="AnacondaWidgets" version="1.0"/>
- <requires lib="TimezoneMap" version="0.4"/> - <requires lib="TimezoneMap" version="0.4"/>
<object class="GtkImage" id="addImage"> <object class="GtkListStore" id="cities">
<property name="visible">True</property> <columns>
<property name="can_focus">False</property> <!-- column-name name -->
@@ -548,19 +547,6 @@ @@ -314,19 +313,6 @@
<property name="position">0</property>
</packing> </packing>
</child> </child>
<child> - <child>
- <object class="CcTimezoneMap" id="tzmap"> - <object class="CcTimezoneMap" id="tzmap">
- <property name="visible">True</property> - <property name="visible">True</property>
- <property name="can_focus">False</property> - <property name="can_focus">False</property>
@ -25,14 +67,14 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.glade anaco
- <property name="position">1</property> - <property name="position">1</property>
- </packing> - </packing>
- </child> - </child>
- <child> <child>
<object class="GtkAlignment" id="footerAlignment"> <object class="GtkAlignment" id="footerAlignment">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda-33.19/pyanaconda/ui/gui/spokes/datetime_spoke.py index b21bbc3..c8416b4 100644
--- anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py 2021-08-07 16:25:21.547621965 +0800 --- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ anaconda-33.19/pyanaconda/ui/gui/spokes/datetime_spoke.py 2021-08-07 16:30:03.958279259 +0800 +++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -53,9 +53,8 @@ @@ -50,15 +50,14 @@ from pyanaconda.threading import threadMgr, AnacondaThread
import gi import gi
gi.require_version("Gdk", "3.0") gi.require_version("Gdk", "3.0")
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
@ -43,7 +85,14 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
log = get_module_logger(__name__) log = get_module_logger(__name__)
@@ -377,11 +376,6 @@ __all__ = ["DatetimeSpoke"]
-DEFAULT_TZ = "America/New_York"
+DEFAULT_TZ = "Asia/Shanghai"
SPLIT_NUMBER_SUFFIX_RE = re.compile(r'([^0-9]*)([-+])([0-9]+)')
@@ -168,11 +167,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
icon = "preferences-system-time-symbolic" icon = "preferences-system-time-symbolic"
title = CN_("GUI|Spoke", "_Time & Date") title = CN_("GUI|Spoke", "_Time & Date")
@ -52,10 +101,10 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
- _hack = TimezoneMap.TimezoneMap() - _hack = TimezoneMap.TimezoneMap()
- del(_hack) - del(_hack)
- -
def __init__(self, *args): @staticmethod
NormalSpoke.__init__(self, *args) def get_screen_id():
"""Return a unique id of this UI screen."""
@@ -407,7 +401,6 @@ @@ -211,7 +205,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
self._yearsStore = self.builder.get_object("years") self._yearsStore = self.builder.get_object("years")
self._regionsStore = self.builder.get_object("regions") self._regionsStore = self.builder.get_object("regions")
self._citiesStore = self.builder.get_object("cities") self._citiesStore = self.builder.get_object("cities")
@ -63,7 +112,7 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
self._dateBox = self.builder.get_object("dateBox") self._dateBox = self.builder.get_object("dateBox")
# we need to know it the new value is the same as previous or not # we need to know it the new value is the same as previous or not
@@ -530,10 +523,6 @@ @@ -334,10 +327,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
else: else:
return _("Invalid timezone") return _("Invalid timezone")
else: else:
@ -74,7 +123,7 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
return _("Nothing selected") return _("Nothing selected")
def apply(self): def apply(self):
@@ -585,7 +574,6 @@ @@ -389,7 +378,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
kickstart_timezone = self._timezone_module.Timezone kickstart_timezone = self._timezone_module.Timezone
if is_valid_timezone(kickstart_timezone): if is_valid_timezone(kickstart_timezone):
@ -82,17 +131,17 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
time.tzset() time.tzset()
self._update_datetime() self._update_datetime()
@@ -960,7 +948,6 @@ @@ -766,7 +754,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
if region == "Etc": if region == "Etc":
# Etc timezones cannot be displayed on the map, so let's reset the # Etc timezones cannot be displayed on the map, so let's reset the
# location and manually set a highlight with no location pin. # location and manually set a highlight with no location pin.
- self._tzmap.clear_location() - self._tzmap.clear_location()
if city in ("GMT", "UTC"): # Some time zones are just the same default.
if city in ("GMT", "UTC", "UCT", "Greenwich", "Universal", "Zulu"):
offset = 0.0 offset = 0.0
# The tzdb data uses POSIX-style signs for the GMT zones, which is @@ -780,13 +767,14 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
@@ -971,13 +958,14 @@ else:
# Take the part after "GMT" log.warning("Unknown time zone selected in GUI: Etc/%s", city)
offset = -float(city[3:])
- self._tzmap.set_selected_offset(offset) - self._tzmap.set_selected_offset(offset)
time.tzset() time.tzset()
@ -107,7 +156,7 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
# update "old" values # update "old" values
self._old_city = city self._old_city = city
@@ -1027,22 +1015,6 @@ @@ -836,22 +824,6 @@ class DatetimeSpoke(FirstbootSpokeMixIn, NormalSpoke):
self._stop_and_maybe_start_time_updating(interval=5) self._stop_and_maybe_start_time_updating(interval=5)
self._daysFilter.refilter() self._daysFilter.refilter()
@ -130,3 +179,6 @@ diff -Nur anaconda-33.19.org/pyanaconda/ui/gui/spokes/datetime_spoke.py anaconda
def on_timeformat_changed(self, button24h, *args): def on_timeformat_changed(self, button24h, *args):
hours = int(self._hoursLabel.get_text()) hours = int(self._hoursLabel.get_text())
amPm = self._amPmLabel.get_text() amPm = self._amPmLabel.get_text()
--
2.23.0

View File

@ -1,119 +0,0 @@
From 554be1cfd3d09035e0370f1efc46d3fc40f8496d Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Fri, 3 Jul 2020 11:11:46 +0200
Subject: [PATCH] Create a new DBus structure for time sources
Use the class TimeSourceData to represent a time source.
---
pyanaconda/core/constants.py | 4 +
.../modules/common/structures/timezone.py | 84 +++++++++++++++++++
2 files changed, 88 insertions(+)
create mode 100644 pyanaconda/modules/common/structures/timezone.py
diff --git a/pyanaconda/core/constants.py b/pyanaconda/core/constants.py
index 536529f4e0..5124f05b7f 100644
--- a/pyanaconda/core/constants.py
+++ b/pyanaconda/core/constants.py
@@ -306,6 +306,10 @@ class SecretStatus(Enum):
# Window title text
WINDOW_TITLE_TEXT = N_("Anaconda Installer")
+# Types of time sources.
+TIME_SOURCE_SERVER = "SERVER"
+TIME_SOURCE_POOL = "POOL"
+
# NTP server checking
NTP_SERVER_OK = 0
NTP_SERVER_NOK = 1
diff --git a/pyanaconda/modules/common/structures/timezone.py b/pyanaconda/modules/common/structures/timezone.py
new file mode 100644
index 0000000000..d18234f681
--- /dev/null
+++ b/pyanaconda/modules/common/structures/timezone.py
@@ -0,0 +1,84 @@
+#
+# DBus structures for the timezone data.
+#
+# Copyright (C) 2020 Red Hat, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+from dasbus.structure import DBusData
+from dasbus.typing import * # pylint: disable=wildcard-import
+
+from pyanaconda.core.constants import TIME_SOURCE_SERVER
+
+__all__ = ["TimeSourceData"]
+
+
+class TimeSourceData(DBusData):
+ """Data for a time source."""
+
+ def __init__(self):
+ self._type = TIME_SOURCE_SERVER
+ self._hostname = ""
+ self._options = []
+
+ @property
+ def type(self) -> Str:
+ """Type of the time source.
+
+ Supported values:
+
+ SERVER A single NTP server
+ POOL A pool of NTP servers
+
+ :return: a type of the time source
+ """
+ return self._type
+
+ @type.setter
+ def type(self, value: Str):
+ self._type = value
+
+ @property
+ def hostname(self) -> Str:
+ """Name of the time server.
+
+ For example:
+
+ ntp.cesnet.cz
+
+ :return: a host name
+ """
+ return self._hostname
+
+ @hostname.setter
+ def hostname(self, value: Str):
+ self._hostname = value
+
+ @property
+ def options(self) -> List[Str]:
+ """Options of the time source.
+
+ For example:
+
+ nts, ntsport 1234, iburst
+
+ See ``man chrony.conf``.
+
+ :return: a list of options
+ """
+ return self._options
+
+ @options.setter
+ def options(self, value):
+ self._options = value
--
2.23.0

View File

@ -1,290 +0,0 @@
From a645a1b8d17310533ef2d9232855c1852558e2b8 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Fri, 3 Jul 2020 12:04:04 +0200
Subject: [PATCH] Use the structure for time sources in ntp.py
Modify ntp.py to work with TimeSourceData instead of strings and clean up
its functions a little.
---
pyanaconda/ntp.py | 174 +++++++++++++++++++---------------------------
1 file changed, 73 insertions(+), 101 deletions(-)
diff --git a/pyanaconda/ntp.py b/pyanaconda/ntp.py
index 16eece65e4..1b74ac9433 100644
--- a/pyanaconda/ntp.py
+++ b/pyanaconda/ntp.py
@@ -31,6 +31,7 @@
from pyanaconda import isys
from pyanaconda.threading import threadMgr, AnacondaThread
from pyanaconda.core.constants import THREAD_SYNC_TIME_BASENAME
+from pyanaconda.modules.common.structures.timezone import TimeSourceData
NTP_CONFIG_FILE = "/etc/chrony.conf"
@@ -47,21 +48,18 @@ class NTPconfigError(Exception):
pass
-def ntp_server_working(server):
- """
- Tries to do an NTP request to the $server (timeout may take some time).
+def ntp_server_working(server_hostname):
+ """Tries to do an NTP request to the server (timeout may take some time).
- :param server: hostname or IP address of an NTP server
- :type server: string
+ :param server_hostname: a host name or an IP address of an NTP server
+ :type server_hostname: string
:return: True if the given server is reachable and working, False otherwise
:rtype: bool
-
"""
-
client = ntplib.NTPClient()
try:
- client.request(server)
+ client.request(server_hostname)
except ntplib.NTPException:
return False
# address related error
@@ -75,118 +73,89 @@ def ntp_server_working(server):
return True
-def pools_servers_to_internal(pools, servers):
- ret = []
- for pool in pools:
- ret.extend(SERVERS_PER_POOL * [pool])
- ret.extend(servers)
-
- return ret
-
-
-def internal_to_pools_and_servers(pools_servers):
- server_nums = dict()
- pools = []
- servers = []
-
- for item in pools_servers:
- server_nums[item] = server_nums.get(item, 0) + 1
-
- for item in server_nums.keys():
- if server_nums[item] >= SERVERS_PER_POOL:
- pools.extend((server_nums[item] // SERVERS_PER_POOL) * [item])
- servers.extend((server_nums[item] % SERVERS_PER_POOL) * [item])
- else:
- servers.extend(server_nums[item] * [item])
+def get_servers_from_config(conf_file_path=NTP_CONFIG_FILE):
+ """Get NTP servers from a configuration file.
- return (pools, servers)
-
-
-def get_servers_from_config(conf_file_path=NTP_CONFIG_FILE,
- srv_regexp=SRV_LINE_REGEXP):
- """
Goes through the chronyd's configuration file looking for lines starting
with 'server'.
+ :param conf_file_path: a path to the chronyd's configuration file
:return: servers found in the chronyd's configuration
- :rtype: list
-
+ :rtype: a list of TimeSourceData instances
"""
-
- pools = list()
- servers = list()
+ servers = []
try:
with open(conf_file_path, "r") as conf_file:
for line in conf_file:
- match = srv_regexp.match(line)
- if match:
- if match.group(1) == "pool":
- pools.append(match.group(2))
- else:
- servers.append(match.group(2))
+ match = SRV_LINE_REGEXP.match(line)
+
+ if not match:
+ continue
+
+ server = TimeSourceData()
+ server.type = match.group(1).upper()
+ server.hostname = match.group(2)
+ server.options = ["iburst"]
+ servers.append(server)
except IOError as ioerr:
- msg = "Cannot open config file %s for reading (%s)" % (conf_file_path,
- ioerr.strerror)
- raise NTPconfigError(msg)
+ msg = "Cannot open config file {} for reading ({})."
+ raise NTPconfigError(msg.format(conf_file_path, ioerr.strerror))
- return (pools, servers)
+ return servers
-def save_servers_to_config(pools, servers, conf_file_path=NTP_CONFIG_FILE,
- srv_regexp=SRV_LINE_REGEXP, out_file_path=None):
- """
+def save_servers_to_config(servers, conf_file_path=NTP_CONFIG_FILE, out_file_path=None):
+ """Save NTP servers to a configuration file.
+
Replaces the pools and servers defined in the chronyd's configuration file
with the given ones. If the out_file is not None, then it is used for the
resulting config.
- :type pools: iterable
- :type servers: iterable
- :param out_file_path: path to the file used for the resulting config
-
+ :param servers: a list of NTP servers and pools
+ :type servers: a list of TimeSourceData instances
+ :param conf_file_path: a path to the chronyd's configuration file
+ :param out_file_path: a path to the file used for the resulting config
"""
+ temp_path = None
try:
old_conf_file = open(conf_file_path, "r")
-
except IOError as ioerr:
- msg = "Cannot open config file %s for reading (%s)" % (conf_file_path,
- ioerr.strerror)
- raise NTPconfigError(msg)
+ msg = "Cannot open config file {} for reading ({})."
+ raise NTPconfigError(msg.format(conf_file_path, ioerr.strerror))
- try:
- if out_file_path:
+ if out_file_path:
+ try:
new_conf_file = open(out_file_path, "w")
- else:
- (fildes, temp_path) = tempfile.mkstemp()
- new_conf_file = os.fdopen(fildes, "w")
-
- except IOError as ioerr:
- if out_file_path:
- msg = "Cannot open new config file %s "\
- "for writing (%s)" % (out_file_path, ioerr.strerror)
- else:
- msg = "Cannot open temporary file %s "\
- "for writing (%s)" % (temp_path, ioerr.strerror)
-
- raise NTPconfigError(msg)
+ except IOError as ioerr:
+ msg = "Cannot open new config file {} for writing ({})."
+ raise NTPconfigError(msg.format(out_file_path, ioerr.strerror))
+ else:
+ try:
+ (fields, temp_path) = tempfile.mkstemp()
+ new_conf_file = os.fdopen(fields, "w")
+ except IOError as ioerr:
+ msg = "Cannot open temporary file {} for writing ({})."
+ raise NTPconfigError(msg.format(temp_path, ioerr.strerror))
heading = "# These servers were defined in the installation:\n"
- #write info about the origin of the following lines
+ # write info about the origin of the following lines
new_conf_file.write(heading)
- #write new servers and pools
- for pool in pools:
- new_conf_file.write("pool " + pool + " iburst\n")
-
+ # write new servers and pools
for server in servers:
- new_conf_file.write("server " + server + " iburst\n")
+ args = [server.type.lower(), server.hostname] + server.options
+ line = " ".join(args) + "\n"
+ new_conf_file.write(line)
- #copy non-server lines from the old config and skip our heading
+ new_conf_file.write("\n")
+
+ # copy non-server lines from the old config and skip our heading
for line in old_conf_file:
- if not srv_regexp.match(line) and line != heading:
+ if not SRV_LINE_REGEXP.match(line) and line != heading:
new_conf_file.write(line)
old_conf_file.close()
@@ -199,28 +168,27 @@ def save_servers_to_config(pools, servers, conf_file_path=NTP_CONFIG_FILE,
os.unlink(temp_path)
except OSError as oserr:
- msg = "Cannot replace the old config with "\
- "the new one (%s)" % (oserr.strerror)
+ msg = "Cannot replace the old config with the new one ({})."
+ raise NTPconfigError(msg.format(oserr.strerror))
- raise NTPconfigError(msg)
+def _one_time_sync(server, callback=None):
+ """Synchronize the system time with a given NTP server.
-def one_time_sync(server, callback=None):
- """
Synchronize the system time with a given NTP server. Note that this
function is blocking and will not return until the time gets synced or
querying server fails (may take some time before timeouting).
- :param server: NTP server
+ :param server: an NTP server
+ :type server: an instance of TimeSourceData
:param callback: callback function to run after sync or failure
:type callback: a function taking one boolean argument (success)
:return: True if the sync was successful, False otherwise
-
"""
client = ntplib.NTPClient()
try:
- results = client.request(server)
+ results = client.request(server.hostname)
isys.set_system_time(int(results.tx_time))
success = True
except ntplib.NTPException:
@@ -235,22 +203,26 @@ def one_time_sync(server, callback=None):
def one_time_sync_async(server, callback=None):
- """
+ """Asynchronously synchronize the system time with a given NTP server.
+
Asynchronously synchronize the system time with a given NTP server. This
function is non-blocking it starts a new thread for synchronization and
returns. Use callback argument to specify the function called when the
new thread finishes if needed.
- :param server: NTP server
+ :param server: an NTP server
+ :type server: an instance of TimeSourceData
:param callback: callback function to run after sync or failure
:type callback: a function taking one boolean argument (success)
-
"""
+ thread_name = "%s_%s" % (THREAD_SYNC_TIME_BASENAME, server.hostname)
- thread_name = "%s_%s" % (THREAD_SYNC_TIME_BASENAME, server)
+ # syncing with the same server running
if threadMgr.get(thread_name):
- #syncing with the same server running
return
- threadMgr.add(AnacondaThread(name=thread_name, target=one_time_sync,
- args=(server, callback)))
+ threadMgr.add(AnacondaThread(
+ name=thread_name,
+ target=_one_time_sync,
+ args=(server, callback)
+ ))
--
2.23.0

View File

@ -1,406 +0,0 @@
From 4bc1b7305199fffc78439ab1ad1cdb8272988d52 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Fri, 3 Jul 2020 12:21:11 +0200
Subject: [PATCH] Use the structure for time sources in the Timezone module
Modify the Timezone module to work with the DBus structures for time sources
instead of the strings. Rename the DBus property NTPServers to TimeSources.
---
pyanaconda/modules/timezone/installation.py | 14 ++-
pyanaconda/modules/timezone/timezone.py | 44 ++++---
.../modules/timezone/timezone_interface.py | 34 +++---
.../pyanaconda_tests/module_timezone_test.py | 107 ++++++++++++++----
4 files changed, 141 insertions(+), 58 deletions(-)
diff --git a/pyanaconda/modules/timezone/installation.py b/pyanaconda/modules/timezone/installation.py
index 6383df1103..c3ea4d7179 100644
--- a/pyanaconda/modules/timezone/installation.py
+++ b/pyanaconda/modules/timezone/installation.py
@@ -145,12 +145,14 @@ def run(self):
return
chronyd_conf_path = os.path.normpath(self._sysroot + ntp.NTP_CONFIG_FILE)
- pools, servers = ntp.internal_to_pools_and_servers(self._ntp_servers)
if os.path.exists(chronyd_conf_path):
log.debug("Modifying installed chrony configuration")
try:
- ntp.save_servers_to_config(pools, servers, conf_file_path=chronyd_conf_path)
+ ntp.save_servers_to_config(
+ self._ntp_servers,
+ conf_file_path=chronyd_conf_path
+ )
except ntp.NTPconfigError as ntperr:
log.warning("Failed to save NTP configuration: %s", ntperr)
@@ -160,9 +162,11 @@ def run(self):
log.debug("Creating chrony configuration based on the "
"configuration from installation environment")
try:
- ntp.save_servers_to_config(pools, servers,
- conf_file_path=ntp.NTP_CONFIG_FILE,
- out_file_path=chronyd_conf_path)
+ ntp.save_servers_to_config(
+ self._ntp_servers,
+ conf_file_path=ntp.NTP_CONFIG_FILE,
+ out_file_path=chronyd_conf_path
+ )
except ntp.NTPconfigError as ntperr:
log.warning("Failed to save NTP configuration without chrony package: %s",
ntperr)
diff --git a/pyanaconda/modules/timezone/timezone.py b/pyanaconda/modules/timezone/timezone.py
index 0678072978..ff89d1ea77 100644
--- a/pyanaconda/modules/timezone/timezone.py
+++ b/pyanaconda/modules/timezone/timezone.py
@@ -18,10 +18,12 @@
# Red Hat, Inc.
#
from pyanaconda.core.configuration.anaconda import conf
+from pyanaconda.core.constants import TIME_SOURCE_SERVER
from pyanaconda.core.dbus import DBus
from pyanaconda.core.signal import Signal
from pyanaconda.modules.common.base import KickstartService
from pyanaconda.modules.common.constants.services import TIMEZONE
+from pyanaconda.modules.common.structures.timezone import TimeSourceData
from pyanaconda.timezone import NTP_PACKAGE
from pyanaconda.modules.common.containers import TaskContainer
from pyanaconda.modules.common.structures.requirement import Requirement
@@ -48,8 +50,8 @@ def __init__(self):
self.ntp_enabled_changed = Signal()
self._ntp_enabled = True
- self.ntp_servers_changed = Signal()
- self._ntp_servers = []
+ self.time_sources_changed = Signal()
+ self._time_sources = []
# FIXME: temporary workaround until PAYLOAD module is available
self._ntp_excluded = False
@@ -70,7 +72,17 @@ def process_kickstart(self, data):
self.set_timezone(data.timezone.timezone)
self.set_is_utc(data.timezone.isUtc)
self.set_ntp_enabled(not data.timezone.nontp)
- self.set_ntp_servers(data.timezone.ntpservers)
+
+ servers = []
+
+ for hostname in data.timezone.ntpservers:
+ server = TimeSourceData()
+ server.type = TIME_SOURCE_SERVER
+ server.hostname = hostname
+ server.options = ["iburst"]
+ servers.append(server)
+
+ self.set_time_sources(servers)
def setup_kickstart(self, data):
"""Set up the kickstart data."""
@@ -78,8 +90,12 @@ def setup_kickstart(self, data):
data.timezone.isUtc = self.is_utc
data.timezone.nontp = not self.ntp_enabled
- if self.ntp_enabled:
- data.timezone.ntpservers = list(self.ntp_servers)
+ if not self.ntp_enabled:
+ return
+
+ data.timezone.ntpservers = [
+ server.hostname for server in self.time_sources
+ ]
@property
def timezone(self):
@@ -115,15 +131,15 @@ def set_ntp_enabled(self, ntp_enabled):
log.debug("NTP is set to %s.", ntp_enabled)
@property
- def ntp_servers(self):
- """Return a list of NTP servers."""
- return self._ntp_servers
+ def time_sources(self):
+ """Return a list of time sources."""
+ return self._time_sources
- def set_ntp_servers(self, servers):
- """Set NTP servers."""
- self._ntp_servers = list(servers)
- self.ntp_servers_changed.emit()
- log.debug("NTP servers are set to %s.", servers)
+ def set_time_sources(self, servers):
+ """Set time sources."""
+ self._time_sources = list(servers)
+ self.time_sources_changed.emit()
+ log.debug("Time sources are set to: %s", servers)
def collect_requirements(self):
"""Return installation requirements for this module.
@@ -168,6 +184,6 @@ def install_with_tasks(self):
ConfigureNTPTask(
sysroot=conf.target.system_root,
ntp_enabled=self.ntp_enabled,
- ntp_servers=self.ntp_servers
+ ntp_servers=self.time_sources
)
]
diff --git a/pyanaconda/modules/timezone/timezone_interface.py b/pyanaconda/modules/timezone/timezone_interface.py
index 03c5003f1e..f36e0b3723 100644
--- a/pyanaconda/modules/timezone/timezone_interface.py
+++ b/pyanaconda/modules/timezone/timezone_interface.py
@@ -17,13 +17,15 @@
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
-from pyanaconda.modules.common.constants.services import TIMEZONE
-from pyanaconda.modules.common.containers import TaskContainer
from dasbus.server.property import emits_properties_changed
from dasbus.typing import * # pylint: disable=wildcard-import
-from pyanaconda.modules.common.base import KickstartModuleInterface
from dasbus.server.interface import dbus_interface
+from pyanaconda.modules.common.base import KickstartModuleInterface
+from pyanaconda.modules.common.constants.services import TIMEZONE
+from pyanaconda.modules.common.containers import TaskContainer
+from pyanaconda.modules.common.structures.timezone import TimeSourceData
+
@dbus_interface(TIMEZONE.interface_name)
class TimezoneInterface(KickstartModuleInterface):
@@ -34,7 +36,7 @@ def connect_signals(self):
self.watch_property("Timezone", self.implementation.timezone_changed)
self.watch_property("IsUTC", self.implementation.is_utc_changed)
self.watch_property("NTPEnabled", self.implementation.ntp_enabled_changed)
- self.watch_property("NTPServers", self.implementation.ntp_servers_changed)
+ self.watch_property("TimeSources", self.implementation.time_sources_changed)
@property
def Timezone(self) -> Str:
@@ -91,22 +93,26 @@ def SetNTPEnabled(self, ntp_enabled: Bool):
self.implementation.set_ntp_enabled(ntp_enabled)
@property
- def NTPServers(self) -> List[Str]:
- """A list of NTP servers.
+ def TimeSources(self) -> List[Structure]:
+ """A list of time sources.
- :return: a list of servers
+ :return: a list of time source data
+ :rtype: a list of structures of the type TimeSourceData
"""
- return self.implementation.ntp_servers
+ return TimeSourceData.to_structure_list(
+ self.implementation.time_sources
+ )
@emits_properties_changed
- def SetNTPServers(self, servers: List[Str]):
- """Set the NTP servers.
+ def SetTimeSources(self, sources: List[Structure]):
+ """Set the time sources.
- Example: [ntp.cesnet.cz]
-
- :param servers: a list of servers
+ :param sources: a list of time sources
+ :type sources: a list of structures of the type TimeSourceData
"""
- self.implementation.set_ntp_servers(servers)
+ self.implementation.set_time_sources(
+ TimeSourceData.from_structure_list(sources)
+ )
def ConfigureNTPServiceEnablementWithTask(self, ntp_excluded: Bool) -> ObjPath:
"""Enable or disable NTP service.
diff --git a/tests/nosetests/pyanaconda_tests/module_timezone_test.py b/tests/nosetests/pyanaconda_tests/module_timezone_test.py
index f991f1e992..bb751d6f4b 100644
--- a/tests/nosetests/pyanaconda_tests/module_timezone_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_timezone_test.py
@@ -23,8 +23,13 @@
from shutil import copytree, copyfile
from unittest.mock import Mock, patch
+from dasbus.structure import compare_data
+from dasbus.typing import * # pylint: disable=wildcard-import
+
+from pyanaconda.core.constants import TIME_SOURCE_SERVER, TIME_SOURCE_POOL
from pyanaconda.modules.common.constants.services import TIMEZONE
from pyanaconda.modules.common.errors.installation import TimezoneConfigurationError
+from pyanaconda.modules.common.structures.timezone import TimeSourceData
from pyanaconda.modules.timezone.installation import ConfigureNTPTask, ConfigureTimezoneTask, \
ConfigureNTPServiceEnablementTask
from pyanaconda.modules.common.structures.kickstart import KickstartReport
@@ -33,7 +38,7 @@
from pyanaconda.ntp import NTP_CONFIG_FILE, NTPconfigError
from tests.nosetests.pyanaconda_tests import check_kickstart_interface, \
patch_dbus_publish_object, PropertiesChangedCallback, check_task_creation, \
- patch_dbus_get_proxy, check_task_creation_list
+ patch_dbus_get_proxy, check_task_creation_list, check_dbus_property
from pyanaconda.timezone import NTP_SERVICE
@@ -50,6 +55,14 @@ def setUp(self):
self.callback = PropertiesChangedCallback()
self.timezone_interface.PropertiesChanged.connect(self.callback)
+ def _check_dbus_property(self, *args, **kwargs):
+ check_dbus_property(
+ self,
+ TIMEZONE,
+ self.timezone_interface,
+ *args, **kwargs
+ )
+
def kickstart_properties_test(self):
"""Test kickstart properties."""
self.assertEqual(self.timezone_interface.KickstartCommands, ["timezone"])
@@ -76,12 +89,24 @@ def ntp_property_test(self):
self.assertEqual(self.timezone_interface.NTPEnabled, False)
self.callback.assert_called_once_with(TIMEZONE.interface_name, {'NTPEnabled': False}, [])
- def ntp_servers_property_test(self):
- """Test the NTPServers property."""
- self.timezone_interface.SetNTPServers(["ntp.cesnet.cz"])
- self.assertEqual(self.timezone_interface.NTPServers, ["ntp.cesnet.cz"])
- self.callback.assert_called_once_with(
- TIMEZONE.interface_name, {'NTPServers': ["ntp.cesnet.cz"]}, [])
+ def time_sources_property_test(self):
+ """Test the TimeSources property."""
+ server = {
+ "type": get_variant(Str, TIME_SOURCE_SERVER),
+ "hostname": get_variant(Str, "ntp.cesnet.cz"),
+ "options": get_variant(List[Str], ["iburst"]),
+ }
+
+ pool = {
+ "type": get_variant(Str, TIME_SOURCE_POOL),
+ "hostname": get_variant(Str, "0.fedora.pool.ntp.org"),
+ "options": get_variant(List[Str], []),
+ }
+
+ self._check_dbus_property(
+ "TimeSources",
+ [server, pool]
+ )
def _test_kickstart(self, ks_in, ks_out):
check_kickstart_interface(self, self.timezone_interface, ks_in, ks_out)
@@ -162,10 +187,19 @@ def install_with_tasks_configured_test(self, publisher):
self.timezone_interface.SetNTPEnabled(False)
# --nontp and --ntpservers are mutually exclusive in kicstart but
# there is no such enforcement in the module so for testing this is ok
- self.timezone_interface.SetNTPServers([
- "clock1.example.com",
- "clock2.example.com",
- ])
+
+ server = TimeSourceData()
+ server.type = TIME_SOURCE_SERVER
+ server.hostname = "clock1.example.com"
+ server.options = ["iburst"]
+
+ pool = TimeSourceData()
+ pool.type = TIME_SOURCE_POOL
+ pool.hostname = "clock2.example.com"
+
+ self.timezone_interface.SetTimeSources(
+ TimeSourceData.to_structure_list([server, pool])
+ )
task_classes = [
ConfigureTimezoneTask,
@@ -182,10 +216,9 @@ def install_with_tasks_configured_test(self, publisher):
# ConfigureNTPTask
obj = task_objs[1]
self.assertEqual(obj.implementation._ntp_enabled, False)
- self.assertEqual(obj.implementation._ntp_servers, [
- "clock1.example.com",
- "clock2.example.com",
- ])
+ self.assertEqual(len(obj.implementation._ntp_servers), 2)
+ self.assertTrue(compare_data(obj.implementation._ntp_servers[0], server))
+ self.assertTrue(compare_data(obj.implementation._ntp_servers[1], pool))
@patch_dbus_publish_object
def configure_ntp_service_enablement_default_test(self, publisher):
@@ -354,13 +387,13 @@ class NTPTasksTestCase(unittest.TestCase):
def ntp_task_success_test(self):
"""Test the success cases for NTP setup D-Bus task."""
- self._test_ntp_inputs(False, False, ["unique.ntp.server", "another.unique.server"])
- self._test_ntp_inputs(False, True, ["unique.ntp.server", "another.unique.server"])
+ self._test_ntp_inputs(False, False)
+ self._test_ntp_inputs(False, True)
def ntp_overwrite_test(self):
"""Test overwriting existing config for NTP setup D-Bus task."""
- self._test_ntp_inputs(True, True, ["unique.ntp.server", "another.unique.server"])
- self._test_ntp_inputs(True, False, ["unique.ntp.server", "another.unique.server"])
+ self._test_ntp_inputs(True, True)
+ self._test_ntp_inputs(True, False)
def ntp_save_failure_test(self):
"""Test failure when saving NTP config in D-Bus task."""
@@ -368,6 +401,25 @@ def ntp_save_failure_test(self):
self._test_ntp_exception(True)
self._test_ntp_exception(False)
+ def _get_test_sources(self):
+ """Get a list of sources"""
+ server = TimeSourceData()
+ server.type = TIME_SOURCE_SERVER
+ server.hostname = "unique.ntp.server"
+ server.options = ["iburst"]
+
+ pool = TimeSourceData()
+ pool.type = TIME_SOURCE_POOL
+ pool.hostname = "another.unique.server"
+
+ return [server, pool]
+
+ def _get_expected_lines(self):
+ return [
+ "server unique.ntp.server iburst\n",
+ "pool another.unique.server\n"
+ ]
+
@patch("pyanaconda.modules.timezone.installation.ntp.save_servers_to_config",
side_effect=NTPconfigError)
def _test_ntp_exception(self, make_chronyd, mock_save):
@@ -376,11 +428,14 @@ def _test_ntp_exception(self, make_chronyd, mock_save):
with self.assertLogs("anaconda.modules.timezone.installation", level="WARNING"):
self._execute_task(sysroot, True, ["ntp.example.com"])
- def _test_ntp_inputs(self, make_chronyd, ntp_enabled, ntp_servers):
+ def _test_ntp_inputs(self, make_chronyd, ntp_enabled):
+ ntp_servers = self._get_test_sources()
+ expected_lines = self._get_expected_lines()
+
with tempfile.TemporaryDirectory() as sysroot:
self._setup_environment(sysroot, make_chronyd)
self._execute_task(sysroot, ntp_enabled, ntp_servers)
- self._validate_ntp_config(sysroot, make_chronyd, ntp_enabled, ntp_servers)
+ self._validate_ntp_config(sysroot, make_chronyd, ntp_enabled, expected_lines)
def _setup_environment(self, sysroot, make_chronyd):
os.mkdir(sysroot + "/etc")
@@ -395,12 +450,14 @@ def _execute_task(self, sysroot, ntp_enabled, ntp_servers):
)
task.run()
- def _validate_ntp_config(self, sysroot, was_present, was_enabled, expected_servers):
+ def _validate_ntp_config(self, sysroot, was_present, was_enabled, expected_lines):
if was_enabled:
with open(sysroot + NTP_CONFIG_FILE) as fobj:
- all_lines = "\n".join(fobj.readlines())
- for server in expected_servers:
- self.assertIn(server, all_lines)
+ all_lines = fobj.readlines()
+
+ for line in expected_lines:
+ self.assertIn(line, all_lines)
+
elif not was_present:
self.assertFalse(os.path.exists(sysroot + NTP_CONFIG_FILE))
--
2.23.0

Some files were not shown because too many files have changed in this diff Show More