|
|
5b4f08 |
commit f84a2dbcc28312105246fac51771481640759da5
|
|
|
5b4f08 |
Author: Phil Dibowitz <phil@ipom.com>
|
|
|
5b4f08 |
Date: Thu Jul 2 11:40:55 2015 -0700
|
|
|
5b4f08 |
|
|
|
5b4f08 |
Add option to remove newest dupes instead of oldest dupes
|
|
|
5b4f08 |
|
|
|
5b4f08 |
Sometimes in a failed transaction you need to remove the newest of the dupes and
|
|
|
5b4f08 |
not the oldest. This provides that option.
|
|
|
5b4f08 |
|
|
|
5b4f08 |
diff --git a/package-cleanup.py b/package-cleanup.py
|
|
|
5b4f08 |
index acad9f2..13cfb89 100755
|
|
|
5b4f08 |
--- a/package-cleanup.py
|
|
|
5b4f08 |
+++ b/package-cleanup.py
|
|
|
5b4f08 |
@@ -79,6 +79,9 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
dupegrp.add_option("--cleandupes", default=False,
|
|
|
5b4f08 |
dest="cleandupes", action="store_true",
|
|
|
5b4f08 |
help='Scan for duplicates in your rpmdb and remove older ')
|
|
|
5b4f08 |
+ dupegrp.add_option("--removenewestdupes", default=False,
|
|
|
5b4f08 |
+ dest="removenewestdupes", action="store_true",
|
|
|
5b4f08 |
+ help='Remove the newest dupes instead of the oldest dupes.')
|
|
|
5b4f08 |
dupegrp.add_option("--noscripts", default=False,
|
|
|
5b4f08 |
dest="noscripts", action="store_true",
|
|
|
5b4f08 |
help="disable rpm scriptlets from running when cleaning duplicates")
|
|
|
5b4f08 |
@@ -172,7 +175,7 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
|
|
|
5b4f08 |
return results
|
|
|
5b4f08 |
|
|
|
5b4f08 |
- def _remove_old_dupes(self):
|
|
|
5b4f08 |
+ def _remove_dupes(self, newest=False):
|
|
|
5b4f08 |
"""add older duplicate pkgs to be removed in the transaction"""
|
|
|
5b4f08 |
dupedict = self._find_installed_duplicates()
|
|
|
5b4f08 |
|
|
|
5b4f08 |
@@ -180,7 +183,11 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
for (name,dupelists) in dupedict.items():
|
|
|
5b4f08 |
for dupelist in dupelists:
|
|
|
5b4f08 |
dupelist.sort()
|
|
|
5b4f08 |
- for lowpo in dupelist[0:-1]:
|
|
|
5b4f08 |
+ if newest:
|
|
|
5b4f08 |
+ plist = dupelist[1:]
|
|
|
5b4f08 |
+ else:
|
|
|
5b4f08 |
+ plist = dupelist[0:-1]
|
|
|
5b4f08 |
+ for lowpo in plist:
|
|
|
5b4f08 |
removedupes.append(lowpo)
|
|
|
5b4f08 |
|
|
|
5b4f08 |
for po in removedupes:
|
|
|
5b4f08 |
@@ -373,7 +380,7 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
sys.exit(1)
|
|
|
5b4f08 |
if opts.noscripts:
|
|
|
5b4f08 |
self.conf.tsflags.append('noscripts')
|
|
|
5b4f08 |
- self._remove_old_dupes()
|
|
|
5b4f08 |
+ self._remove_dupes(opts.removenewestdupes)
|
|
|
5b4f08 |
self.run_with_package_names.add('yum-utils')
|
|
|
5b4f08 |
|
|
|
5b4f08 |
if hasattr(self, 'doUtilBuildTransaction'):
|
|
|
5b4f08 |
commit 27784822a342debd3ecfa04686a35f2e7e576023
|
|
|
5b4f08 |
Author: Michal Domonkos <mdomonko@redhat.com>
|
|
|
5b4f08 |
Date: Wed Oct 11 19:26:38 2017 +0200
|
|
|
5b4f08 |
|
|
|
5b4f08 |
package-cleanup: don't remove required dupes. BZ 1455318
|
|
|
5b4f08 |
|
|
|
5b4f08 |
Note: Turning removedupes into a set for O(1) complexity on
|
|
|
5b4f08 |
removedupes.remove().
|
|
|
5b4f08 |
|
|
|
5b4f08 |
diff --git a/package-cleanup.py b/package-cleanup.py
|
|
|
5b4f08 |
index 13cfb89..9f74609 100755
|
|
|
5b4f08 |
--- a/package-cleanup.py
|
|
|
5b4f08 |
+++ b/package-cleanup.py
|
|
|
5b4f08 |
@@ -176,10 +176,12 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
return results
|
|
|
5b4f08 |
|
|
|
5b4f08 |
def _remove_dupes(self, newest=False):
|
|
|
5b4f08 |
- """add older duplicate pkgs to be removed in the transaction"""
|
|
|
5b4f08 |
- dupedict = self._find_installed_duplicates()
|
|
|
5b4f08 |
+ """add duplicate pkgs to be removed in the transaction,
|
|
|
5b4f08 |
+ return a dict of excluded dupes and their requiring packages"""
|
|
|
5b4f08 |
|
|
|
5b4f08 |
- removedupes = []
|
|
|
5b4f08 |
+ # Find dupes
|
|
|
5b4f08 |
+ dupedict = self._find_installed_duplicates()
|
|
|
5b4f08 |
+ removedupes = set()
|
|
|
5b4f08 |
for (name,dupelists) in dupedict.items():
|
|
|
5b4f08 |
for dupelist in dupelists:
|
|
|
5b4f08 |
dupelist.sort()
|
|
|
5b4f08 |
@@ -188,11 +190,37 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
else:
|
|
|
5b4f08 |
plist = dupelist[0:-1]
|
|
|
5b4f08 |
for lowpo in plist:
|
|
|
5b4f08 |
- removedupes.append(lowpo)
|
|
|
5b4f08 |
-
|
|
|
5b4f08 |
+ removedupes.add(lowpo)
|
|
|
5b4f08 |
+
|
|
|
5b4f08 |
+ # Exclude any such dupes that would pull other installed packages into
|
|
|
5b4f08 |
+ # the removal transaction (to prevent us from accidentally removing a
|
|
|
5b4f08 |
+ # huge part of a working system) by performing a dry transaction(s)
|
|
|
5b4f08 |
+ # first.
|
|
|
5b4f08 |
+ excluded = {}
|
|
|
5b4f08 |
+ while True:
|
|
|
5b4f08 |
+ for po in removedupes:
|
|
|
5b4f08 |
+ self.remove(po)
|
|
|
5b4f08 |
+ changed = False
|
|
|
5b4f08 |
+ for txmbr in self.tsInfo.getMembers():
|
|
|
5b4f08 |
+ requiredby = self._checkRemove(txmbr)
|
|
|
5b4f08 |
+ if requiredby:
|
|
|
5b4f08 |
+ removedupes.remove(txmbr.po)
|
|
|
5b4f08 |
+ excluded[txmbr.po] = requiredby
|
|
|
5b4f08 |
+ # Do another round, to cover any transitive deps within
|
|
|
5b4f08 |
+ # removedupes, for example: if foo requires bar requires
|
|
|
5b4f08 |
+ # baz and removedupes contains bar and baz, then
|
|
|
5b4f08 |
+ # _checkRemove(baz) won't return bar.
|
|
|
5b4f08 |
+ changed = True
|
|
|
5b4f08 |
+ del self.tsInfo
|
|
|
5b4f08 |
+ if not changed:
|
|
|
5b4f08 |
+ break
|
|
|
5b4f08 |
+
|
|
|
5b4f08 |
+ # Mark the dupes for removal
|
|
|
5b4f08 |
for po in removedupes:
|
|
|
5b4f08 |
self.remove(po)
|
|
|
5b4f08 |
|
|
|
5b4f08 |
+ return excluded
|
|
|
5b4f08 |
+
|
|
|
5b4f08 |
|
|
|
5b4f08 |
def _should_show_leaf(self, po, leaf_regex, exclude_devel, exclude_bin):
|
|
|
5b4f08 |
"""
|
|
|
5b4f08 |
@@ -380,7 +408,13 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
sys.exit(1)
|
|
|
5b4f08 |
if opts.noscripts:
|
|
|
5b4f08 |
self.conf.tsflags.append('noscripts')
|
|
|
5b4f08 |
- self._remove_dupes(opts.removenewestdupes)
|
|
|
5b4f08 |
+ excluded = self._remove_dupes(opts.removenewestdupes)
|
|
|
5b4f08 |
+ for po, requiredby in excluded.iteritems():
|
|
|
5b4f08 |
+ count = len(requiredby)
|
|
|
5b4f08 |
+ print ('Not removing %s because it is required by %s '
|
|
|
5b4f08 |
+ 'installed package%s' %
|
|
|
5b4f08 |
+ (po.hdr.sprintf(opts.qf), count,
|
|
|
5b4f08 |
+ 's' if count > 1 else ''))
|
|
|
5b4f08 |
self.run_with_package_names.add('yum-utils')
|
|
|
5b4f08 |
|
|
|
5b4f08 |
if hasattr(self, 'doUtilBuildTransaction'):
|
|
|
5b4f08 |
@@ -397,9 +431,20 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
|
|
|
5b4f08 |
if len(self.tsInfo) < 1:
|
|
|
5b4f08 |
print 'No duplicates to remove'
|
|
|
5b4f08 |
- sys.exit(0)
|
|
|
5b4f08 |
-
|
|
|
5b4f08 |
- sys.exit(self.doUtilTransaction())
|
|
|
5b4f08 |
+ errc = 0
|
|
|
5b4f08 |
+ else:
|
|
|
5b4f08 |
+ errc = self.doUtilTransaction()
|
|
|
5b4f08 |
+
|
|
|
5b4f08 |
+ if excluded:
|
|
|
5b4f08 |
+ self.logger.warn(
|
|
|
5b4f08 |
+ 'Warning: Some duplicates were not removed because they '
|
|
|
5b4f08 |
+ 'are required by installed packages.\n'
|
|
|
5b4f08 |
+ 'You can try --cleandupes with%s --removenewestdupes, '
|
|
|
5b4f08 |
+ 'or review them with --dupes and remove manually.' %
|
|
|
5b4f08 |
+ ('out' if opts.removenewestdupes else '')
|
|
|
5b4f08 |
+ )
|
|
|
5b4f08 |
+
|
|
|
5b4f08 |
+ sys.exit(errc)
|
|
|
5b4f08 |
|
|
|
5b4f08 |
|
|
|
5b4f08 |
if __name__ == '__main__':
|
|
|
5b4f08 |
commit 4594bbc623b68bea6522047fb6267069c8ad94c8
|
|
|
5b4f08 |
Author: Michal Domonkos <mdomonko@redhat.com>
|
|
|
5b4f08 |
Date: Wed Oct 11 20:23:06 2017 +0200
|
|
|
5b4f08 |
|
|
|
5b4f08 |
package-cleanup: update man page
|
|
|
5b4f08 |
|
|
|
5b4f08 |
Add missing options from --help and also clear up the wording of
|
|
|
5b4f08 |
--removenewestdupes.
|
|
|
5b4f08 |
|
|
|
5b4f08 |
diff --git a/docs/package-cleanup.1 b/docs/package-cleanup.1
|
|
|
5b4f08 |
index 61959ac..5b7e1c0 100644
|
|
|
5b4f08 |
--- a/docs/package-cleanup.1
|
|
|
5b4f08 |
+++ b/docs/package-cleanup.1
|
|
|
5b4f08 |
@@ -36,6 +36,10 @@ Scan for duplicates in the local RPM database.
|
|
|
5b4f08 |
.IP "\fB\-\-cleandupes\fP"
|
|
|
5b4f08 |
Scan for duplicates in the local RPM database and clean out the
|
|
|
5b4f08 |
older versions.
|
|
|
5b4f08 |
+.IP "\fB\-\-removenewestdupes\fP"
|
|
|
5b4f08 |
+Remove the newest dupes instead of the oldest dupes when cleaning duplicates.
|
|
|
5b4f08 |
+.IP "\fB\-\-noscripts\fP"
|
|
|
5b4f08 |
+Disable rpm scriptlets from running when cleaning duplicates.
|
|
|
5b4f08 |
.IP "\fB\-\-count <COUNT>\fP"
|
|
|
5b4f08 |
Number of duplicate/kernel packages to keep on the system (default 2)
|
|
|
5b4f08 |
.PP
|
|
|
5b4f08 |
diff --git a/package-cleanup.py b/package-cleanup.py
|
|
|
5b4f08 |
index 9f74609..4a44326 100755
|
|
|
5b4f08 |
--- a/package-cleanup.py
|
|
|
5b4f08 |
+++ b/package-cleanup.py
|
|
|
5b4f08 |
@@ -81,7 +81,7 @@ class PackageCleanup(YumUtilBase):
|
|
|
5b4f08 |
help='Scan for duplicates in your rpmdb and remove older ')
|
|
|
5b4f08 |
dupegrp.add_option("--removenewestdupes", default=False,
|
|
|
5b4f08 |
dest="removenewestdupes", action="store_true",
|
|
|
5b4f08 |
- help='Remove the newest dupes instead of the oldest dupes.')
|
|
|
5b4f08 |
+ help='Remove the newest dupes instead of the oldest dupes when cleaning duplicates.')
|
|
|
5b4f08 |
dupegrp.add_option("--noscripts", default=False,
|
|
|
5b4f08 |
dest="noscripts", action="store_true",
|
|
|
5b4f08 |
help="disable rpm scriptlets from running when cleaning duplicates")
|