Merge ~juliank/ubuntu-release-upgrader:improve-obsoletes into ubuntu-release-upgrader:ubuntu/main

Proposed by Julian Andres Klode
Status: Merged
Merge reported by: Nick Rosbrook
Merged at revision: ae0c35fc3df04c5abcf4db6ceb1e64edd66bfe84
Proposed branch: ~juliank/ubuntu-release-upgrader:improve-obsoletes
Merge into: ubuntu-release-upgrader:ubuntu/main
Diff against target: 110 lines (+53/-25)
2 files modified
DistUpgrade/DistUpgradeCache.py (+18/-19)
DistUpgrade/DistUpgradeController.py (+35/-6)
Reviewer Review Type Date Requested Status
Nick Rosbrook Approve
Review via email: mp+465148@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Julian Andres Klode (juliank) wrote :

I think we likely want to ship this _after_ the current fixes in ubuntu/main have landed in -updates, as this is a bigger change for performance, but ymmv.

Revision history for this message
Nick Rosbrook (enr0n) wrote :

This looks good to me. Thanks for the detailed commit message.

review: Approve
Revision history for this message
Nick Rosbrook (enr0n) wrote :

I rebased your commits and pushed to ubuntu/main.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/DistUpgrade/DistUpgradeCache.py b/DistUpgrade/DistUpgradeCache.py
index 0692ef9..77ffb64 100644
--- a/DistUpgrade/DistUpgradeCache.py
+++ b/DistUpgrade/DistUpgradeCache.py
@@ -940,7 +940,7 @@ class MyCache(apt.Cache):
940 return False940 return False
941941
942 @withResolverLog942 @withResolverLog
943 def tryMarkObsoleteForRemoval(self, pkgname, remove_candidates, forced_obsoletes, foreign_pkgs):943 def tryMarkObsoleteForRemoval(self, pkgname, remove_candidates, forced_obsoletes, foreign_pkgs, auto_fix):
944 #logging.debug("tryMarkObsoleteForRemoval(): %s" % pkgname)944 #logging.debug("tryMarkObsoleteForRemoval(): %s" % pkgname)
945 # coherence check, first see if it looks like a running kernel pkg945 # coherence check, first see if it looks like a running kernel pkg
946 if pkgname.endswith(self.uname):946 if pkgname.endswith(self.uname):
@@ -972,28 +972,27 @@ class MyCache(apt.Cache):
972 # if this package has not been forced obsolete, only972 # if this package has not been forced obsolete, only
973 # delete it if it doesn't remove other dependents973 # delete it if it doesn't remove other dependents
974 # that are not obsolete as well974 # that are not obsolete as well
975 actiongroup = apt_pkg.ActionGroup(self._depcache)975 if auto_fix:
976 # just make pyflakes shut up, later we should use976 self.create_snapshot()
977 # with self.actiongroup():
978 actiongroup
979 self.create_snapshot()
980 try:977 try:
981 self[pkgname].mark_delete(purge=purge)978 self[pkgname].mark_delete(purge=purge, auto_fix=auto_fix)
982 self.view.processEvents()979 self.view.processEvents()
983 if pkgname in forced_obsoletes:980 if auto_fix:
984 return True981 if pkgname in forced_obsoletes:
985 #logging.debug("marking '%s' for removal" % pkgname)982 return True
986 for pkg in self.get_changes():983 #logging.debug("marking '%s' for removal" % pkgname)
987 if (pkg.name not in remove_candidates or984 for pkg in self.get_changes():
988 pkg.name in foreign_pkgs or985 if (pkg.name not in remove_candidates or
989 self._inRemovalDenylist(pkg.name) or986 pkg.name in foreign_pkgs or
990 pkg.name == self.linux_metapackage):987 self._inRemovalDenylist(pkg.name) or
991 logging.debug("package '%s' produces an unwanted removal '%s', skipping" % (pkgname, pkg.name))988 pkg.name == self.linux_metapackage):
992 self.restore_snapshot()989 logging.debug("package '%s' produces an unwanted removal '%s', skipping" % (pkgname, pkg.name))
993 return False990 self.restore_snapshot()
991 return False
994 except (SystemError, KeyError) as e:992 except (SystemError, KeyError) as e:
995 logging.warning("_tryMarkObsoleteForRemoval failed for '%s' (%s: %s)" % (pkgname, repr(e), e))993 logging.warning("_tryMarkObsoleteForRemoval failed for '%s' (%s: %s)" % (pkgname, repr(e), e))
996 self.restore_snapshot()994 if auto_fix:
995 self.restore_snapshot()
997 return False996 return False
998 return True997 return True
999998
diff --git a/DistUpgrade/DistUpgradeController.py b/DistUpgrade/DistUpgradeController.py
index eebe281..f7853ae 100644
--- a/DistUpgrade/DistUpgradeController.py
+++ b/DistUpgrade/DistUpgradeController.py
@@ -1995,12 +1995,41 @@ class DistUpgradeController(object):
1995 logging.debug("remove_candidates: '%s'" % remove_candidates)1995 logging.debug("remove_candidates: '%s'" % remove_candidates)
1996 logging.debug("Start checking for obsolete pkgs")1996 logging.debug("Start checking for obsolete pkgs")
1997 progress = self._view.getOpCacheProgress()1997 progress = self._view.getOpCacheProgress()
1998 for (i, pkgname) in enumerate(remove_candidates):1998 scheduled_remove = set()
1999 progress.update((i/float(len(remove_candidates)))*100.0)1999
2000 if pkgname not in self.foreign_pkgs:2000 with self.cache.actiongroup():
2001 self._view.processEvents()2001 # Forced obsoletes we remove, removing any of their dependencies, hence do a first loop with auto_fix=True
2002 if not self.cache.tryMarkObsoleteForRemoval(pkgname, remove_candidates, self.forced_obsoletes, self.foreign_pkgs):2002 for (i, pkgname) in enumerate(remove_candidates):
2003 logging.debug("'%s' scheduled for remove but not safe to remove, skipping", pkgname)2003 progress.update((i/float(len(remove_candidates)))*100.0 / 2)
2004 if pkgname in self.foreign_pkgs and pkgname in self.force_obsoletes:
2005 self._view.processEvents()
2006 if not self.cache.tryMarkObsoleteForRemoval(pkgname, remove_candidates, self.forced_obsoletes, self.foreign_pkgs, auto_fix=True):
2007 logging.debug("'%s' scheduled for remove but not safe to remove, skipping", pkgname)
2008 else:
2009 scheduled_remove.add(pkgname)
2010
2011 # Now let's try to remove other packages
2012 for (i, pkgname) in enumerate(remove_candidates):
2013 progress.update((i/float(len(remove_candidates)))*100.0 / 2 + 50)
2014 if pkgname not in self.foreign_pkgs:
2015 self._view.processEvents()
2016 if not self.cache.tryMarkObsoleteForRemoval(pkgname, remove_candidates, self.forced_obsoletes, self.foreign_pkgs, auto_fix=False):
2017 logging.debug("'%s' scheduled for remove but not safe to remove, skipping", pkgname)
2018 else:
2019 scheduled_remove.add(pkgname)
2020
2021 # We have scheduled their removals, but not any reverse-dependencies. If anything is broken now,
2022 # resolve them by keeping back the obsolete packages.
2023 self.cache._startAptResolverLog()
2024 pr = apt.ProblemResolver(self.cache)
2025 pr.resolve_by_keep()
2026 self.cache._stopAptResolverLog()
2027
2028 # resolve_by_keep() will revert any unsafe removals, so we need to list them here again.
2029 for pkgname in scheduled_remove:
2030 if not self.cache[pkgname].marked_delete:
2031 logging.debug("obsolete package '%s' could not be removed", pkgname)
2032
2004 logging.debug("Finish checking for obsolete pkgs")2033 logging.debug("Finish checking for obsolete pkgs")
2005 progress.done()2034 progress.done()
20062035

Subscribers

People subscribed via source and target branches