summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DistUpgrade/DistUpgradeCache.py192
-rw-r--r--DistUpgrade/DistUpgradeControler.py204
-rw-r--r--DistUpgrade/removal_blacklist.txt2
3 files changed, 198 insertions, 200 deletions
diff --git a/DistUpgrade/DistUpgradeCache.py b/DistUpgrade/DistUpgradeCache.py
new file mode 100644
index 00000000..26df7144
--- /dev/null
+++ b/DistUpgrade/DistUpgradeCache.py
@@ -0,0 +1,192 @@
+
+import apt
+import apt_pkg
+import os
+import re
+
+class MyCache(apt.Cache):
+ # init
+ def __init__(self, progress=None):
+ apt.Cache.__init__(self, progress)
+ self.to_install = []
+ self.to_remove = []
+ # turn on debuging
+ apt_pkg.Config.Set("Debug::pkgProblemResolver","true")
+ fd = os.open(os.path.expanduser("~/dist-upgrade-apt.log"), os.O_RDWR|os.O_CREAT|os.O_TRUNC)
+ os.dup2(fd,1)
+ os.dup2(fd,2)
+
+ # a list of regexp that are not allowed to be removed
+ self.removal_blacklist = []
+ for line in open("removal_blacklist.txt").readlines():
+ line = line.strip()
+ if not line == "" or line.startswith("#"):
+ self.removal_blacklist.append(line)
+
+ # properties
+ @property
+ def requiredDownload(self):
+ """ get the size of the packages that are required to download """
+ pm = apt_pkg.GetPackageManager(self._depcache)
+ fetcher = apt_pkg.GetAcquire()
+ pm.GetArchives(fetcher, self._list, self._records)
+ return fetcher.FetchNeeded
+ @property
+ def isBroken(self):
+ """ is the cache broken """
+ return self._depcache.BrokenCount > 0
+
+ # methods
+ def downloadable(self, pkg, useCandidate=True):
+ " check if the given pkg can be downloaded "
+ if useCandidate:
+ ver = self._depcache.GetCandidateVer(pkg._pkg)
+ else:
+ ver = pkg._pkg.CurrentVer
+ if ver == None:
+ return False
+ return ver.Downloadable
+
+ def fixBroken(self):
+ """ try to fix broken dependencies on the system, may throw
+ SystemError when it can't"""
+ return self._depcache.FixBroken()
+
+ def create_snapshot(self):
+ """ create a snapshot of the current changes """
+ self.to_install = []
+ self.to_remove = []
+ for pkg in self.getChanges():
+ if pkg.markedInstall or pkg.markedUpgrade:
+ self.to_install.append(pkg.name)
+ if pkg.markedDelete:
+ self.to_remove.append(pkg.name)
+
+ def restore_snapshot(self):
+ """ restore a snapshot """
+ for pkg in self:
+ pkg.markKeep()
+ for name in self.to_remove:
+ pkg = self[name]
+ pkg.markDelete()
+ for name in self.to_install:
+ pkg = self[name]
+ pkg.markInstall()
+
+ def sanityCheck(self, view):
+ """ check if the cache is ok and if the required metapkgs
+ are installed
+ """
+ if self.isBroken:
+ try:
+ logging.debug("Have broken pkgs, trying to fix them")
+ self.fixBroken()
+ except SystemError:
+ view.error(_("Broken packages"),
+ _("Your system contains broken packages "
+ "that couldn't be fixed with this "
+ "software. "
+ "Please fix them first using synaptic or "
+ "apt-get before proceeding."))
+ return False
+ return True
+
+ def distUpgrade(self, view):
+ try:
+ # upgrade (and make sure this way that the cache is ok)
+ self.upgrade(True)
+ self._installMetaPkgs(view)
+ 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
+ self._view.error(_("Could not calculate the upgrade"),
+ _("A unresolvable problem occured while "
+ "calculating the upgrade. Please report "
+ "this as a bug. "))
+ logging.debug("Dist-upgrade failed: '%s'", e)
+ return False
+ return True
+
+ def _verifyChanges(self):
+ """ this function tests if the current changes don't violate
+ our constrains (blacklisted removals etc)
+ """
+ for pkg in self.getChanges():
+ if pkg.markedDelete and self._inRemovalBlacklist(pkg.name):
+ logging.debug("The package '%s' is marked for removal but it's in the removal blacklist", pkg.name)
+ return False
+ return True
+
+ def _installMetaPkgs(self, view):
+ # now check for ubuntu-base
+ if not self["ubuntu-base"].isInstalled:
+ self["ubuntu-base"].markInstall()
+
+ # now check for ubuntu-desktop, kubuntu-desktop, edubuntu-desktop
+ metapkgs = {"ubuntu-desktop": ["gdm","gnome-panel", "ubuntu-artwork"],
+ "kubuntu-desktop": ["kdm", "kicker",
+ "kubuntu-artwork-usplash"],
+ "edubuntu-desktop": ["edubuntu-artwork", "tuxpaint"]
+ }
+ # helper
+ def metaPkgInstalled():
+ metapkg_found = False
+ for key in metapkgs:
+ if self.has_key(key) and (self[key].isInstalled or self[key].markedInstall):
+ metapkg_found=True
+ return metapkg_found
+ # check if we have a meta-pkg, if not, try to guess which one to pick
+ if not metaPkgInstalled():
+ logging.debug("no {ubuntu,edubuntu,kubuntu}-desktop pkg installed")
+ for key in metapkgs:
+ deps_found = True
+ for pkg in metapkgs[key]:
+ deps_found &= self.has_key(pkg) and self[pkg].isInstalled
+ if deps_found:
+ logging.debug("guessing '%s' as missing meta-pkg" % key)
+ try:
+ self[key].markInstall()
+ except SystemError:
+ logging.error("failed to mark '%s' for install" % key)
+ view.error(_("Can't install '%s'" % key),
+ _("It was impossible to install a "
+ "required package. Please report "
+ "this as a bug. "))
+ return False
+ # check if we actually found one
+ if not metaPkgInstalled() and len(self.missing_pkgs) == 0:
+ # FIXME: provide a list
+ view.error(_("Can't guess meta-package"),
+ _("Your system does not contain a "
+ "ubuntu-desktop, kubuntu-desktop or "
+ "edubuntu-desktop package and it was not "
+ "possible to detect which version of "
+ "ubuntu you are runing.\n "
+ "Please install one of the packages "
+ "above first using synaptic or "
+ "apt-get before proceeding."))
+ return False
+
+ # FIXME: check for ubuntu-desktop, kubuntu-dekstop, edubuntu-desktop
+ return True
+
+ def _inRemovalBlacklist(self, pkgname):
+ for expr in self.removal_blacklist:
+ if re.compile(expr).match(pkgname):
+ return True
+ return False
+
+ def _tryMarkObsoleteForRemoval(self, pkgname, remove_candidates):
+ # this is a delete candidate, only actually delete,
+ # if it dosn't remove other packages depending on it
+ # that are not obsolete as well
+ self.cache.create_snapshot()
+ self.cache[pkgname].markDelete()
+ for pkg in self.cache.getChanges():
+ if pkg.name not in remove_candidates or \
+ pkg.name in self.foreign_pkgs or \
+ self._inRemovalBlacklist(pkg.name):
+ self.cache.restore_snapshot()
+ return False
+ return True
diff --git a/DistUpgrade/DistUpgradeControler.py b/DistUpgrade/DistUpgradeControler.py
index 80c4dd0c..fe679830 100644
--- a/DistUpgrade/DistUpgradeControler.py
+++ b/DistUpgrade/DistUpgradeControler.py
@@ -31,64 +31,8 @@ import re
from UpdateManager.Common.SimpleGladeApp import SimpleGladeApp
from SoftwareProperties.aptsources import SourcesList, SourceEntry
from gettext import gettext as _
+from DistUpgradeCache import MyCache
-
-class MyCache(apt.Cache):
- # init
- def __init__(self, progress=None):
- apt.Cache.__init__(self, progress)
- self.to_install = []
- self.to_remove = []
- # turn on debuging
- apt_pkg.Config.Set("Debug::pkgProblemResolver","true")
- fd = os.open(os.path.expanduser("~/dist-upgrade-apt.log"), os.O_RDWR|os.O_CREAT|os.O_TRUNC)
- os.dup2(fd,1)
- os.dup2(fd,2)
-
- # properties
- @property
- def requiredDownload(self):
- pm = apt_pkg.GetPackageManager(self._depcache)
- fetcher = apt_pkg.GetAcquire()
- pm.GetArchives(fetcher, self._list, self._records)
- return fetcher.FetchNeeded
- @property
- def isBroken(self):
- return self._depcache.BrokenCount > 0
-
- # methods
- def downloadable(self, pkg, useCandidate=True):
- " check if the given pkg can be downloaded "
- if useCandidate:
- ver = self._depcache.GetCandidateVer(pkg._pkg)
- else:
- ver = pkg._pkg.CurrentVer
- if ver == None:
- return False
- return ver.Downloadable
- def fixBroken(self):
- """ try to fix broken dependencies on the system, may throw
- SystemError when it can't"""
- return self._depcache.FixBroken()
- def create_snapshot(self):
- """ create a snapshot of the current changes """
- self.to_install = []
- self.to_remove = []
- for pkg in self.getChanges():
- if pkg.markedInstall or pkg.markedUpgrade:
- self.to_install.append(pkg.name)
- if pkg.markedDelete:
- self.to_remove.append(pkg.name)
- def restore_snapshot(self):
- """ restore a snapshot """
- for pkg in self:
- pkg.markKeep()
- for name in self.to_remove:
- pkg = self[name]
- pkg.markDelete()
- for name in self.to_install:
- pkg = self[name]
- pkg.markInstall()
class DistUpgradeControler(object):
@@ -109,74 +53,10 @@ class DistUpgradeControler(object):
# be added before the dist-upgrade (e.g. missing ubuntu-desktop)
self.missing_pkgs = []
- # a list of regexp that are not allowed to be removed
- self.removal_blacklist = []
- for line in open("removal_blacklist.txt").readlines():
- line = line.strip()
- if not line == "" or line.startswith("#"):
- self.removal_blacklist.append(line)
def openCache(self):
self.cache = MyCache(self._view.getOpCacheProgress())
- def sanityCheck(self):
- if self.cache.isBroken:
- try:
- logging.debug("Have broken pkgs, trying to fix them")
- self.cache.fixBroken()
- except SystemError:
- self._view.error(_("Broken packages"),
- _("Your system contains broken packages "
- "that couldn't be fixed with this "
- "software. "
- "Please fix them first using synaptic or "
- "apt-get before proceeding."))
- return False
-
- # now check for ubuntu-base
- if not self.cache.has_key("ubuntu-base") or \
- not self.cache["ubuntu-base"].isInstalled:
- self.missing_pkgs.append("ubuntu-base")
-
- # now check for ubuntu-desktop, kubuntu-desktop, edubuntu-desktop
- metapkgs = {"ubuntu-desktop": ["gdm","gnome-panel", "ubuntu-artwork"],
- "kubuntu-desktop": ["kdm", "kicker",
- "kubuntu-artwork-usplash"],
- "edubuntu-desktop": ["edubuntu-artwork", "tuxpaint"]
- }
- # helper
- def metaPkgInstalled():
- metapkg_found = False
- for key in metapkgs:
- if self.cache.has_key(key) and (self.cache[key].isInstalled or self.cache[key].markedInstall):
- metapkg_found=True
- return metapkg_found
- # check if we have a meta-pkg, if not, try to guess which one to pick
- if not metaPkgInstalled():
- logging.debug("no {ubuntu,edubuntu,kubuntu}-desktop pkg installed")
- for key in metapkgs:
- deps_found = True
- for pkg in metapkgs[key]:
- deps_found &= self.cache.has_key(pkg) and self.cache[pkg].isInstalled
- if deps_found:
- logging.debug("guessing '%s' as missing meta-pkg" % key)
- self.missing_pkgs.append(key)
- # check if we actually found one
- if not metaPkgInstalled() and len(self.missing_pkgs) == 0:
- # FIXME: provide a list
- self._view.error(_("Can't guess meta-package"),
- _("Your system does not contain a "
- "ubuntu-desktop, kubuntu-desktop or "
- "edubuntu-desktop package and it was not "
- "possible to detect which version of "
- "ubuntu you are runing.\n "
- "Please install one of the packages "
- "above first using synaptic or "
- "apt-get before proceeding."))
- return False
-
- # FIXME: check for ubuntu-desktop, kubuntu-dekstop, edubuntu-desktop
- return True
def updateSourcesList(self):
self.sources = SourcesList()
@@ -316,53 +196,8 @@ class DistUpgradeControler(object):
return True
def askDistUpgrade(self):
- try:
- # upgrade (and make sure this way that the cache is ok)
- self.cache.upgrade(True)
- # then add missing pkgs (like {ubuntu,kubuntu,edubuntu}-desktop)
- for pkg in self.missing_pkgs:
- logging.debug("Installing missing pkg: %s" % pkg)
- self.cache[pkg].markInstall()
- 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
- self._view.error(_("Could not calculate the upgrade"),
- _("A unresolvable problem occured while "
- "calculating the upgrade. Please report "
- "this as a bug. "))
- logging.debug("Dist-upgrade failed: '%s'", e)
+ if not self.cache.distUpgrade(self._view):
return False
-
- # now do some sanity checking,
- try:
- #are all missing_pkgs really installed?
- for pkgname in self.missing_pkgs:
- pkg = self.cache[pkgname]
- if not (pkg.markedInstall or pkg.markedUpgrade):
- logging.error("Missing pkg '%s' not installed after upgrade" % pkgname)
- raise AssertionError
- # do we still have ubuntu-base?
- pkg = self.cache["ubuntu-base"]
- if not (pkg.markedInstall or pkg.markedUpgrade or pkg.markedKeep):
- logging.error("No ubuntu-base installed after upgrade")
- raise AssertionError
- # one desktop package?
- found = False
- for n in ["ubuntu-desktop","kubuntu-desktop","edubuntu-desktop"]:
- pkg = self.cache[n]
- if pkg.markedKeep or pkg.markedInstall or pkg.markedUpgrade:
- found = True
- if not found:
- logging.error("No dekstop pkg installed after upgrade")
- raise AssertionError
- except AssertionError:
- self._view.error(_("Could not calculate the upgrade"),
- _("After calculation the upgrade one of the "
- "essential packages can't be upgraded or "
- "installed. Please report this as a bug. "))
- return False
-
changes = self.cache.getChanges()
# log the changes for debuging
self._logChanges()
@@ -385,35 +220,6 @@ class DistUpgradeControler(object):
return False
return True
- def _inRemovalBlacklist(self, pkgname):
- for expr in self.removal_blacklist:
- if re.compile(expr).match(pkgname):
- return True
- return False
-
- def _verifyChanges(self):
- """ this function tests if the current changes don't violate
- our constrains (blacklisted removals etc)
- """
- for pkg in self.cache.getChanges():
- if pkg.markedDelete and self._inRemovalBlacklist(pkg.name):
- logging.debug("The package '%s' is marked for removal but it's in the removal blacklist", pkg.name)
- return False
- return True
-
- def _tryMarkObsoleteForRemoval(self, pkgname, remove_candidates):
- # this is a delete candidate, only actually delete,
- # if it dosn't remove other packages depending on it
- # that are not obsolete as well
- self.cache.create_snapshot()
- self.cache[pkgname].markDelete()
- for pkg in self.cache.getChanges():
- if pkg.name not in remove_candidates or \
- pkg.name in self.foreign_pkgs or \
- self._inRemovalBlacklist(pkg.name):
- self.cache.restore_snapshot()
- return False
- return True
def doPostUpgrade(self):
self.openCache()
@@ -431,7 +237,7 @@ class DistUpgradeControler(object):
logging.debug("Start checking for obsolete pkgs")
for pkgname in remove_candidates:
if pkgname not in self.foreign_pkgs:
- if not self._tryMarkObsoleteForRemoval(pkgname,
+ if not self.cache._tryMarkObsoleteForRemoval(pkgname,
remove_candidates):
logging.debug("'%s' scheduled for remove but not in remove_candiates, skipping", pkgname)
logging.debug("Finish checking for obsolete pkgs")
@@ -462,8 +268,8 @@ class DistUpgradeControler(object):
self._view.updateStatus(_("Checking the system"))
self._view.setStep(1)
self.openCache()
- if not self.sanityCheck():
- sys.exit(1)
+ if not self.cache.sanityCheck(self._view):
+ abort(1)
# do pre-upgrade stuff (calc list of obsolete pkgs etc)
self.doPreUpdate()
diff --git a/DistUpgrade/removal_blacklist.txt b/DistUpgrade/removal_blacklist.txt
index 7d0ee2fb..86b2a831 100644
--- a/DistUpgrade/removal_blacklist.txt
+++ b/DistUpgrade/removal_blacklist.txt
@@ -1,7 +1,7 @@
# blacklist of packages that should never be removed
+ubuntu-base
ubuntu-desktop
kubuntu-destkop
edubuntu-desktop
-ubuntu-base
linux-image-.*
linux-restricted-.*