Support to install the updated packages while re-creating image.
authorwanchao-xu <wanchao.xu@samsung.com>
Wed, 14 Aug 2024 07:39:21 +0000 (15:39 +0800)
committerwanchao-xu <wanchao.xu@samsung.com>
Thu, 15 Aug 2024 09:19:49 +0000 (17:19 +0800)
Change-Id: Ief4d79ce92e80946ef5806dc57dc95cbf17bf167
Signed-off-by: wanchao-xu <wanchao.xu@samsung.com>
mic/imager/baseimager.py
plugins/backend/zypppkgmgr.py
plugins/imager/loop_plugin.py
tools/mic

index e3669ed2e279e25945bc97c9b2a18104ec828c26..9a04d9eb54f0f6a4d08926db1249b9bb7998c0ae 100644 (file)
@@ -961,6 +961,22 @@ class BaseImageCreator(object):
 
         return None
 
+    def __update_packages(self, pkg_manager, updated_pkgs):
+        skipped_pkgs = []
+        for pkg in updated_pkgs:
+            e = pkg_manager.updatePackage(pkg)
+            if e:
+                if kickstart.ignore_missing(self.ks):
+                    skipped_pkgs.append(pkg)
+                elif self.__is_excluded_pkg(pkg):
+                    skipped_pkgs.append(pkg)
+                else:
+                    raise CreatorError("Failed to find package '%s' : %s" %
+                                       (pkg, e))
+
+        for pkg in skipped_pkgs:
+            msger.warning("Skipping missing package '%s'" % (pkg))
+
     def __select_packages(self, pkg_manager):
         skipped_pkgs = []
         for pkg in self._required_pkgs:
@@ -1051,7 +1067,7 @@ class BaseImageCreator(object):
                     fpath = os.path.join(root, fname)
                     self._attachment.append(fpath)
 
-    def install(self, repo_urls=None):
+    def install(self, repo_urls=None, updated_pkgs=None):
         """Install packages into the install root.
 
         This function installs the packages listed in the supplied kickstart
@@ -1131,12 +1147,15 @@ class BaseImageCreator(object):
             rpm.addMacro("_install_langs", kickstart.inst_langs(self.ks))
 
         try:
-            self.__preinstall_packages(pkg_manager)
-            self.__select_packages(pkg_manager)
-            self.__select_groups(pkg_manager)
-            self.__deselect_packages(pkg_manager)
-            # self.__localinst_packages(pkg_manager)
-            self.__check_packages(pkg_manager)
+            if self.reuse_environment and updated_pkgs != None:
+                self.__update_packages(pkg_manager, updated_pkgs)
+            else:
+                self.__preinstall_packages(pkg_manager)
+                self.__select_packages(pkg_manager)
+                self.__select_groups(pkg_manager)
+                self.__deselect_packages(pkg_manager)
+                # self.__localinst_packages(pkg_manager)
+                self.__check_packages(pkg_manager)
 
             BOOT_SAFEGUARD = 256 * 1024 * 1024  # 256M
             checksize = self._root_fs_avail
index ee04cd4fd70facde4e049dab74488c42d29dd512..c881c36b2bd580b0d08628c3421a0fd4c693d8ea 100644 (file)
@@ -78,6 +78,7 @@ class Zypp(BackendPlugin):
         self.excpkgs = {}
         self.pre_pkgs = []
         self.check_pkgs = []
+        self.update_pkgs = []
         self.probFilterFlags = [ rpm.RPMPROB_FILTER_OLDPACKAGE,
                                  rpm.RPMPROB_FILTER_REPLACEPKG ]
 
@@ -159,20 +160,14 @@ class Zypp(BackendPlugin):
                 name = ".".join(sp)
         return name, arch
 
-    def selectPackage(self, pkg):
-        """Select a given package or package pattern, can be specified
+    def _findPackage(self, pkg):
+        """find a given package or package pattern, can be specified
         with name.arch or name* or *name
         """
 
         if not self.Z:
             self.__initialize_zypp()
 
-        def markPoolItem(obs, pi):
-            if obs == None:
-                pi.status().setToBeInstalled (zypp.ResStatus.USER)
-            else:
-                obs.status().setToBeInstalled (zypp.ResStatus.USER)
-
         def cmpEVR(p1, p2):
             # compare criterion: arch compatibility first, then repo
             # priority, and version last
@@ -199,6 +194,7 @@ class Zypp(BackendPlugin):
             return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
 
         found = False
+        packages = []
         startx = pkg.startswith("*")
         endx = pkg.endswith("*")
         ispattern = startx or endx
@@ -241,9 +237,12 @@ class Zypp(BackendPlugin):
             obspkg = self.whatObsolete(item)
             if arch:
                 if arch == str(item.arch()):
