1 Star 0 Fork 23

guyu/anaconda

forked from src-anolis-os/anaconda 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0005-install-add-anolis-install-files.patch 31.54 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
From 07aac35b8827fd46ac3967617c174486467c2b86 Mon Sep 17 00:00:00 2001
From: Liwei Ge <geliwei@openanolis.org>
Date: Fri, 13 May 2022 15:36:29 +0800
Subject: [PATCH 5/7] install: add anolis install files
add anolis install class
add kernel selection spoke
---
data/product.d/anolis.conf | 33 +++
pyanaconda/payload/dnf/payload.py | 61 +++-
.../ui/gui/spokes/kernel_selection.glade | 125 ++++++++
pyanaconda/ui/gui/spokes/kernel_selection.py | 278 ++++++++++++++++++
.../ui/gui/spokes/software_selection.py | 2 +-
pyanaconda/ui/tui/spokes/kernel_selection.py | 219 ++++++++++++++
.../ui/tui/spokes/software_selection.py | 2 +-
7 files changed, 717 insertions(+), 3 deletions(-)
create mode 100644 data/product.d/anolis.conf
create mode 100644 pyanaconda/ui/gui/spokes/kernel_selection.glade
create mode 100644 pyanaconda/ui/gui/spokes/kernel_selection.py
create mode 100644 pyanaconda/ui/tui/spokes/kernel_selection.py
diff --git a/data/product.d/anolis.conf b/data/product.d/anolis.conf
new file mode 100644
index 0000000..f3e0386
--- /dev/null
+++ b/data/product.d/anolis.conf
@@ -0,0 +1,33 @@
+# Anaconda configuration file for AnolisOS Linux.
+
+[Product]
+product_name = Anolis OS
+
+[Base Product]
+product_name = Red Hat Enterprise Linux
+
+[Anaconda]
+# List of enabled Anaconda DBus modules for RHEL.
+# but without org.fedoraproject.Anaconda.Modules.Subscription
+kickstart_modules =
+ org.fedoraproject.Anaconda.Modules.Timezone
+ org.fedoraproject.Anaconda.Modules.Network
+ org.fedoraproject.Anaconda.Modules.Localization
+ org.fedoraproject.Anaconda.Modules.Security
+ org.fedoraproject.Anaconda.Modules.Users
+ org.fedoraproject.Anaconda.Modules.Payloads
+ org.fedoraproject.Anaconda.Modules.Storage
+ org.fedoraproject.Anaconda.Modules.Services
+
+[Bootloader]
+efi_dir = anolis
+
+[User Interface]
+help_directory = /usr/share/anaconda/help/rhel
+default_help_pages =
+ anolis_help_placeholder.txt
+ anolis_help_placeholder.xml
+ anolis_help_placeholder.xml
+
+[Payload]
+default_source = CLOSEST_MIRROR
diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py
index 3b9a806..1a9249e 100644
--- a/pyanaconda/payload/dnf/payload.py
+++ b/pyanaconda/payload/dnf/payload.py
@@ -40,9 +40,9 @@ from blivet.size import Size
from dnf.const import GROUP_PACKAGE_TYPES
from fnmatch import fnmatch
from glob import glob
+from collections import OrderedDict
from pyanaconda.modules.common.structures.payload import RepoConfigurationData
-from pyanaconda.modules.payloads.payload.dnf.installation import UpdateDNFConfigurationTask
from pyanaconda.payload.source import SourceFactory, PayloadSourceTypeUnrecognized
from pykickstart.constants import GROUP_ALL, GROUP_DEFAULT, KS_MISSING_IGNORE, GROUP_REQUIRED
from pykickstart.parser import Group
@@ -131,6 +131,9 @@ class DNFPayload(Payload):
# save repomd metadata
self._repoMD_list = []
+ self._available_kernels = OrderedDict()
+ self._current_kernel = None
+
self._req_groups = set()
self._req_packages = set()
self.requirements.set_apply_callback(self._apply_requirements)
@@ -776,6 +779,62 @@ class DNFPayload(Payload):
return kernels
+ def isCompatibleKernel(self, kernel_version):
+ # ZHAOXIN KaiSheng KH-37800D@2.7GHz
+ # Hygon C86 7280 32-core Processor
+ # Phytium,D2000/8,FT-2000+/64,S2500,FT2004
+ if kernel_version == "4.18.0":
+ f_cpuinfo = os.popen('dmidecode -s processor-version')
+ cpuinfo = f_cpuinfo.readlines()
+ f_cpuinfo.close()
+ for line in cpuinfo:
+ if "Hygon" in line or "ZHAOXIN" in line or "Phytium" in line or "FT-2000+/64" in line or "S2500" in line or "FT2004" in line:
+ return False
+ return True
+
+ def detectMultiKernel(self):
+ kernel_patterns=["kernel", "kernel-tools", "python3-perf", "kernel-headers", "kernel-devel", "bpftool", "perf"]
+ self._available_kernels = {}
+
+ if not self._base.sack:
+ ret_msg = "Query is not ready yet"
+ log.info(ret_msg)
+ return ret_msg
+
+ # Get exception, when repo's format is wrong (eg. wrong repo url by inst.addrepo or inst.repo)
+ ypl = self._base._do_package_lists("available", kernel_patterns, True)
+ if not ypl or not ypl.available:
+ ret_msg = "No kernel is detected"
+ log.info(ret_msg)
+ return ret_msg
+
+ for pkg in ypl.available:
+ if not self.isCompatibleKernel(pkg.version):
+ continue
+ kernel_key = "%s" % (pkg.version)
+ kernel_sub_key = "%s" % (pkg.release)
+ if kernel_key in self._available_kernels:
+ if kernel_sub_key in self._available_kernels[kernel_key]:
+ self._available_kernels[kernel_key][kernel_sub_key].append("%s-%s" % (pkg.name, pkg.version))
+ else:
+ self._available_kernels[kernel_key][kernel_sub_key] = ["%s-%s" % (pkg.name, pkg.version)]
+ else:
+ self._available_kernels[kernel_key] = OrderedDict()
+ self._available_kernels[kernel_key][kernel_sub_key] = ["%s-%s" % (pkg.name, pkg.version)]
+ return None
+
+ @property
+ def available_kernels(self):
+ return self._available_kernels
+
+ @property
+ def current_kernel(self):
+ return self._current_kernel
+
+ @current_kernel.setter
+ def current_kernel(self, value):
+ self._current_kernel = value
+
def _get_kernel_package(self):
kernels = self.kernel_packages
selected_kernel_package = None
diff --git a/pyanaconda/ui/gui/spokes/kernel_selection.glade b/pyanaconda/ui/gui/spokes/kernel_selection.glade
new file mode 100644
index 0000000..ae2c2c7
--- /dev/null
+++ b/pyanaconda/ui/gui/spokes/kernel_selection.glade
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+ <requires lib="gtk+" version="3.10"/>
+ <requires lib="AnacondaWidgets" version="1.0"/>
+ <object class="AnacondaSpokeWindow" id="kernelWindow">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="window_name" translatable="yes">KERNEL SELECTION</property>
+ <signal name="button-clicked" handler="on_back_clicked" swapped="no"/>
+ <child internal-child="main_box">
+ <object class="GtkBox" id="AnacondaSpokeWindow-main_box1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child internal-child="nav_box">
+ <object class="GtkEventBox" id="AnacondaSpokeWindow-nav_box1">
+ <property name="can_focus">False</property>
+ <child internal-child="nav_area">
+ <object class="GtkGrid" id="AnacondaSpokeWindow-nav_area1">
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="alignment">
+ <object class="GtkAlignment" id="AnacondaSpokeWindow-alignment1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="top_padding">12</property>
+ <property name="bottom_padding">48</property>
+ <property name="left_padding">24</property>
+ <property name="right_padding">24</property>
+ <child internal-child="action_area">
+ <object class="GtkBox" id="AnacondaSpokeWindow-action_area1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">6</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Kernel Selection</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="font-desc" value="Cantarell 12"/>
+ <attribute name="weight" value="normal"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="kernelScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_STRUCTURE_MASK | GDK_SCROLL_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="kernelViewport">
+ <property name="width_request">250</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkListBox" id="kernelListBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <signal name="row-activated" handler="on_kernel_activated" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/pyanaconda/ui/gui/spokes/kernel_selection.py b/pyanaconda/ui/gui/spokes/kernel_selection.py
new file mode 100644
index 0000000..d836e51
--- /dev/null
+++ b/pyanaconda/ui/gui/spokes/kernel_selection.py
@@ -0,0 +1,278 @@
+# kernel selection spoke classes
+#
+# Copyright (C) 2021 OpenAnolis Community
+#
+import re
+import gi
+import time
+
+gi.require_version("Gtk", "3.0")
+gi.require_version("Pango", "1.0")
+
+from gi.repository import Gtk, Pango
+
+from pyanaconda.flags import flags
+from pyanaconda.core.i18n import _, C_, CN_
+from pyanaconda.threading import threadMgr, AnacondaThread
+from pyanaconda.payload.manager import payloadMgr, PayloadState
+from pyanaconda.payload.base import Payload
+from pyanaconda.payload.errors import NoSuchGroup, PayloadError, DependencyError
+
+from pyanaconda.core import util, constants
+
+from pyanaconda.ui.communication import hubQ
+from pyanaconda.ui.gui.spokes import NormalSpoke
+from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
+from pyanaconda.ui.gui.utils import blockedHandler, escape_markup
+from pyanaconda.core.async_utils import async_action_wait
+from pyanaconda.ui.categories.software import SoftwareCategory
+
+from pyanaconda.anaconda_loggers import get_module_logger
+log = get_module_logger(__name__)
+
+import sys, copy
+
+__all__ = ["KernelSelectionSpoke"]
+
+class KernelSelectionSpoke(NormalSpoke):
+ builderObjects = ["kernelWindow"]
+ mainWidgetName = "kernelWindow"
+ uiFile = "spokes/kernel_selection.glade"
+ help_id = "KernelSelectionSpoke"
+
+ category = SoftwareCategory
+
+ #icon = "applications-system"
+ icon = "package-x-generic-symbolic"
+ title = CN_("GUI|Spoke", "_Kernel Selection")
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self._error_msgs = None
+ self._error = False
+
+ self._orig_kernel = None
+
+ self._kickstarted = flags.automatedInstall and self.data.packages.seen
+
+ self._kernelListBox = self.builder.get_object("kernelListBox")
+ self._kernelViewport = self.builder.get_object("kernelViewport")
+ self._kernelListBox.set_focus_vadjustment(Gtk.Scrollable.get_vadjustment(self._kernelViewport))
+
+ self._fakeRadio = Gtk.RadioButton(group=None)
+ self._fakeRadio.set_active(True)
+
+ # Register event listeners to update our status on payload events
+ payloadMgr.add_listener(PayloadState.ERROR, self._payload_error)
+ payloadMgr.add_listener(PayloadState.FINISHED, self._payload_finished)
+
+ payloadMgr.add_listener(PayloadState.DOWNLOADING_PKG_METADATA,
+ self._downloading_package_md)
+ payloadMgr.add_listener(PayloadState.DOWNLOADING_GROUP_METADATA,
+ self._downloading_group_md)
+
+ # Payload event handlers
+ def _downloading_package_md(self):
+ # Reset the error state from previous payloads
+ self._error = False
+ hubQ.send_message(self.__class__.__name__, _(constants.PAYLOAD_STATUS_PACKAGE_MD))
+
+ def _downloading_group_md(self):
+ hubQ.send_message(self.__class__.__name__, _(constants.PAYLOAD_STATUS_GROUP_MD))
+
+ def _payload_error(self):
+ self._error = True
+ hubQ.send_message(self.__class__.__name__, payloadMgr.error)
+
+ def _payload_finished(self):
+ self._error_msgs = self.payload.detectMultiKernel()
+ if not self._error_msgs:
+ # use latest kernel as default, normally it's anck
+ self.current_kernel = list(self.available_kernels.keys())[-1]
+
+ @property
+ def available_kernels(self):
+ return self.payload.available_kernels
+
+ @property
+ def current_kernel(self):
+ return self.payload.current_kernel
+
+ @current_kernel.setter
+ def current_kernel(self, value):
+ self.payload.current_kernel = value
+
+ def apply(self):
+ self._apply()
+
+ def _apply(self):
+ hubQ.send_not_ready(self.__class__.__name__)
+ hubQ.send_not_ready("SourceSpoke")
+ threadMgr.add(AnacondaThread(name="AnaCheckKernel", target=self.checkKernelSelection))
+
+ def checkKernelSelection(self):
+ if self._kickstarted:
+ kernel_pattern=re.compile(r"kernel-[4,5].\d+.\d+")
+ for package in self.payload.data.packages.packageList:
+ if kernel_pattern.search(package):
+ self.current_kernel = package.split('-')[1]
+
+ # we do this only kernel changed
+ if self.changed:
+ kernel_keys = self.available_kernels.keys()
+ for kernel in kernel_keys:
+ kernel_sub_keys = list(self.available_kernels[kernel].keys())
+ if kernel == self.current_kernel:
+ include_kernel = self.available_kernels[kernel][kernel_sub_keys[-1]]
+ self.payload.data.packages.packageList.extend(include_kernel)
+ for package in include_kernel:
+ if package in self.payload.data.packages.excludedList:
+ self.payload.data.packages.excludedList.remove(package)
+ else:
+ exclude_kernel = self.available_kernels[kernel][kernel_sub_keys[-1]]
+ self.payload.data.packages.excludedList.extend(exclude_kernel)
+ for package in exclude_kernel:
+ if package in self.payload.data.packages.packageList:
+ self.payload.data.packages.packageList.remove(package)
+
+ # store kernel selection
+ self._orig_kernel = self.current_kernel
+
+ hubQ.send_ready(self.__class__.__name__, False)
+ hubQ.send_ready("SourceSpoke", False)
+
+ def initialize(self):
+ super().initialize()
+ self.initialize_start()
+ threadMgr.add(AnacondaThread(name="AnaKernelWatcher", target=self._initialize))
+
+ def _initialize(self):
+ threadMgr.wait(constants.THREAD_PAYLOAD)
+
+ if not self._kickstarted:
+ if not self._first_refresh():
+ return
+
+ hubQ.send_ready(self.__class__.__name__, False)
+
+ if not self._error:
+ self._apply()
+
+ self.initialize_done()
+
+ @property
+ def completed(self):
+ processingDone = bool(not threadMgr.get("AnaCheckKernel") and
+ not threadMgr.get(constants.THREAD_PAYLOAD) and
+ self.current_kernel is not None)
+
+ if processingDone:
+ return True
+
+ @property
+ def changed(self):
+ if self.current_kernel == self._orig_kernel:
+ return False
+ else:
+ return True
+
+ @property
+ def mandatory(self):
+ return True
+
+ @property
+ def ready(self):
+ return bool(not threadMgr.get("AnaKernelWatcher") and
+ not threadMgr.get(constants.THREAD_PAYLOAD) and
+ not threadMgr.get("AnaCheckKernel") and
+ self.payload.base_repo is not None)
+
+ @property
+ def showable(self):
+ return isinstance(self.payload, Payload)
+
+ @property
+ def status(self):
+ if not self.ready:
+ return _("Installation source not set up")
+
+ if self._error_msgs:
+ return _(self._error_msgs)
+
+ if not flags.automatedInstall:
+ if not self.current_kernel:
+ return _("Please confirm kernel selection")
+
+ return self.current_kernel
+
+
+ def _add_row(self, listbox, name, desc, button, clicked):
+ row = Gtk.ListBoxRow()
+ box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
+
+ button.set_valign(Gtk.Align.START)
+ button.connect("toggled", clicked, row)
+ box.add(button)
+
+ label = Gtk.Label(label="<b>%s</b>\n%s" % (escape_markup(name), escape_markup(desc)),
+ use_markup=True, wrap=True, wrap_mode=Pango.WrapMode.WORD_CHAR,
+ hexpand=True, xalign=0, yalign=0.5)
+ box.add(label)
+
+ row.add(box)
+ listbox.insert(row, -1)
+
+ @async_action_wait
+ def _first_refresh(self):
+ self.refresh()
+ return True
+
+ def refresh(self):
+ super().refresh()
+
+ threadMgr.wait(constants.THREAD_PAYLOAD)
+
+ self._clear_listbox(self._kernelListBox)
+
+ kernel_keys = self.available_kernels.keys()
+ for kernel in kernel_keys:
+ kernel_sub_keys = list(self.available_kernels[kernel].keys())
+ radio = Gtk.RadioButton(group=self._fakeRadio)
+ if not self.current_kernel:
+ self.current_kernel = kernel
+ radio.set_active(self.current_kernel and kernel == self.current_kernel)
+ if kernel == '4.18.0':
+ kernel_desc = _("RHCK")
+ kernel_info = _("Compatible with RHEL")
+ elif kernel == '4.19.91':
+ kernel_desc = _("ANCK")
+ kernel_info = _("Support Anolis OS verified platform")
+ else:
+ kernel_desc = ''
+ kernel_info = ''
+
+ self._add_row(self._kernelListBox, "%s (%s)" % (kernel, kernel_desc), "%s (%s)" % (kernel_info, self.available_kernels[kernel][kernel_sub_keys[-1]][0]), radio, self.on_radio_button_toggled)
+
+ self._kernelListBox.show_all()
+
+ def _clear_listbox(self, listbox):
+ for child in listbox.get_children():
+ listbox.remove(child)
+ del(child)
+
+ # Signal handlers
+ def on_radio_button_toggled(self, radio, row):
+ # If the radio button toggled to inactive, don't reactivate the row
+ if not radio.get_active():
+ return
+ row.activate()
+
+ def on_kernel_activated(self, listbox, row):
+ box = row.get_children()[0]
+ button = box.get_children()[0]
+
+ with blockedHandler(button, self.on_radio_button_toggled):
+ button.set_active(True)
+
+ kernel_keys = list(self.available_kernels.keys())
+ self.current_kernel=kernel_keys[row.get_index()]
diff --git a/pyanaconda/ui/gui/spokes/software_selection.py b/pyanaconda/ui/gui/spokes/software_selection.py
index 66c0cda..afcb462 100644
--- a/pyanaconda/ui/gui/spokes/software_selection.py
+++ b/pyanaconda/ui/gui/spokes/software_selection.py
@@ -201,7 +201,7 @@ class SoftwareSelectionSpoke(NormalSpoke):
addons = self._get_selected_addons()
if not self._kickstarted and set(addons) != set(self._orig_addons):
self._select_flag = False
- self.payload.data.packages.packageList = []
+ #self.payload.data.packages.packageList = []
self.payload.data.packages.groupList = []
self.payload.select_environment(self.environment)
log.debug("Environment selected for installation: %s", self.environment)
diff --git a/pyanaconda/ui/tui/spokes/kernel_selection.py b/pyanaconda/ui/tui/spokes/kernel_selection.py
new file mode 100644
index 0000000..cd144c1
--- /dev/null
+++ b/pyanaconda/ui/tui/spokes/kernel_selection.py
@@ -0,0 +1,219 @@
+# Copyright (C) 2021 OpenAnolis Community
+#
+#
+import re
+from pyanaconda.flags import flags
+from pyanaconda.ui.categories.software import SoftwareCategory
+from pyanaconda.ui.tui.spokes import NormalTUISpoke
+from pyanaconda.threading import threadMgr, AnacondaThread
+from pyanaconda.payload.manager import payloadMgr, PayloadState
+from pyanaconda.payload.errors import DependencyError, NoSuchGroup
+from pyanaconda.core.i18n import N_, _, C_
+
+from pyanaconda.core.constants import THREAD_PAYLOAD, THREAD_CHECK_SOFTWARE, \
+ THREAD_SOFTWARE_WATCHER, PAYLOAD_TYPE_DNF
+
+from simpleline.render.containers import ListColumnContainer
+from simpleline.render.screen import InputState
+from simpleline.render.screen_handler import ScreenHandler
+from simpleline.render.widgets import TextWidget, CheckboxWidget
+
+from pyanaconda.anaconda_loggers import get_module_logger
+log = get_module_logger(__name__)
+
+__all__ = ["KernelSpoke"]
+
+
+class KernelSpoke(NormalTUISpoke):
+ """ Spoke used to read new value of text to represent source repo.
+
+ .. inheritance-diagram:: SoftwareSpoke
+ :parts: 3
+ """
+ help_id = "KernelSelectionSpoke"
+ category = SoftwareCategory
+
+ def __init__(self, data, storage, payload):
+ super().__init__(data, storage, payload)
+ self.title = N_("Kernel selection")
+ self._container = None
+ self.errors = []
+
+ self._orig_kernel = None
+ self._kickstarted = flags.automatedInstall and self.data.packages.seen
+
+ payloadMgr.add_listener(PayloadState.STARTED, self._payload_start)
+ payloadMgr.add_listener(PayloadState.FINISHED, self._payload_finished)
+ payloadMgr.add_listener(PayloadState.ERROR, self._payload_error)
+
+ def _payload_start(self):
+ # Source is changing, invalidate the software selection and clear the
+ # errors
+ self.errors = []
+ self.current_kernel = None
+
+ def _payload_finished(self):
+ msgs = self.payload.detectMultiKernel()
+ if not msgs:
+ # use latest kernel as default, normally it's anck
+ self.current_kernel = list(self.available_kernels.keys())[-1]
+
+ def _payload_error(self):
+ self.errors = [payloadMgr.error]
+
+ def initialize(self):
+ self.initialize_start()
+ super().initialize()
+ threadMgr.add(AnacondaThread(name="AnaKernelWatcher", target=self._initialize))
+
+ def _initialize(self):
+ threadMgr.wait(THREAD_PAYLOAD)
+
+ self._apply()
+
+ threadMgr.wait("AnaCheckKernel")
+ self.initialize_done()
+
+ @property
+ def changed(self):
+ if self.current_kernel == self._orig_kernel:
+ return False
+ else:
+ return True
+
+ @property
+ def showable(self):
+ return self.payload.type == PAYLOAD_TYPE_DNF
+
+ @property
+ def status(self):
+ if not self.payload.base_repo:
+ return _("Installation source not set up")
+
+ if not self.ready:
+ return _("Processing...")
+
+ if self.errors:
+ return _("Error checking kernel selection")
+
+ if not self._kickstarted:
+ if not self.current_kernel:
+ return _("Please confirm kernel selection")
+
+ return self.current_kernel
+
+ @property
+ def completed(self):
+ processing_done = self.ready and not self.errors
+ return processing_done and self.payload.base_repo
+
+ def refresh(self, args=None):
+ """ Refresh screen. """
+ NormalTUISpoke.refresh(self, args)
+
+ threadMgr.wait(THREAD_PAYLOAD)
+ self._container = None
+
+ if not self.payload.base_repo:
+ message = TextWidget(_("Installation source needs to be set up first."))
+ self.window.add_with_separator(message)
+ return
+
+ threadMgr.wait("AnaCheckKernel")
+ self._container = ListColumnContainer(2, columns_width=38, spacing=2)
+
+ msg = self._refresh_kernels()
+
+ self.window.add_with_separator(TextWidget(msg))
+ self.window.add_with_separator(self._container)
+
+ def _refresh_kernels(self):
+ kernel_keys = self.available_kernels.keys()
+ for kernel in kernel_keys:
+ selected = (self.current_kernel == kernel)
+ if kernel == '4.18.0':
+ kernel_desc = _("RHCK")
+ kernel_info = _("Compatible with RHEL")
+ elif kernel == '4.19.91':
+ kernel_desc = _("ANCK")
+ kernel_info = _("Support Anolis OS verified platform")
+ else:
+ kernel_desc = ''
+ kernel_info = ''
+ widget = CheckboxWidget(title="%s (%s)" % (kernel, kernel_desc), completed=selected)
+ self._container.add(widget, callback=self._set_kernel_callback, data=kernel)
+
+ return _("Kernel List")
+
+ def _set_kernel_callback(self, data):
+ self.current_kernel = data
+
+ def input(self, args, key):
+ if self._container is not None and self._container.process_user_input(key):
+ self.redraw()
+ else:
+ # TRANSLATORS: 'c' to continue
+ if key.lower() == C_('TUI|Spoke Navigation', 'c'):
+
+ if self.current_kernel is None:
+ self.close()
+ else:
+ self.apply()
+ self.close()
+ else:
+ return super().input(args, key)
+
+ return InputState.PROCESSED
+
+ @property
+ def ready(self):
+ """ If we're ready to move on. """
+ return (not threadMgr.get(THREAD_PAYLOAD) and
+ not threadMgr.get("AnaCheckKernel") and
+ not threadMgr.get("AnaKernelWatcher"))
+
+ @property
+ def available_kernels(self):
+ return self.payload.available_kernels
+
+ @property
+ def current_kernel(self):
+ return self.payload.current_kernel
+
+ @current_kernel.setter
+ def current_kernel(self, value):
+ self.payload.current_kernel = value
+
+ def apply(self):
+ self._apply()
+
+ def _apply(self):
+ threadMgr.add(AnacondaThread(name="AnaCheckKernel", target=self.checkKernelSelection))
+
+ def checkKernelSelection(self):
+ if self._kickstarted:
+ kernel_pattern=re.compile(r"kernel-[4,5].\d+.\d+")
+ for package in self.payload.data.packages.packageList:
+ if kernel_pattern.search(package):
+ self.current_kernel = package.split('-')[1]
+
+ # we do this only kernel changed
+ if self.changed:
+ kernel_keys = self.available_kernels.keys()
+ for kernel in kernel_keys:
+ kernel_sub_keys = list(self.available_kernels[kernel].keys())
+ if kernel == self.current_kernel:
+ include_kernel = self.available_kernels[kernel][kernel_sub_keys[-1]]
+ self.payload.data.packages.packageList.extend(include_kernel)
+ for package in include_kernel:
+ if package in self.payload.data.packages.excludedList:
+ self.payload.data.packages.excludedList.remove(package)
+ else:
+ exclude_kernel = self.available_kernels[kernel][kernel_sub_keys[-1]]
+ self.payload.data.packages.excludedList.extend(exclude_kernel)
+ for package in exclude_kernel:
+ if package in self.payload.data.packages.packageList:
+ self.payload.data.packages.packageList.remove(package)
+
+ # store kernel selection
+ self._orig_kernel = self.current_kernel
diff --git a/pyanaconda/ui/tui/spokes/software_selection.py b/pyanaconda/ui/tui/spokes/software_selection.py
index 87a7611..19a9513 100644
--- a/pyanaconda/ui/tui/spokes/software_selection.py
+++ b/pyanaconda/ui/tui/spokes/software_selection.py
@@ -312,7 +312,7 @@ class SoftwareSpoke(NormalTUISpoke):
log.debug("Setting new software selection old env %s, new env %s and addons %s",
self._orig_env, self.environment, self.addons)
- self.payload.data.packages.packageList = []
+ #self.payload.data.packages.packageList = []
self.data.packages.groupList = []
self.payload.select_environment(self.environment)
--
2.27.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/guyvwang/anaconda.git
git@gitee.com:guyvwang/anaconda.git
guyvwang
anaconda
anaconda
a8

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385