Support to remove the preload package when removing rpm.
authorwanchao-xu <wanchao.xu@samsung.com>
Fri, 30 Aug 2024 10:01:09 +0000 (18:01 +0800)
committerwanchao-xu <wanchao.xu@samsung.com>
Mon, 2 Sep 2024 01:19:51 +0000 (09:19 +0800)
Change-Id: I8b59a8afa7a43fa09752dbc6ef5558af490a6680
Signed-off-by: wanchao-xu <wanchao.xu@samsung.com>
plugins/backend/zypppkgmgr.py

index 4558673fe2bc389c6e22c8b0534276ba10ee336b..33fb7e81a7ba7ce47634dd3613ea9224be01bf45 100644 (file)
@@ -21,6 +21,7 @@ import urllib.parse
 import rpm
 import glob
 import functools
+import tempfile
 import subprocess
 
 import zypp #pylint: disable=import-error
@@ -1074,13 +1075,68 @@ class Zypp(BackendPlugin):
 
         # chroot into install root and remove packages with rpm cmd
         # note: the rpm package should has been installed in install root
-        retcode = 0
+        # some rpm packages only include tpk package, them should be uninstalled
+        script = """#!/bin/bash
+pkgs=$1
+if [ -n "$pkgs" ]; then
+  if [ -f /usr/bin/rpm ]; then
+    rpm -e --allmatches $pkgs
+    if [ -f /usr/bin/pkgcmd ]; then
+      for pkg in $pkgs; do
+        info=$(pkgcmd -l --global | grep $pkg)
+        pkgid=$(echo ${info#*pkgid} | awk -F ' ' '{print $1}' | sed 's/.*\\[\\(.*\\)\\].*/\\1/')
+        if [ -n "$pkgid" ]; then
+          pkgtype=$(echo ${info#*pkg_type} | awk -F ' ' '{print $1}' | sed 's/.*\\[\\(.*\\)\\].*/\\1/')
+          echo "Uninstalling preload $pkgtype package $pkgid ..."
+          if [[ $pkgtype == 'tpk' ]]; then
+            cmd='/usr/bin/tpk-backend'
+          elif [[ $pkgtype == 'wgt' ]]; then
+            cmd='/usr/bin/wgt-backend'
+          else
+            cmd='/usr/bin/unified-backend'
+          fi
+          if [ -f $cmd ]; then
+            $cmd -d $pkg --preload --force-remove
+          else
+            echo "$cmd is not installed"
+            exit 1
+          fi
+        fi
+      done
+    else
+      echo 'pkgmgr package is not installed in image, no preload packages'
+    fi
+  else
+    echo 'rpm package is not installed in image'
+    exit 1
+  fi
+fi
+exit 0
+"""
+        if os.path.exists(self.instroot + "/tmp"):
+            shutil.rmtree(self.instroot + "/tmp")
+        os.mkdir(self.instroot + "/tmp", 0o755)
+        (fd, path) = tempfile.mkstemp(prefix="uninstall_preload_pkg-",
+                                      dir=self.instroot + "/tmp")
+        os.write(fd, script.encode())
+        os.close(fd)
+        os.chmod(path, 0o700)
+
         try:
-            cmd = 'rpm -e --allmatches %s' % ' '.join(to_delete)
-            msger.debug("do chroot and run command [%s] to erase packages" % cmd)
-            retcode = subprocess.call(cmd, preexec_fn=mychroot, shell=True)
-        except (IOError, OSError) as err:
-            raise CreatorError("chroot err: %s" % str(err))
+            script_path = "/tmp/" + os.path.basename(path)
+            pkgs = ' '.join(to_delete)
+            p = subprocess.Popen(['/bin/bash', script_path, pkgs],
+                                 preexec_fn=mychroot,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.STDOUT)
+            while p.poll() == None:
+                msger.info(p.stdout.readline().strip().decode())
+            if p.returncode != 0:
+                raise CreatorError("Failed to uninstall preload packages")
+        except OSError as msg:
+            raise CreatorError("Failed to uninstall preload packages : %s" % msg)
+        finally:
+            os.unlink(path)
 
         return to_delete