summaryrefslogtreecommitdiff
path: root/DistUpgrade/DistUpgradeCache.py
diff options
context:
space:
mode:
Diffstat (limited to 'DistUpgrade/DistUpgradeCache.py')
-rw-r--r--DistUpgrade/DistUpgradeCache.py150
1 files changed, 134 insertions, 16 deletions
diff --git a/DistUpgrade/DistUpgradeCache.py b/DistUpgrade/DistUpgradeCache.py
index 680e7d9e..d9dc9959 100644
--- a/DistUpgrade/DistUpgradeCache.py
+++ b/DistUpgrade/DistUpgradeCache.py
@@ -66,10 +66,12 @@ class MyCache(apt.Cache):
if pkg.markedDelete:
self.to_remove.append(pkg.name)
+ def clear(self):
+ self._depcache.Init()
+
def restore_snapshot(self):
""" restore a snapshot """
- for pkg in self:
- pkg.markKeep()
+ self.clear()
for name in self.to_remove:
pkg = self[name]
pkg.markDelete()
@@ -108,6 +110,39 @@ class MyCache(apt.Cache):
if self.has_key(pkg):
self._depcache.MarkDelete(self[pkg]._pkg,True)
+ def keepInstalledRule(self):
+ """ run after the dist-upgrade to ensure that certain
+ packages are kept installed """
+ def keepInstalled(self, pkgname, reason):
+ if (self.has_key(pkgname)
+ and self[pkgname].isInstalled
+ and self[pkgname].markedDelete):
+ self.markInstall(pkgname, reason)
+
+ # first the global list
+ for pkgname in self.config.getlist("Distro","KeepInstalledPkgs"):
+ keepInstalled(self, pkgname, "Distro KeepInstalledPkgs rule")
+ # the the per-metapkg rules
+ for key in self.metapkgs:
+ if self.has_key(key) and (self[key].isInstalled or
+ self[key].markedInstall):
+ for pkgname in self.config.getlist(key,"KeepInstalledPkgs"):
+ keepInstalled(self, pkgname, "%s KeepInstalledPkgs rule" % key)
+ # now the keepInstalledSection code
+ for section in self.config.getlist("Distro","KeepInstalledSection"):
+ for pkg in self:
+ if pkg.markedDelete and pkg.section == section:
+ keepInstalled(self, pkg.name, "Distro KeepInstalledSection rule: %s" % section)
+ # the the per-metapkg rules
+ for key in self.metapkgs:
+ if self.has_key(key) and (self[key].isInstalled or
+ self[key].markedInstall):
+ for section in self.config.getlist(key,"KeepInstalledSection"):
+ for pkg in self:
+ if pkg.markedDelete and pkg.section == section:
+ keepInstalled(self, pkg.name, "%s KeepInstalledSection rule: %s" % (key, section))
+
+
def postUpgradeRule(self):
" run after the upgrade was done in the cache "
for (rule, action) in [("Install", self.markInstall),
@@ -128,6 +163,67 @@ class MyCache(apt.Cache):
if func is not None:
func()
+ def edgyQuirks(self):
+ """ this function works around quirks in the dapper->edgy upgrade """
+ logging.debug("running edgyQuirks handler")
+ for pkg in self:
+ # deal with the python2.4-$foo -> python-$foo transition
+ if (pkg.name.startswith("python2.4-") and
+ pkg.isInstalled and
+ not pkg.markedUpgrade):
+ basepkg = "python-"+pkg.name[len("python2.4-"):]
+ if (self.has_key(basepkg) and not self[basepkg].markedInstall):
+ try:
+ self.markInstall(basepkg,
+ "python2.4->python upgrade rule")
+ except SystemError, e:
+ logging.debug("Failed to apply python2.4->python install: %s (%s)" % (basepkg, e))
+ # xserver-xorg-input-$foo gives us trouble during the upgrade too
+ if (pkg.name.startswith("xserver-xorg-input-") and
+ pkg.isInstalled and
+ not pkg.markedUpgrade):
+ try:
+ self.markInstall(pkg.name, "xserver-xorg-input fixup rule")
+ except SystemError, e:
+ logging.debug("Failed to apply fixup: %s (%s)" % (pkg.name, e))
+
+ # deal with held-backs that are unneeded
+ for pkgname in ["hpijs", "bzr", "tomboy"]:
+ if (self.has_key(pkgname) and self[pkgname].isInstalled and
+ not self[pkgname].markedUpgrade):
+ try:
+ self.markInstall(pkgname,"%s quirk upgrade rule" % pkgname)
+ except SystemError, e:
+ logging.debug("Failed to apply %s install (%s)" % (pkgname,e))
+ # libgl1-mesa-dri from xgl.compiz.info (and friends) breaks the
+ # upgrade, work around this here by downgrading the package
+ if self.has_key("libgl1-mesa-dri"):
+ pkg = self["libgl1-mesa-dri"]
+ # the version from the compiz repo has a "6.5.1+cvs20060824" ver
+ if (pkg.candidateVersion == pkg.installedVersion and
+ "+cvs2006" in pkg.candidateVersion):
+ for ver in pkg._pkg.VersionList:
+ # the "officual" edgy version has "6.5.1~20060817-0ubuntu3"
+ if "~2006" in ver.VerStr:
+ # ensure that it is from a trusted repo
+ for (VerFileIter, index) in ver.FileList:
+ indexfile = self._list.FindIndex(VerFileIter)
+ if indexfile and indexfile.IsTrusted:
+ logging.info("Forcing downgrade of libgl1-mesa-dri for xgl.compz.info installs")
+ self._depcache.SetCandidateVer(pkg._pkg, ver)
+ break
+
+ # deal with general if $foo is installed, install $bar
+ for (fr, to) in [("xserver-xorg-driver-all","xserver-xorg-video-all")]:
+ if self.has_key(fr) and self.has_key(to):
+ if self[fr].isInstalled and not self[to].markedInstall:
+ try:
+ self.markInstall(to,"%s->%s quirk upgrade rule" % (fr, to))
+ except SystemError, e:
+ logging.debug("Failed to apply %s->%s install (%s)" % (fr, to, e))
+
+
+
def dapperQuirks(self):
""" this function works around quirks in the breezy->dapper upgrade """
logging.debug("running dapperQuirks handler")
@@ -142,20 +238,23 @@ class MyCache(apt.Cache):
# upgrade (and make sure this way that the cache is ok)
self.upgrade(True)
- # then see if meta-pkgs are missing
- if not self._installMetaPkgs(view):
- raise SystemError, _("Can't upgrade required meta-packages")
+ # see if our KeepInstalled rules are honored
+ self.keepInstalledRule()
# and if we have some special rules
self.postUpgradeRule()
+ # then see if meta-pkgs are missing
+ if not self._installMetaPkgs(view):
+ raise SystemError, _("Can't upgrade required meta-packages")
+
# see if it all makes sense
if not self._verifyChanges():
raise SystemError, _("A essential package would have to be removed")
except SystemError, e:
# FIXME: change the text to something more useful
view.error(_("Could not calculate the upgrade"),
- _("A unresolvable problem occured while "
+ _("A unresolvable problem occurred while "
"calculating the upgrade.\n\n"
"Please report this bug against the 'update-manager' "
"package and include the files in /var/log/dist-upgrade/ "
@@ -168,6 +267,15 @@ class MyCache(apt.Cache):
for pkg in self.getChanges():
if pkg.markedDelete:
continue
+ # special case because of a bug in pkg.candidateOrigin
+ if pkg.markedDowngrade:
+ for ver in pkg._pkg.VersionList:
+ # version is lower than installed one
+ if apt_pkg.VersionCompare(ver.VerStr, pkg.installedVersion) < 0:
+ for (verFileIter,index) in ver.FileList:
+ if not origin.trusted:
+ untrusted.append(pkg.name)
+ continue
origins = pkg.candidateOrigin
trusted = False
for origin in origins:
@@ -244,8 +352,8 @@ class MyCache(apt.Cache):
logging.debug("guessing '%s' as missing meta-pkg" % key)
try:
self[key].markInstall()
- except SystemError:
- logging.error("failed to mark '%s' for install" % key)
+ except SystemError, e:
+ logging.error("failed to mark '%s' for install (%s)" % (key,e))
view.error(_("Can't install '%s'" % key),
_("It was impossible to install a "
"required package. Please report "
@@ -259,7 +367,7 @@ class MyCache(apt.Cache):
"ubuntu-desktop, kubuntu-desktop or "
"edubuntu-desktop package and it was not "
"possible to detect which version of "
- "ubuntu you are runing.\n "
+ "ubuntu you are running.\n "
"Please install one of the packages "
"above first using synaptic or "
"apt-get before proceeding."))
@@ -277,13 +385,18 @@ class MyCache(apt.Cache):
# if it dosn't remove other packages depending on it
# that are not obsolete as well
self.create_snapshot()
- self[pkgname].markDelete()
- for pkg in self.getChanges():
- if pkg.name not in remove_candidates or \
- pkg.name in foreign_pkgs or \
- self._inRemovalBlacklist(pkg.name):
- self.restore_snapshot()
- return False
+ try:
+ self[pkgname].markDelete()
+ for pkg in self.getChanges():
+ if pkg.name not in remove_candidates or \
+ pkg.name in foreign_pkgs or \
+ self._inRemovalBlacklist(pkg.name):
+ self.restore_snapshot()
+ return False
+ except (SystemError,KeyError),e:
+ logging.warning("_tryMarkObsoleteForRemoval failed for '%s' (%s)" % (pkgname,e))
+ self.restore_snapshot()
+ return False
return True
def _getObsoletesPkgs(self):
@@ -315,3 +428,8 @@ class MyCache(apt.Cache):
if foreign:
foreign_pkgs.add(pkg.name)
return foreign_pkgs
+
+if __name__ == "__main__":
+ import DistUpgradeConfigParser
+ c = MyCache(DistUpgradeConfigParser.DistUpgradeConfig("."))
+ c.clear()