summaryrefslogtreecommitdiff
path: root/DistUpgrade/DistUpgradeControler.py
diff options
context:
space:
mode:
Diffstat (limited to 'DistUpgrade/DistUpgradeControler.py')
-rw-r--r--DistUpgrade/DistUpgradeControler.py767
1 files changed, 0 insertions, 767 deletions
diff --git a/DistUpgrade/DistUpgradeControler.py b/DistUpgrade/DistUpgradeControler.py
deleted file mode 100644
index 4e76a65d..00000000
--- a/DistUpgrade/DistUpgradeControler.py
+++ /dev/null
@@ -1,767 +0,0 @@
-# DistUpgradeControler.py
-#
-# Copyright (c) 2004-2006 Canonical
-#
-# Author: Michael Vogt <michael.vogt@ubuntu.com>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-
-import warnings
-warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
-import apt
-import apt_pkg
-import sys
-import os
-import subprocess
-import logging
-import re
-import statvfs
-import shutil
-import glob
-from DistUpgradeConfigParser import DistUpgradeConfig
-
-from aptsources import SourcesList, SourceEntry, Distribution, is_mirror
-from gettext import gettext as _
-import gettext
-from DistUpgradeCache import MyCache
-
-class AptCdrom(object):
- def __init__(self, view, path):
- self.view = view
- self.cdrompath = path
-
- def restoreBackup(self, backup_ext):
- " restore the backup copy of the cdroms.list file (*not* sources.list)! "
- cdromstate = os.path.join(apt_pkg.Config.FindDir("Dir::State"),
- apt_pkg.Config.Find("Dir::State::cdroms"))
- if os.path.exists(cdromstate+backup_ext):
- shutil.copy(cdromstate+backup_ext, cdromstate)
- # mvo: we don't have to care about restoring the sources.list here because
- # aptsources will do this for us anyway
-
- def add(self, backup_ext=None):
- " add a cdrom to apts database "
- logging.debug("AptCdrom.add() called with '%s'", self.cdrompath)
- # do backup (if needed) of the cdroms.list file
- if backup_ext:
- cdromstate = os.path.join(apt_pkg.Config.FindDir("Dir::State"),
- apt_pkg.Config.Find("Dir::State::cdroms"))
- if os.path.exists(cdromstate):
- shutil.copy(cdromstate, cdromstate+backup_ext)
- # do the actual work
- apt_pkg.Config.Set("Acquire::cdrom::mount",self.cdrompath)
- apt_pkg.Config.Set("APT::CDROM::NoMount","true")
- cdrom = apt_pkg.GetCdrom()
- # FIXME: add cdrom progress here for the view
- progress = self.view.getCdromProgress()
- try:
- res = cdrom.Add(progress)
- except SystemError, e:
- logging.error("can't add cdrom: %s" % e)
- self.view.error(_("Failed to add the CD"),
- _("There was a error adding the CD, the "
- "upgrade will abort. Please report this as "
- "a bug if this is a valid Ubuntu CD.\n\n"
- "The error message was:\n'%s'") % e)
- return False
- logging.debug("AptCdrom.add() returned: %s" % res)
- return res
-
- def __nonzero__(self):
- """ helper to use this as 'if cdrom:' """
- return self.cdrompath is not None
-
-class DistUpgradeControler(object):
- """ this is the controler that does most of the work """
-
- def __init__(self, distUpgradeView, options=None, datadir=None):
- # setup the pathes
- localedir = "/usr/share/locale/update-manager/"
- if datadir == None:
- datadir = os.getcwd()
- localedir = os.path.join(datadir,"mo")
- gladedir = datadir
- self.datadir = datadir
-
- self.options = options
-
- # init gettext
- gettext.bindtextdomain("update-manager",localedir)
- gettext.textdomain("update-manager")
-
- # setup the view
- self._view = distUpgradeView
- self._view.updateStatus(_("Reading cache"))
- self.cache = None
-
- if not self.options or self.options.withNetwork == None:
- self.useNetwork = True
- else:
- self.useNetwork = self.options.withNetwork
- if options:
- cdrompath = options.cdromPath
- else:
- cdrompath = None
- self.aptcdrom = AptCdrom(distUpgradeView, cdrompath)
-
- # the configuration
- self.config = DistUpgradeConfig(datadir)
- self.sources_backup_ext = "."+self.config.get("Files","BackupExt")
-
- # some constants here
- self.fromDist = self.config.get("Sources","From")
- self.toDist = self.config.get("Sources","To")
- self.origin = self.config.get("Sources","ValidOrigin")
-
- # forced obsoletes
- self.forced_obsoletes = self.config.getlist("Distro","ForcedObsoletes")
-
- # turn on debuging in the cache
- apt_pkg.Config.Set("Debug::pkgProblemResolver","true")
- apt_pkg.Config.Set("Debug::pkgDepCache::AutoInstall","true")
- fd = os.open("/var/log/dist-upgrade/apt.log",
- os.O_RDWR|os.O_CREAT|os.O_APPEND, 0644)
- os.dup2(fd,1)
- os.dup2(fd,2)
-
- def openCache(self):
- self.cache = MyCache(self.config, self._view.getOpCacheProgress())
-
- def prepare(self):
- """ initial cache opening, sanity checking, network checking """
- try:
- self.openCache()
- except SystemError, e:
- logging.error("openCache() failed: '%s'" % e)
- return False
- if not self.cache.sanityCheck(self._view):
- return False
- # FIXME: we may try to find out a bit more about the network
- # connection here and ask more inteligent questions
- if self.aptcdrom and self.options and self.options.withNetwork == None:
- res = self._view.askYesNoQuestion(_("Fetch data from the network for the upgrade?"),
- _("The upgrade can use the network to check "
- "the latest updates and to fetch packages that are not on the "
- "current CD.\n"
- "If you have fast or inexpensive network access you should answer "
- "'Yes' here. If networking is expensive for you choose 'No'.")
- )
- self.useNetwork = res
- logging.debug("useNetwork: '%s' (selected by user)" % res)
- return True
-
- def rewriteSourcesList(self, mirror_check=True):
- logging.debug("rewriteSourcesList()")
-
- # enable main (we always need this!)
- distro = Distribution()
- distro.get_sources(self.sources)
- # make sure that main is enabled
- distro.enable_component(self.sources, "main")
-
- # this must map, i.e. second in "from" must be the second in "to"
- # (but they can be different, so in theory we could exchange
- # component names here)
- fromDists = [self.fromDist,
- self.fromDist+"-security",
- self.fromDist+"-updates",
- self.fromDist+"-backports"
- ]
- toDists = [self.toDist,
- self.toDist+"-security",
- self.toDist+"-updates",
- self.toDist+"-backports"
- ]
-
- # list of valid mirrors that we can add
- valid_mirrors = self.config.getListFromFile("Sources","ValidMirrors")
-
- self.sources_disabled = False
-
- # look over the stuff we have
- foundToDist = False
- for entry in self.sources:
-
- # ignore invalid records or disabled ones
- if entry.invalid or entry.disabled:
- continue
-
- # we disable breezy cdrom sources to make sure that demoted
- # packages are removed
- if entry.uri.startswith("cdrom:") and entry.dist == self.fromDist:
- entry.disabled = True
- continue
- # ignore cdrom sources otherwise
- elif entry.uri.startswith("cdrom:"):
- continue
-
- logging.debug("examining: '%s'" % entry)
- # check if it's a mirror (or offical site)
- validMirror = False
- for mirror in valid_mirrors:
- if not mirror_check or is_mirror(mirror,entry.uri):
- validMirror = True
- # security is a special case
- res = not entry.uri.startswith("http://security.ubuntu.com") and not entry.disabled
- if entry.dist in toDists:
- # so the self.sources.list is already set to the new
- # distro
- logging.debug("entry '%s' is already set to new dist" % entry)
- foundToDist |= res
- elif entry.dist in fromDists:
- foundToDist |= res
- entry.dist = toDists[fromDists.index(entry.dist)]
- logging.debug("entry '%s' updated to new dist" % entry)
- else:
- # disable all entries that are official but don't
- # point to either "to" or "from" dist
- entry.disabled = True
- self.sources_disabled = True
- logging.debug("entry '%s' was disabled (unknown dist)" % entry)
- # it can only be one valid mirror, so we can break here
- break
- # disable anything that is not from a official mirror
- if not validMirror:
- entry.disabled = True
- self.sources_disabled = True
- logging.debug("entry '%s' was disabled (unknown mirror)" % entry)
- return foundToDist
-
- def updateSourcesList(self):
- logging.debug("updateSourcesList()")
- self.sources = SourcesList(matcherPath=".")
- if not self.rewriteSourcesList(mirror_check=True):
- logging.error("No valid mirror found")
- res = self._view.askYesNoQuestion(_("No valid mirror found"),
- _("While scaning your repository "
- "information no mirror entry for "
- "the upgrade was found."
- "This cam happen if you run a internal "
- "mirror or if the mirror information is "
- "out of date.\n\n"
- "Do you want to rewrite your "
- "'sources.list' file anyway? If you choose "
- "'Yes' here it will update all '%s' to '%s' "
- "entries.\n"
- "If you select 'no' the update will cancel."
- ) % (self.fromDist, self.toDist))
- if res:
- # re-init the sources and try again
- self.sources = SourcesList(matcherPath=".")
- if not self.rewriteSourcesList(mirror_check=False):
- #hm, still nothing useful ...
- prim = _("Generate default sources?")
- secon = _("After scanning your 'sources.list' no "
- "valid entry for '%s' was found.\n\n"
- "Should default entries for '%s' be "
- "added? If you select 'No' the update "
- "will cancel.") % (self.fromDist, self.toDist)
- if not self._view.askYesNoQuestion(prim, secon):
- self.abort()
-
- # add some defaults here
- # FIXME: find mirror here
- uri = "http://archive.ubuntu.com/ubuntu"
- comps = ["main","restricted"]
- self.sources.add("deb", uri, self.toDist, comps)
- self.sources.add("deb", uri, self.toDist+"-updates", comps)
- self.sources.add("deb",
- "http://security.ubuntu.com/ubuntu/",
- self.toDist+"-security", comps)
- else:
- self.abort()
-
- # write (well, backup first ;) !
- self.sources.backup(self.sources_backup_ext)
- self.sources.save()
-
- # re-check if the written self.sources are valid, if not revert and
- # bail out
- # TODO: check if some main packages are still available or if we
- # accidently shot them, if not, maybe offer to write a standard
- # sources.list?
- try:
- sourceslist = apt_pkg.GetPkgSourceList()
- sourceslist.ReadMainList()
- except SystemError:
- logging.error("Repository information invalid after updating (we broke it!)")
- self._view.error(_("Repository information invalid"),
- _("Upgrading the repository information "
- "resulted in a invalid file. Please "
- "report this as a bug."))
- return False
-
- if self.sources_disabled:
- self._view.information(_("Third party sources disabled"),
- _("Some third party entries in your sources.list "
- "were disabled. You can re-enable them "
- "after the upgrade with the "
- "'software-properties' tool or with synaptic."
- ))
- return True
-
- def _logChanges(self):
- # debuging output
- logging.debug("About to apply the following changes")
- inst = []
- up = []
- rm = []
- held = []
- for pkg in self.cache:
- if pkg.markedInstall: inst.append(pkg.name)
- elif pkg.markedUpgrade: up.append(pkg.name)
- elif pkg.markedDelete: rm.append(pkg.name)
- elif (pkg.isInstalled and pkg.isUpgradable): held.append(pkg.name)
- logging.debug("Held-back: %s" % " ".join(held))
- logging.debug("Remove: %s" % " ".join(rm))
- logging.debug("Install: %s" % " ".join(inst))
- logging.debug("Upgrade: %s" % " ".join(up))
-
-
- def doPreUpgrade(self):
- # FIXME: check out what packages are downloadable etc to
- # compare the list after the update again
- self.obsolete_pkgs = self.cache._getObsoletesPkgs()
- self.foreign_pkgs = self.cache._getForeignPkgs(self.origin, self.fromDist, self.toDist)
- logging.debug("Foreign: %s" % " ".join(self.foreign_pkgs))
- logging.debug("Obsolete: %s" % " ".join(self.obsolete_pkgs))
-
- def doUpdate(self):
- if not self.useNetwork:
- logging.debug("doUpdate() will not use the network because self.useNetwork==false")
- return True
- self.cache._list.ReadMainList()
- progress = self._view.getFetchProgress()
- # FIXME: retry here too? just like the DoDistUpgrade?
- # also remove all files from the lists partial dir!
- currentRetry = 0
- maxRetries = int(self.config.get("Network","MaxRetries"))
- while currentRetry < maxRetries:
- try:
- res = self.cache.update(progress)
- except IOError, e:
- logging.error("IOError in cache.update(): '%s'. Retrying (currentRetry: %s)" % (e,currentRetry))
- currentRetry += 1
- continue
- # no exception, so all was fine, we are done
- return True
-
- logging.error("doUpdate() failed complettely")
- self._view.error(_("Error during update"),
- _("A problem occured during the update. "
- "This is usually some sort of network "
- "problem, please check your network "
- "connection and retry."), "%s" % e)
- return False
-
-
- def _checkFreeSpace(self):
- " this checks if we have enough free space on /var and /usr"
- err_sum = _("Not enough free disk space")
- err_long= _("The upgrade aborts now. "
- "Please free at least %s of disk space on %s. "
- "Empty your trash and remove temporary "
- "packages of former installations using "
- "'sudo apt-get clean'.")
-
- # gather/log some staticts
- mnt_map = {}
- for d in ["/","/usr","/var","/boot"]:
- st = os.statvfs(d)
- free = st[statvfs.F_BAVAIL]*st[statvfs.F_FRSIZE]
- if st in mnt_map:
- logging.debug("Dir %s mounted on %s" % (d,mnt_map[st]))
- else:
- logging.debug("Free space on %s: %s" % (d,free))
- mnt_map[st] = d
- del mnt_map
-
- # first check for /var (or where the archives are downloaded too)
- archivedir = apt_pkg.Config.FindDir("Dir::Cache::archives")
- st_archivedir = os.statvfs(archivedir)
- free = st_archivedir[statvfs.F_BAVAIL]*st_archivedir[statvfs.F_FRSIZE]
- logging.debug("required download: %s " % self.cache.requiredDownload)
- logging.debug("free on %s: %s " % (archivedir, free))
- if self.cache.requiredDownload > free:
- free_at_least = apt_pkg.SizeToStr(self.cache.requiredDownload-free)
- logging.error("not enough free space (missing %s)" % free_at_least)
- self._view.error(err_sum, err_long % (free_at_least,archivedir))
- return False
-
- # then check for /usr assuming that all the data goes into /usr
- # this won't catch space problems when e.g. /boot,/usr/,/ are all
- # seperated partitions, but with a fragmented
- # patition layout we can't do a lot better because we don't know
- # the space-requirements on a per dir basis inside the deb without
- # looking into each
- logging.debug("need additional space: %s" % self.cache.additionalRequiredSpace)
- dir = "/usr"
- st_usr = os.statvfs(dir)
- if st_archivedir == st_usr:
- # we are on the same filesystem, so we need to take the space
- # for downloading the debs into account
- free -= self.cache.requiredDownload
- logging.debug("/usr on same fs as %s, taking dl-size into account, new free: %s" % (archivedir, free))
- else:
- free = st_usr[statvfs.F_BAVAIL]*st_usr[statvfs.F_FRSIZE]
- logging.debug("/usr on different fs than %s, free: %s" % (archivedir, free))
-
- safety_buffer = 1024*1024*100 # 100 Mb
- logging.debug("using safety buffer: %s" % safety_buffer)
- if (self.cache.additionalRequiredSpace+safety_buffer) > free:
- free_at_least = apt_pkg.SizeToStr(self.cache.additionalRequiredSpace+safety_buffer-free)
- logging.error("not enough free space, we need addional %s" % free_at_least)
- self._view.error(err_sum, err_long % (free_at_least,dir))
- return False
-
- # FIXME: we should try to esitmate if "/" has enough free space,
- # linux-restricted-modules and linux-image- are both putting there
- # modules there and those take a lot of space
-
- return True
-
- def askDistUpgrade(self):
- if not self.cache.distUpgrade(self._view):
- return False
- changes = self.cache.getChanges()
- # log the changes for debuging
- self._logChanges()
- # check if we have enough free space
- if not self._checkFreeSpace():
- return False
- # ask the user if he wants to do the changes
- res = self._view.confirmChanges(_("Do you want to start the upgrade?"),
- changes,
- self.cache.requiredDownload)
- return res
-
- def doDistUpgrade(self):
- if self.options and self.options.haveBackports:
- backportsdir = os.getcwd()+"/backports"
- apt_pkg.Config.Set("Dir::Bin::dpkg",backportsdir+"/usr/bin/dpkg");
- currentRetry = 0
- fprogress = self._view.getFetchProgress()
- iprogress = self._view.getInstallProgress(self.cache)
- # retry the fetching in case of errors
- maxRetries = int(self.config.get("Network","MaxRetries"))
- while currentRetry < maxRetries:
- try:
- res = self.cache.commit(fprogress,iprogress)
- except SystemError, e:
- # installing the packages failed, can't be retried
- logging.error("SystemError from cache.commit(): %s" % e)
- self._view.getTerminal().call(["dpkg","--configure","-a"])
- self._view.error(_("Could not install the upgrades"),
- _("The upgrade aborts now. Your system "
- "could be in an unusable state. A recovery "
- "was run (dpkg --configure -a).\n\n"
- "Please report this bug against the 'update-manager' "
- "package and include the files in /var/log/dist-upgrade/ "
- "in the bugreport."),
- "%s" % e)
- return False
- except IOError, e:
- # fetch failed, will be retried
- logging.error("IOError in cache.commit(): '%s'. Retrying (currentTry: %s)" % (e,currentRetry))
- currentRetry += 1
- continue
- # no exception, so all was fine, we are done
- return True
-
- # maximum fetch-retries reached without a successful commit
- logging.error("giving up on fetching after maximum retries")
- self._view.error(_("Could not download the upgrades"),
- _("The upgrade aborts now. Please check your "\
- "internet connection or "\
- "installation media and try again. "),
- "%s" % e)
- # abort here because we want our sources.list back
- self.abort()
-
-
-
- def doPostUpgrade(self):
- self.openCache()
- # check out what packages are cruft now
- # use self.{foreign,obsolete}_pkgs here and see what changed
- now_obsolete = self.cache._getObsoletesPkgs()
- now_foreign = self.cache._getForeignPkgs(self.origin, self.fromDist, self.toDist)
- logging.debug("Obsolete: %s" % " ".join(now_obsolete))
- logging.debug("Foreign: %s" % " ".join(now_foreign))
-
- # now get the meta-pkg specific obsoletes and purges
- for pkg in self.config.getlist("Distro","MetaPkgs"):
- if self.cache.has_key(pkg) and self.cache[pkg].isInstalled:
- self.forced_obsoletes.extend(self.config.getlist(pkg,"ForcedObsoletes"))
- logging.debug("forced_obsoletes: %s", self.forced_obsoletes)
-
- # check what packages got demoted
- demotions_file = self.config.get("Distro","Demotions")
- demotions = set()
- if os.path.exists(demotions_file):
- map(lambda pkgname: demotions.add(pkgname.strip()),
- filter(lambda line: not line.startswith("#"),
- open(demotions_file).readlines()))
- installed_demotions = filter(lambda pkg: pkg.isInstalled and pkg.name in demotions, self.cache)
- if len(installed_demotions) > 0:
- demoted = [pkg.name for pkg in installed_demotions]
- demoted.sort()
- logging.debug("demoted: '%s'" % " ".join(demoted))
- self._view.information(_("Support for some applications ended"),
- _("Canonical Ltd. no longer provides "
- "support for the following software "
- "packages. You can still get support "
- "from the community.\n\n"
- "If you have not enabled community "
- "maintained software (universe), "
- "these packages will be suggested for "
- "removal in the next step."),
- "\n".join(demoted))
-
- # mark packages that are now obsolete (and where not obsolete
- # before) to be deleted. make sure to not delete any foreign
- # (that is, not from ubuntu) packages
- if self.useNetwork:
- # we can only do the obsoletes calculation here if we use a
- # network. otherwise after rewriting the sources.list everything
- # that is not on the CD becomes obsolete (not-downloadable)
- remove_candidates = now_obsolete - self.obsolete_pkgs
- else:
- # initial remove candidates when no network is used should
- # be the demotions to make sure we don't leave potential
- # unsupported software
- remove_candidates = set(installed_demotions)
- remove_candidates |= set(self.forced_obsoletes)
- logging.debug("remove_candidates: '%s'" % remove_candidates)
- logging.debug("Start checking for obsolete pkgs")
- for pkgname in remove_candidates:
- if pkgname not in self.foreign_pkgs:
- if not self.cache._tryMarkObsoleteForRemoval(pkgname, remove_candidates, self.foreign_pkgs):
- logging.debug("'%s' scheduled for remove but not in remove_candiates, skipping", pkgname)
- logging.debug("Finish checking for obsolete pkgs")
-
- # get changes
- changes = self.cache.getChanges()
- logging.debug("The following packages are remove candidates: %s" % " ".join([pkg.name for pkg in changes]))
- summary = _("Remove obsolete packages?")
- actions = [_("_Skip This Step"), _("_Remove")]
- # FIXME Add an explanation about what obsolete pacages are
- #explanation = _("")
- if len(changes) > 0 and \
- self._view.confirmChanges(summary, changes, 0, actions):
- fprogress = self._view.getFetchProgress()
- iprogress = self._view.getInstallProgress(self.cache)
- try:
- res = self.cache.commit(fprogress,iprogress)
- except (SystemError, IOError), e:
- logging.error("cache.commit() in doPostUpgrade() failed: %s" % e)
- self._view.error(_("Error during commit"),
- _("Some problem occured during the clean-up. "
- "Please see the below message for more "
- "information. "),
- "%s" % e)
-
- def abort(self):
- """ abort the upgrade, cleanup (as much as possible) """
- if hasattr(self, "sources"):
- self.sources.restoreBackup(self.sources_backup_ext)
- if hasattr(self, "aptcdrom"):
- self.aptcdrom.restoreBackup(self.sources_backup_ext)
- # generate a new cache
- self._view.updateStatus(_("Restoring original system state"))
- self._view.abort()
- self.openCache()
- sys.exit(1)
-
- def getRequiredBackports(self):
- " download the backports specified in DistUpgrade.cfg "
- # add the backports sources.list fragment
- shutil.copy(self.config.get("Backports","SourcesList"),
- apt_pkg.Config.FindDir("Dir::Etc::sourceparts"))
- # run update
- self.doUpdate()
- self.openCache()
-
- # save cachedir and setup new one
- cachedir = apt_pkg.Config.Find("Dir::Cache::archives")
- cwd = os.getcwd()
- backportsdir = os.path.join(os.getcwd(),"backports")
- if not os.path.exists(backportsdir):
- os.mkdir(backportsdir)
- if not os.path.exists(os.path.join(backportsdir,"partial")):
- os.mkdir(os.path.join(backportsdir,"partial"))
- os.chdir(backportsdir)
- apt_pkg.Config.Set("Dir::Cache::archives",backportsdir)
-
- # mark the backports for upgrade and get them
- fetcher = apt_pkg.GetAcquire(self._view.getFetchProgress())
- # FIXME: add a version line to the cfg file to make sure
- # we get the right version file! and add sanity checking
- # that we don't get (accidently) the edgy version
- for pkgname in self.config.getlist("Backports","Packages"):
- pkg = self.cache[pkgname]
- # look for the right version (backport)
- for ver in pkg._pkg.VersionList:
- print ver.VerStr
- if self.config.get("Backports","VersionIdent") in ver.VerStr:
- break
- else:
- # FIXME: be more clever here (exception)
- raise Exception, "No backport found!?!"
- return False
- if ver.FileList == None:
- print "No FileList for: %s " % self._pkg.Name()
- return False
- f, index = ver.FileList.pop(0)
- pkg._records.Lookup((f,index))
- path = apt_pkg.ParseSection(pkg._records.Record)["Filename"]
- for (packagefile,i) in ver.FileList:
- indexfile = self.cache._list.FindIndex(packagefile)
- if indexfile:
- match = re.match(r"<.*ArchiveURI='(.*)'>$",
- str(indexfile))
- if match:
- uri = match.group(1) + path
- apt_pkg.GetPkgAcqFile(fetcher, uri=uri,
- size=ver.Size,
- descr=_("Fetching backport of '%s'") % pkgname)
- res = fetcher.Run()
- if res != fetcher.ResultContinue:
- # ick! error ...
- return False
-
- # reset the cache dir
- os.unlink(apt_pkg.Config.FindDir("Dir::Etc::sourceparts")+"/backport-source.list")
- apt_pkg.Config.Set("Dir::Cache::archives",cachedir)
- os.chdir(cwd)
- # unpack it
- for deb in glob.glob(backportsdir+"/*.deb"):
- ret = os.system("dpkg-deb -x %s %s" % (deb, backportsdir))
- # FIXME: do error checking
- return self.setupRequiredBackports(backportsdir)
-
- def setupRequiredBackports(self, backportsdir):
- " setup the required backports in a evil way "
- # setup some pathes to make sure the new stuff is used
- os.environ["LD_LIBRARY_PATH"] = backportsdir+"/usr/lib"
- os.environ["PYTHONPATH"] = backportsdir+"/usr/lib/python2.4/site-packages/"
- os.environ["PATH"] = "%s:%s" % (backportsdir+"/usr/bin",
- os.getenv("PATH"))
-
- # now exec self again
- args = sys.argv+["--have-backports"]
- if self.useNetwork:
- args.append("--with-network")
- else:
- args.append("--without-network")
- os.execve(sys.argv[0],args, os.environ)
-
- # this is the core
- def edgyUpgrade(self):
- # sanity check (check for ubuntu-desktop, brokenCache etc)
- self._view.updateStatus(_("Checking package manager"))
- self._view.setStep(1)
-
- if not self.prepare():
- logging.error("self.prepared() failed")
- self._view.error(_("Preparing the upgrade failed"),
- _("Preparing the system for the upgrade "
- "failed. Please report this as a bug "
- "against the 'update-manager' "
- "package and include the files in "
- "/var/log/dist-upgrade/ "
- "in the bugreport." ))
- sys.exit(1)
-
- # mvo: commented out for now, see #54234, this needs to be
- # refactored to use a arch=any tarball
- #if self.options and self.options.haveBackports == False:
- # # get backported packages (if needed)
- # self.getRequiredBackports()
-
- # run a "apt-get update" now
- if not self.doUpdate():
- sys.exit(1)
-
- # do pre-upgrade stuff (calc list of obsolete pkgs etc)
- self.doPreUpgrade()
-
- # update sources.list
- self._view.setStep(2)
- self._view.updateStatus(_("Updating repository information"))
- if not self.updateSourcesList():
- self.abort()
-
- # add cdrom (if we have one)
- if (self.aptcdrom and
- not self.aptcdrom.add(self.sources_backup_ext)):
- sys.exit(1)
-
- # then update the package index files
- if not self.doUpdate():
- self.abort()
-
- # then open the cache (again)
- self._view.updateStatus(_("Checking package manager"))
- self.openCache()
- # now check if we still have some key packages after the update
- # if not something went seriously wrong
- for pkg in self.config.getlist("Distro","BaseMetaPkgs"):
- if not self.cache.has_key(pkg):
- # FIXME: we could offer to add default source entries here,
- # but we need to be careful to not duplicate them
- # (i.e. the error here could be something else than
- # missing sources entires but network errors etc)
- logging.error("No '%s' after sources.list rewrite+update")
- self._view.error(_("Invalid package information"),
- _("After your package information was "
- "updated the essential package '%s' can "
- "not be found anymore.\n"
- "This indicates a serious error, please "
- "report this bug against the 'update-manager' "
- "package and include the files in /var/log/dist-upgrade/ "
- "in the bugreport.") % pkg)
- self.abort()
-
- # calc the dist-upgrade and see if the removals are ok/expected
- # do the dist-upgrade
- self._view.setStep(3)
- self._view.updateStatus(_("Asking for confirmation"))
- if not self.askDistUpgrade():
- self.abort()
-
- self._view.updateStatus(_("Upgrading"))
- if not self.doDistUpgrade():
- # don't abort here, because it would restore the sources.list
- sys.exit(1)
-
- # do post-upgrade stuff
- self._view.setStep(4)
- self._view.updateStatus(_("Searching for obsolete software"))
- self.doPostUpgrade()
-
- # done, ask for reboot
- self._view.setStep(5)
- self._view.updateStatus(_("System upgrade is complete."))
- # FIXME should we look into /var/run/reboot-required here?
- if self._view.confirmRestart():
- subprocess.call(["reboot"])
-
- def run(self):
- self.edgyUpgrade()
-
-