From 7dc41d9a1f3d0e3dfa48838cf0e75c2f0f04e207 Mon Sep 17 00:00:00 2001
From: sun_hai_10 <sunhai10@huawei.com>
Date: Sun, 25 Jun 2023 15:01:25 +0800
Subject: [PATCH] change the startup mode of do_transaction sub proces

---
 .../payloads/payload/dnf/dnf_manager.py       | 109 ++++++++++++++++--
 1 file changed, 102 insertions(+), 7 deletions(-)

diff --git a/pyanaconda/modules/payloads/payload/dnf/dnf_manager.py b/pyanaconda/modules/payloads/payload/dnf/dnf_manager.py
index b1f452c..c73f3d9 100644
--- a/pyanaconda/modules/payloads/payload/dnf/dnf_manager.py
+++ b/pyanaconda/modules/payloads/payload/dnf/dnf_manager.py
@@ -67,6 +67,50 @@ DNF_PLUGINCONF_DIR = '/tmp/dnf.pluginconf'
 #
 DNF_EXTRA_SIZE_PER_FILE = Size("6 KiB")
 
+g_include_list = []
+g_exclude_list = []
+
+def update_conf(conf, substitutions, releasever, installroot, multilib_policy, timeout, retries):
+    conf.cachedir = DNF_CACHE_DIR
+    conf.pluginconfpath = DNF_PLUGINCONF_DIR
+    conf.logdir = '/tmp/'
+
+    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 = DNF_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, ignore_broken_packages, ignore_missing_packages):
+    base.fill_sack()
+    base.read_comps()
+
+    try:
+        base.install_specs(
+            install=include_list,
+            exclude=exclude_list,
+            strict=not ignore_broken_packages
+        )
+    except dnf.exceptions.MarkingErrors as e:
+        log.error("Failed to apply specs!\n%s", str(e))
+        if ignore_missing_packages:
+            log.info("Ignoring missing packages, groups or modules.")
+        else:
+            message = _("Some packages, groups or modules are missing.")
+            raise MissingSpecsError(message + "\n\n" + str(e).strip()) from None
+
+    base.resolve()
 
 class DNFManagerError(Exception):
     """General error for the DNF manager."""
@@ -555,6 +599,10 @@ class DNFManager(object):
         log.info("Including specs: %s", include_list)
         log.info("Excluding specs: %s", exclude_list)
 
+        global g_include_list, g_exclude_list
+        g_include_list = list(include_list)
+        g_exclude_list = list(exclude_list)
+
         try:
             self._base.install_specs(
                 install=include_list,
@@ -664,12 +712,35 @@ class DNFManager(object):
         :param timeout: a time out of a failed process in seconds
         :raise PayloadInstallationError: if the installation fails
         """
-        queue = multiprocessing.Queue()
-        display = TransactionProgress(queue)
-        process = multiprocessing.Process(
-            target=self._run_transaction,
-            args=(self._base, display)
-        )
+        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 = ctx.Queue()
+        process = ctx.Process(target=self._run_transaction,
+            args=(queue, 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,
+                  self._ignore_broken_packages,
+                  self._ignore_missing_packages))
 
         # Start the transaction.
         log.debug("Starting the transaction process...")
@@ -688,7 +759,10 @@ class DNFManager(object):
             log.debug("The transaction process exited with %s.", process.exitcode)
 
     @staticmethod
-    def _run_transaction(base, display):
+    def _run_transaction(queue_instance, repos, releasever, installroot, substitutions,
+                         multilib_policy, timeout, retries, pkgdir, proxy,
+                         proxy_username, proxy_password, include_list, exclude_list,
+                         ignore_broken_packages, ignore_missing_packages):
         """Run the DNF transaction.
 
         Execute the DNF transaction and catch any errors. An error
@@ -702,6 +776,27 @@ class DNFManager(object):
         exit_reason = None
 
         try:
+            display = TransactionProgress(queue_instance)
+
+            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, ignore_broken_packages, ignore_missing_packages)
+            queue_instance.put(('log', 'start to transaction.'))
+
             base.do_transaction(display)
             exit_reason = "DNF done"
         except BaseException as e:  # pylint: disable=broad-except
-- 
2.19.1