-                    pitem.status().setToBeInstalled (zypp.ResStatus.USER)
+                    packages.append(pitem)
             else:
-                markPoolItem(obspkg, pitem)
+                if obspkg == None:
+                    packages.append(pitem)
+                else:
+                    packages.append(obspkg)
             if not ispattern:
                 break
 
@@ -267,13 +266,39 @@ class Zypp(BackendPlugin):
 
                 found = True
                 obspkg = self.whatObsolete(item)
-                markPoolItem(obspkg, pitem)
+                if obspkg == None:
+                    packages.append(pitem)
+                else:
+                    packages.append(obspkg)
                 break
 
-        if found:
+        return packages
+
+    def selectPackage(self, pkg):
+        """Select a given package or package pattern, can be specified
+        with name.arch or name* or *name
+        """
+
+        packages = self._findPackage(pkg)
+        if len(packages) > 0:
+            for pkg in packages:
+                pkg.status().setToBeInstalled(zypp.ResStatus.USER)
+            return None
+        else:
+            raise CreatorError("Unable to find package: %s" % (pkg))
+
+    def updatePackage(self, pkg):
+        """Update a given package or package pattern, can be specified
+        with name.arch or name* or *name
+        """
+
+        packages = self._findPackage(pkg)
+        if len(packages) > 0:
+            for pkg in packages:
+                self.update_pkgs.append(pkg)
             return None
         else:
-            raise CreatorError("Unable to find package: %s" % (pkg,))
+            raise CreatorError("Unable to find package: %s" % (pkg))
 
     def inDeselectPackages(self, pitem):
         """check if specified pacakges are in the list of inDeselectPackages
@@ -481,10 +506,28 @@ class Zypp(BackendPlugin):
             elif os.path.splitext(cropts['local_pkgs_path'])[-1] == '.rpm':
                 return [cropts['local_pkgs_path']]
         return []
+
     def __localinst_packages(self):
         for rpm_path in self._get_local_packages():
             self.installLocal(rpm_path)
+
+    def _getPackagesToReinstall(self):
+        to_install_pkgs = []
+        for pkg in self.update_pkgs:
+            to_install_pkgs.append(pkg)
+            isInstalled = pkg.status().isInstalled()
+            msger.info("Update package %s : installed = %s" % (pkg.name(), isInstalled))
+
+            for item in self.Z.pool():
+                if item.name() == pkg.name and item.kind() == pkg.kind():
+                    msger.info("package %s in pool : installed = %s" % (item.name(), item.status().isInstalled()))
+
+        return to_install_pkgs
+
     def runInstall(self, checksize = 0):
+        if not self.Z:
+            self.__initialize_zypp()
+
         os.environ["HOME"] = "/"
         os.environ["LD_PRELOAD"] = ""
         self.buildTransaction()
@@ -494,6 +537,9 @@ class Zypp(BackendPlugin):
         installed_pkgs = todo._toInstall
         dlpkgs = []
 
+        if len(installed_pkgs) == 0:
+            installed_pkgs = self._getPackagesToReinstall()
+
         for pitem in installed_pkgs:
             if not zypp.isKindPattern(pitem) and \
               not self.inDeselectPackages(pitem):
index 57e8ae48042e80f6636cd2a46fc32262e7920d69..0ad7218a6725cbce33895b86e5d948b1b2cdd3ab 100644 (file)
@@ -56,7 +56,12 @@ class LoopPlugin(ImagerPlugin):
             creator.check_depend_tools()
             creator.mount(None, creatoropts["cachedir"])
             if creator.reuse_environment:
-                msger.info("Re-install the packages which are modified")
+                msger.debug("Update the packages which are modified")
+                if args.updated_pkgs:
+                    updated_pkgs = []
+                    for pkg in args.updated_pkgs.split(','):
+                        updated_pkgs.append(pkg)
+                    creator.install(updated_pkgs = updated_pkgs)
             else:
                 creator.install()
                 creator.tpkinstall()
index 96caf89d905172b0f03e1416d5e0214c348218f5..2851397d7f21d8bc1913351fdfbe70e70958f7e6 100755 (executable)
--- a/tools/mic
+++ b/tools/mic
@@ -170,8 +170,8 @@ def create_parser(parser):
     loop_parser.add_argument('--reuse-environment', action='store_true', default=False,
                              help='Reuse the image creator environment of mic')
     group = loop_parser.add_argument_group('only for reuse create environment option')
-    group.add_argument('--reinsrall-pkgs', action='store', dest='reinstall_pkgs', default=[],
-                       help='Reinstall the given packages to re-create image, '
+    group.add_argument('--updated-pkgs', action='store', dest='updated_pkgs', default=None,
+                       help='Update the given packages to re-create image, '
                             'packages should be separated by comma')
                   
     qcow_parser = subparsers.add_parser('qcow', parents=[parent_parser], help='create qcow image')