[Yum-devel] [PATCH] Move protect-packages plugin into core, and fix some bugs in it

James Antill james at and.org
Sun Apr 25 05:08:23 UTC 2010


---
 cli.py          |    1 +
 yum/__init__.py |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 yum/history.py  |    1 +
 3 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/cli.py b/cli.py
index 4d5b538..f89c333 100644
--- a/cli.py
+++ b/cli.py
@@ -69,6 +69,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
         signal.signal(signal.SIGQUIT, sigquit)
         yum.YumBase.__init__(self)
         output.YumOutput.__init__(self)
+        self.protect_packages = True
         logging.basicConfig()
         self.logger = logging.getLogger("yum.cli")
         self.verbose_logger = logging.getLogger("yum.verbose.cli")
diff --git a/yum/__init__.py b/yum/__init__.py
index 87644a1..8acc92a 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -165,6 +165,8 @@ class YumBase(depsolve.Depsolve):
 
         self.run_with_package_names = set()
 
+        self.protect_packages = False # Old default, needed for mock etc.
+
     def __del__(self):
         self.close()
         self.closeRpmDB()
@@ -855,6 +857,21 @@ class YumBase(depsolve.Depsolve):
         func(_("The program %s%s%s is found in the yum-utils package.") %
              (hibeg, prog, hiend))
 
+    def _parse_protected_packages(self):
+        """ Find the protected packages by parsing the files in
+            /etc/yum/protected.d. yum is always protected. """
+        protected = set(['yum'])
+        for fname in glob.glob("/etc/yum/protected.d/*.conf"):
+            for line in open(fname):
+                if re.match('\s*(#|$)', line):
+                    continue
+                line = line.rstrip() # no more trailing \n's
+                line = line.lstrip() # be nice
+                if not line:
+                    continue
+                protected.add(line)
+        return protected
+
     def buildTransaction(self, unfinished_transactions_check=True):
         """go through the packages in the transaction set, find them in the
            packageSack or rpmdb, and pack up the ts accordingly"""
@@ -888,6 +905,45 @@ class YumBase(depsolve.Depsolve):
 
         if self.tsInfo.pkgSack is not None: # rm Transactions don't have pkgSack
             self.tsInfo.pkgSack.dropCachedData()
+
+        #  This is a version of the old "protect-packages" plugin, it allows
+        # you to erase duplicates and do remove+install.
+        #  But we don't allow you to turn it off!:)
+        protect_states = [TS_OBSOLETED, TS_ERASE]
+        txmbrs = []
+        if rescode == 2 and self.protect_packages:
+            protected = self._parse_protected_packages()
+            txmbrs = self.tsInfo.getMembersWithState(None, protect_states)
+        bad_togo = {}
+        for txmbr in txmbrs:
+            if txmbr.name not in protected:
+                continue
+            if txmbr.name not in bad_togo:
+                bad_togo[txmbr.name] = []
+            bad_togo[txmbr.name].append(txmbr.pkgtup)
+        for ipkg in self.rpmdb.searchNames(bad_togo.keys()):
+            if ipkg.name not in bad_togo:
+                continue
+            # If there is at least one version not being removed, allow it
+            if ipkg.pkgtup not in bad_togo[ipkg.name]:
+                del bad_togo[ipkg.name]
+        for pkgname in bad_togo.keys():
+            for txmbr in self.tsInfo.matchNaevr(name=pkgname):
+                if txmbr.name not in bad_togo:
+                    continue
+                if txmbr.pkgtup in bad_togo[ipkg.name]:
+                    continue
+                # If we are installing one version we aren't removing, allow it
+                if txmbr.output_state in TS_INSTALL_STATES:
+                    del bad_togo[ipkg.name]
+
+        if bad_togo:
+            rescode = 1
+            restring = []
+            for pkgname in sorted(bad_togo):
+                restring.append(_('Trying to remove "%s", which is protected') %
+                                pkgname)
+
         self.rpmdb.dropCachedData()
 
         self.verbose_logger.debug('Depsolve time: %0.3f' % (time.time() - ds_st))
diff --git a/yum/history.py b/yum/history.py
index 76a3bb7..9d87f87 100644
--- a/yum/history.py
+++ b/yum/history.py
@@ -649,6 +649,7 @@ class YumHistory:
      pkgtupid INTEGER NOT NULL REFERENCES pkgtups);
 ''']
 
+    # VIEWS!
     def _update_db_file_2(self):
         """ Update to version 2 of history, includes trans_skip_pkgs. """
         if not self.conf.writable:
-- 
1.7.0.1



More information about the Yum-devel mailing list