diff options
Diffstat (limited to 'DistUpgrade')
| -rw-r--r-- | DistUpgrade/Changelog | 4 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgrade.cfg | 8 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeCache.py | 16 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeConfigParser.py | 4 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeControler.py | 127 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeView.py | 1 | ||||
| -rw-r--r-- | DistUpgrade/DistUpgradeViewGtk.py | 12 | ||||
| -rw-r--r-- | DistUpgrade/README | 9 | ||||
| -rw-r--r-- | DistUpgrade/backport-source.list | 2 | ||||
| -rwxr-xr-x | DistUpgrade/build-tarball.sh | 3 | ||||
| -rwxr-xr-x | DistUpgrade/dist-upgrade.py | 6 |
11 files changed, 163 insertions, 29 deletions
diff --git a/DistUpgrade/Changelog b/DistUpgrade/Changelog index 33ecff3d..54d194e6 100644 --- a/DistUpgrade/Changelog +++ b/DistUpgrade/Changelog @@ -1,3 +1,7 @@ +2006-09-23: + - support fetching backports of selected packages first and + use them for the upgrade (needed to support Breaks) + - fetch/use apt/dpkg/python-apt backports for the upgrade 2006-09-06: - increased the "free-space-savety-buffer" to 100MB 2006-09-05: diff --git a/DistUpgrade/DistUpgrade.cfg b/DistUpgrade/DistUpgrade.cfg index 7a8ebba9..60c3ca9f 100644 --- a/DistUpgrade/DistUpgrade.cfg +++ b/DistUpgrade/DistUpgrade.cfg @@ -39,5 +39,11 @@ To=edgy ValidOrigin=Ubuntu ValidMirrors = mirrors.cfg +[Backports] +Packages=apt,dpkg,python2.4-apt +VersionIdent=~dapper +SourcesList=backport-source.list + + [Network] -MaxRetries=3
\ No newline at end of file +MaxRetries=3 diff --git a/DistUpgrade/DistUpgradeCache.py b/DistUpgrade/DistUpgradeCache.py index 680e7d9e..8427bb3d 100644 --- a/DistUpgrade/DistUpgradeCache.py +++ b/DistUpgrade/DistUpgradeCache.py @@ -1,6 +1,7 @@ import warnings warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning) +warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning) import apt import apt_pkg import os @@ -66,10 +67,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() @@ -155,7 +158,7 @@ class MyCache(apt.Cache): 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/ " @@ -259,7 +262,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.")) @@ -315,3 +318,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() diff --git a/DistUpgrade/DistUpgradeConfigParser.py b/DistUpgrade/DistUpgradeConfigParser.py index 6879dfda..d5391939 100644 --- a/DistUpgrade/DistUpgradeConfigParser.py +++ b/DistUpgrade/DistUpgradeConfigParser.py @@ -2,10 +2,10 @@ from ConfigParser import ConfigParser, NoOptionError class DistUpgradeConfig(ConfigParser): - def __init__(self, datadir): + def __init__(self, datadir, name="DistUpgrade.cfg"): ConfigParser.__init__(self) self.datadir=datadir - self.read([datadir+'/DistUpgrade.cfg']) + self.read([datadir+"/"+name]) def getlist(self, section, option): try: tmp = self.get(section, option) diff --git a/DistUpgrade/DistUpgradeControler.py b/DistUpgrade/DistUpgradeControler.py index 800590cb..e32c0c5f 100644 --- a/DistUpgrade/DistUpgradeControler.py +++ b/DistUpgrade/DistUpgradeControler.py @@ -31,6 +31,7 @@ import logging import re import statvfs import shutil +import glob from DistUpgradeConfigParser import DistUpgradeConfig from aptsources import SourcesList, SourceEntry, Distribution, is_mirror @@ -86,7 +87,7 @@ class AptCdrom(object): class DistUpgradeControler(object): """ this is the controler that does most of the work """ - def __init__(self, distUpgradeView, cdromPath=None, datadir=None): + def __init__(self, distUpgradeView, options=None, datadir=None): # setup the pathes localedir = "/usr/share/locale/update-manager/" if datadir == None: @@ -95,6 +96,8 @@ class DistUpgradeControler(object): gladedir = datadir self.datadir = datadir + self.options = options + # init gettext gettext.bindtextdomain("update-manager",localedir) gettext.textdomain("update-manager") @@ -104,9 +107,15 @@ class DistUpgradeControler(object): self._view.updateStatus(_("Reading cache")) self.cache = None - # specific for the CDROM based upgrade - self.aptcdrom = AptCdrom(distUpgradeView, cdromPath) - self.useNetwork = True + 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) @@ -123,9 +132,8 @@ class DistUpgradeControler(object): # turn on debuging in the cache apt_pkg.Config.Set("Debug::pkgProblemResolver","true") apt_pkg.Config.Set("Debug::pkgDepCache::AutoInstall","true") - # FIXME: make this "append"? fd = os.open("/var/log/dist-upgrade/apt.log", - os.O_RDWR|os.O_CREAT|os.O_TRUNC, 0644) + os.O_RDWR|os.O_CREAT|os.O_APPEND, 0644) os.dup2(fd,1) os.dup2(fd,2) @@ -137,9 +145,9 @@ class DistUpgradeControler(object): self.openCache() 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: + # 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 " @@ -270,7 +278,7 @@ class DistUpgradeControler(object): self.toDist+"-security", comps) else: self.abort() - + # write (well, backup first ;) ! self.sources.backup(self.sources_backup_ext) self.sources.save() @@ -293,7 +301,7 @@ class DistUpgradeControler(object): if self.sources_disabled: self._view.information(_("Third party sources disabled"), - _("Some third party entries in your souces.list " + _("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." @@ -418,6 +426,9 @@ class DistUpgradeControler(object): 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) @@ -540,24 +551,112 @@ class DistUpgradeControler(object): def abort(self): """ abort the upgrade, cleanup (as much as possible) """ - self.sources.restoreBackup(self.sources_backup_ext) - self.aptcdrom.restoreBackup(self.sources_backup_ext) + 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) + return self.setupRequiredBackports(backportsdir) + + def setupRequiredBackports(self, backportsdir): + " setup the required backports in a evil way " + # unpack it + for deb in glob.glob(backportsdir+"/*.deb"): + ret = os.system("dpkg-deb -x %s %s" % (deb, backportsdir)) + # FIXME: do error checking + # 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(): self.abort(1) + 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) diff --git a/DistUpgrade/DistUpgradeView.py b/DistUpgrade/DistUpgradeView.py index d5b430b8..a9cd16d7 100644 --- a/DistUpgrade/DistUpgradeView.py +++ b/DistUpgrade/DistUpgradeView.py @@ -43,6 +43,7 @@ def estimatedDownloadTime(requiredDownload): class DumbTerminal(object): def call(self, cmd): " expects a command in the subprocess style (as a list) " + import subprocess subprocess.call(cmd) diff --git a/DistUpgrade/DistUpgradeViewGtk.py b/DistUpgrade/DistUpgradeViewGtk.py index 5a3779e9..1385d18f 100644 --- a/DistUpgrade/DistUpgradeViewGtk.py +++ b/DistUpgrade/DistUpgradeViewGtk.py @@ -484,19 +484,19 @@ class DistUpgradeViewGtk(DistUpgradeView,SimpleGladeApp): if pkgs_remove > 0: # FIXME: make those two seperate lines to make it clear # that the "%" applies to the result of ngettext - msg += gettext.ngettext("%s package is going to be removed.", - "%s packages are going to be removed.", + msg += gettext.ngettext("%d package is going to be removed.", + "%d packages are going to be removed.", pkgs_remove) % pkgs_remove msg += " " if pkgs_inst > 0: - msg += gettext.ngettext("%s new package is going to be " + msg += gettext.ngettext("%d new package is going to be " "installed.", - "%s new packages are going to be " + "%d new packages are going to be " "installed.",pkgs_inst) % pkgs_inst msg += " " if pkgs_upgrade > 0: - msg += gettext.ngettext("%s package is going to be upgraded.", - "%s packages are going to be upgraded.", + msg += gettext.ngettext("%d package is going to be upgraded.", + "%d packages are going to be upgraded.", pkgs_upgrade) % pkgs_upgrade msg +=" " if downloadSize > 0: diff --git a/DistUpgrade/README b/DistUpgrade/README index 60c761d6..c38a422f 100644 --- a/DistUpgrade/README +++ b/DistUpgrade/README @@ -46,4 +46,11 @@ ForcedObsoletes: [Sources] - how to rewrite the sources.list -[Network] - network specific options
\ No newline at end of file +[Network] - network specific options + +[Backports] - use specific packages for dist-upgrade +Packages= List of what packages to look for +VersionIdent=Version identification. needs to be uniq, dist-upgrader will + fetch the version that contains this string +SourcesList=a sources.list fragment that will be placed into + /etc/apt/sources.list.d and that contains the backported pkgs
\ No newline at end of file diff --git a/DistUpgrade/backport-source.list b/DistUpgrade/backport-source.list new file mode 100644 index 00000000..5945e218 --- /dev/null +++ b/DistUpgrade/backport-source.list @@ -0,0 +1,2 @@ +# sources.list fragment for backported apt/dpkg/python-apt +deb http://people.ubuntu.com/~mvo/backports/dapper /
\ No newline at end of file diff --git a/DistUpgrade/build-tarball.sh b/DistUpgrade/build-tarball.sh index 4f88b848..df9d6506 100755 --- a/DistUpgrade/build-tarball.sh +++ b/DistUpgrade/build-tarball.sh @@ -3,7 +3,10 @@ DIST=edgy # cleanup +echo "Cleaning up" rm -f *~ *.bak *.pyc *.moved '#'* +sudo rm -rf backports/ profile/ result/ tarball/ *.deb + # update po (cd ../po; make update-po) diff --git a/DistUpgrade/dist-upgrade.py b/DistUpgrade/dist-upgrade.py index 07320fb9..ff2fb933 100755 --- a/DistUpgrade/dist-upgrade.py +++ b/DistUpgrade/dist-upgrade.py @@ -12,6 +12,10 @@ if __name__ == "__main__": parser = OptionParser() parser.add_option("-c", "--cdrom", dest="cdromPath", default=None, help="Use the given path to search for a cdrom with upgradable packages") + parser.add_option("--have-backports", dest="haveBackports", + action="store_true", default=False) + parser.add_option("--with-network", dest="withNetwork",action="store_true") + parser.add_option("--without-network", dest="withNetwork",action="store_false") (options, args) = parser.parse_args() if not os.path.exists("/var/log/dist-upgrade"): @@ -31,7 +35,7 @@ if __name__ == "__main__": logging.error("can't import view '%s'" % requested_view) print "can't find %s" % requested_view sys.exit(1) - app = DistUpgradeControler(view, cdromPath=options.cdromPath) + app = DistUpgradeControler(view, options) app.run() |
