Commit d21a4328 authored by Sebastian Heinlein's avatar Sebastian Heinlein

* Fork a pyton-aptsources source tree from update-manager

parent ee831734
......@@ -2,6 +2,7 @@ Hackers
=======
Michiel Sikkes <michiel@eyesopened.nl>
Michael Vogt <michael.vogt@canonical.com>
Sebastian Heinlein <glatzor@ubuntu.com>
Translators
===========
......
2006-10-28:
- catch errors when load_icon() does not work
2006-10-27:
- reset self.read so that we do not loop endlessly when dpkg
sends unexpected data (lp: #68553)
2006-10-26:
- make sure that xserver-xorg-video-all get installed if
xserver-xorg-driver-all was installed before (lp: #58424)
2006-10-21:
- comment out old cdrom sources
- demotions updated
2006-10-21:
- fix incorrect arguments in fixup logging (lp: #67311)
- more error logging
- fix upgrade problems for people with unofficial compiz
repositories (lp: #58424)
- rosetta i18n updates
- uploaded
2006-10-17:
- ensure bzr, tomboy and xserver-xorg-input-* are properly
upgraded
- don't fail if dpkg sents unexpected status lines (lp: #66013)
2006-10-16:
- remove leftover references to ubuntu-base and
use ubuntu-minimal and ubuntu-standard instead
- updated translations from rosetta
2006-10-13:
- log held-back as well
2006-10-12:
- check if cdrom.lst actually exists before copying it
2006-10-11:
- keep pixbuf loader reference around so that we
have one after the upgrade when the old
/usr/lib/gtk-2.0/loader/2.4.0/ loader is gone.
This fixes the problem of missing stock-icons
after the upgrade. Also revalidate the theme
in each step.
2006-10-10:
- fix time calculation
- fix kubuntu upgrade case
2006-10-06:
- fix source.list rewrite corner case bug (#64159)
2006-10-04:
- improve the space checking/logging
2006-09-29:
- typo fix (thanks to Jane Silber) (lp: #62946)
2006-09-28:
- bugfix in the cdromupgrade script
2006-09-27:
- uploaded a version that only reverts the backport fetching
but no other changes compared to 2006-09-23
2006-09-27:
- embarrassing bug cdromupgrade.sh
2006-09-26:
- comment out the getRequiredBackport code because we will
not use Breaks for the dapper->edgy upgrade yet
(see #54234 for the rationale)
- updated demotions.cfg for dapper->edgy
- special case the packages affected by the Breaks changes
- make sure that no translations get lost during the upgrade
(thanks to mdz for pointing this out)
- bugfixes
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:
- added "RemoveEssentialOk" option and put "sysvinit" into it
2006-09-04:
- set Debug::pkgDepCache::AutoInstall as debug option too
- be more robust against failure from the locales
- remove libgl1-mesa (no longer needed on edgy)
2006-09-03:
- fix in the cdromupgrade script path detection
2006-09-01:
- make the cdromupgrade wrapper work with the compressed version
of the upgrader as put onto the CD
- uploaded
2006-08-30:
- fixes to the cdromupgrade wrapper
2006-08-29:
- always enable the "main" component to make sure it is available
- add download estimated time
- add --cdrom switch to make cdrom based dist-upgrades possible
- better error reporting
- moved the logging into the /var/log/dist-upgrade/ dir
- change the obsoletes calculation when run without network and
consider demotions as obsoletes then (because we can't really
use the "pkg.downloadable" hint without network)
- uploaded
2006-08-18:
- sort the demoted software list
2006-07-31:
- updated to edgy
- uploadedd
2006-05-31:
- fix bug in the free space calculation (#47092)
- updated ReleaseAnnouncement
- updated translations
- fix a missing bindtextdomain
- fix a incorrect ngettext usage
- added quirks handler to fix nvidia-glx issue (#47017)
Thanks to the amazing Kiko for helping improve this!
2006-05-24:
- if the initial "update()" fails, just exit, don't try
to restore the old sources.list (nothing was modified yet)
Ubuntu: #46712
- fix a bug in the sourcesList rewriting (ubuntu: #46245)
- expand the terminal when no libgnome2-perl is installed
because debconf might want to ask questions (ubuntu: #46214)
- disable the breezy cdrom source to make removal of demoted
packages work properly (ubuntu: #46336)
- translations updated from rosetta
- fixed a bug in the demotions calculation (ubuntu: #46245)
- typos fixed and translations unfuzzied (ubuntu: #46792,#46464)
- upload
2006-05-12:
- space checking improved (ubuntu: #43948)
- show software that was demoted from main -> universe
- improve the remaining time reporting
- translation updates
- upload
2006-05-09:
- upload
2006-05-08:
- fix error when asking for media-change (ubuntu: 43442,43728)
2006-05-02:
- upload
2006-04-28:
- add more sanity checking, if no valid mirror is found in the
sources.list ask for "dumb" rewrite
- if nothing valid was found after a dumb rewrite, add official
sources
- don't report install TIMEOUT over and over in the log
- report what package caused a install TIMEOUT
2006-04-27:
- add a additonal sanity check after the rewriting of the sources.list
(check for BaseMetaPkgs still in the cache)
- on abort reopen() the cache to force writing a new
/var/cache/apt/pkgcache.bin
- use a much more compelte mirror list (based on the information
from https://wiki.ubuntu.com/Archive)
2006-04-25:
- make sure that DistUpgradeView.getTerminal().call() actually
waits until the command has finished (dpkg --configure -a)
2006-04-18:
- add logging to the sources.list modification code
- general logging improvements (thanks to Xavier Poinsard)
../UpdateManager/Common/DistInfo.py
\ No newline at end of file
[View]
View=DistUpgradeViewGtk
#View=DistUpgradeViewNonInteractive
#View=DistUpgradeViewText
# Distro contains global information about the upgrade
[Distro]
# the meta-pkgs we support
MetaPkgs=ubuntu-desktop, kubuntu-desktop, edubuntu-desktop, xubuntu-desktop
BaseMetaPkgs=ubuntu-minimal, ubuntu-standard
PostUpgradePurge=xorg-common, libgl1-mesa
Demotions=demoted.cfg
RemoveEssentialOk=sysvinit
RemovalBlacklistFile=removal_blacklist.cfg
# if those packages were installed, make sure to keep them installed
# we use this right now to emulate Breaks
KeepInstalledPkgs=gnumeric, gnumeric-gtk, hpijs
KeepInstalledSection=translations
# information about the individual meta-pkgs
[ubuntu-desktop]
KeyDependencies=gdm, gnome-panel, ubuntu-artwork
# those pkgs will be marked remove right after the distUpgrade in the cache
PostUpgradeRemove=xscreensaver
[kubuntu-desktop]
KeyDependencies=kdm, kicker, kubuntu-artwork-usplash
# those packages are marked as obsolete right after the upgrade
ForcedObsoletes=ivman
[edubuntu-desktop]
KeyDependencies=edubuntu-artwork, tuxpaint
[xubuntu-desktop]
KeyDependencies=xubuntu-artwork-usplash, xubuntu-default-settings, xfce4
[Files]
BackupExt=distUpgrade
[Sources]
From=dapper
To=edgy
ValidOrigin=Ubuntu
ValidMirrors = mirrors.cfg
[Backports]
Packages=apt,dpkg,python2.4-apt
VersionIdent=~dapper
SourcesList=backport-source.list
[Network]
MaxRetries=3
This diff is collapsed.
This diff is collapsed.
from ConfigParser import ConfigParser, NoOptionError
class DistUpgradeConfig(ConfigParser):
def __init__(self, datadir, name="DistUpgrade.cfg"):
ConfigParser.__init__(self)
self.datadir=datadir
self.read([datadir+"/"+name])
def getlist(self, section, option):
try:
tmp = self.get(section, option)
except NoOptionError:
return []
items = [x.strip() for x in tmp.split(",")]
return items
def getListFromFile(self, section, option):
try:
filename = self.get(section, option)
except NoOptionError:
return []
items = [x.strip() for x in open(self.datadir+"/"+filename)]
return filter(lambda s: not s.startswith("#") and not s == "", items)
if __name__ == "__main__":
c = DistUpgradeConfig()
print c.getlist("Distro","MetaPkgs")
print c.getlist("Distro","ForcedPurges")
print c.getListFromFile("Sources","ValidMirrors")
This diff is collapsed.
# DistUpgradeView.py
#
# Copyright (c) 2004,2005 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
from gettext import gettext as _
def FuzzyTimeToStr(sec):
" return the time a bit fuzzy (no seconds if time > 60 secs "
if sec > 60*60*24:
return _("%li days %li hours %li minutes") % (sec/60/60/24, (sec/60/60) % 24, (sec/60) % 60)
if sec > 60*60:
return _("%li hours %li minutes") % (sec/60/60, (sec/60) % 60)
if sec > 60:
return _("%li minutes") % (sec/60)
return _("%li seconds") % sec
def estimatedDownloadTime(requiredDownload):
""" get the estimated download time """
timeModem = requiredDownload/(56*1024/8) # 56 kbit
timeDSL = requiredDownload/(1024*1024/8) # 1Mbit = 1024 kbit
s= _("This download will take about %s with a 1Mbit DSL connection "
"and about %s with a 56k modem" % (FuzzyTimeToStr(timeDSL),FuzzyTimeToStr(timeModem)))
return s
class DumbTerminal(object):
def call(self, cmd):
" expects a command in the subprocess style (as a list) "
import subprocess
subprocess.call(cmd)
(STEP_PREPARE,
STEP_MODIFY_SOURCES,
STEP_FETCH_INSTALL,
STEP_CLEANUP,
STEP_REBOOT) = range(1,6)
class DistUpgradeView(object):
" abstraction for the upgrade view "
def __init__(self):
pass
def getOpCacheProgress(self):
" return a OpProgress() subclass for the given graphic"
return apt.progress.OpProgress()
def getFetchProgress(self):
" return a fetch progress object "
return apt.progress.FetchProgress()
def getInstallProgress(self, cache=None):
" return a install progress object "
return apt.progress.InstallProgress(cache)
def getTerminal(self):
return DumbTerminal()
def updateStatus(self, msg):
""" update the current status of the distUpgrade based
on the current view
"""
pass
def abort():
""" provide a visual feedback that the upgrade was aborted """
pass
def setStep(self, step):
""" we have 5 steps current for a upgrade:
1. Analyzing the system
2. Updating repository information
3. Performing the upgrade
4. Post upgrade stuff
5. Complete
"""
pass
def hideStep(self, step):
" hide a certain step from the GUI "
pass
def confirmChanges(self, summary, changes, downloadSize, actions=None):
""" display the list of changed packages (apt.Package) and
return if the user confirms them
"""
self.toInstall = []
self.toUpgrade = []
self.toRemove = []
self.toDowngrade = []
for pkg in changes:
if pkg.markedInstall: self.toInstall.append(pkg.name)
elif pkg.markedUpgrade: self.toUpgrade.append(pkg.name)
elif pkg.markedDelete: self.toRemove.append(pkg.name)
elif pkg.markedDowngrade: self.toDowngrade.append(pkg.name)
# no re-installs
assert(len(self.toInstall)+len(self.toUpgrade)+len(self.toRemove)+len(self.toDowngrade) == len(changes))
def askYesNoQuestion(self, summary, msg):
" ask a Yes/No question and return True on 'Yes' "
pass
def confirmRestart(self):
" generic ask about the restart, can be overriden "
summary = _("Reboot required")
msg = _("The upgrade is finished and "
"a reboot is required. "
"Do you want to do this "
"now?")
return self.askYesNoQuestion(summary, msg)
def error(self, summary, msg, extended_msg=None):
" display a error "
pass
def information(self, summary, msg, extended_msg=None):
" display a information msg"
pass
This diff is collapsed.
# DistUpgradeView.py
#
# Copyright (c) 2004,2005 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 apt
import logging
import time
from DistUpgradeView import DistUpgradeView
class NonInteractiveInstallProgress(apt.progress.InstallProgress):
def error(self, pkg, errormsg):
logging.error("got a error from dpkg for pkg: '%s': '%s'" % (pkg, errormsg))
def conffile(self, current, new):
logging.debug("got a conffile-prompt from dpkg for file: '%s'" % current)
def updateInterface(self):
apt.progress.InstallProgress.updateInterface(self)
time.sleep(0.001)
class DistUpgradeViewNonInteractive(DistUpgradeView):
" non-interactive version of the upgrade view "
def __init__(self):
pass
def getOpCacheProgress(self):
" return a OpProgress() subclass for the given graphic"
return apt.progress.OpProgress()
def getFetchProgress(self):
" return a fetch progress object "
return apt.progress.FetchProgress()
def getInstallProgress(self):
" return a install progress object "
return NonInteractiveInstallProgress()
def updateStatus(self, msg):
""" update the current status of the distUpgrade based
on the current view
"""
pass
def setStep(self, step):
""" we have 5 steps current for a upgrade:
1. Analyzing the system
2. Updating repository information
3. Performing the upgrade
4. Post upgrade stuff
5. Complete
"""
pass
def confirmChanges(self, summary, changes, downloadSize, actions=None):
DistUpgradeView.confirmChanges(self, summary, changes, downloadSize, actions)
logging.debug("toinstall: '%s'" % self.toInstall)
logging.debug("toupgrade: '%s'" % self.toUpgrade)
logging.debug("toremove: '%s'" % self.toRemove)
return True
def askYesNoQuestion(self, summary, msg):
" ask a Yes/No question and return True on 'Yes' "
return True
def confirmRestart(self):
" generic ask about the restart, can be overriden "
return False
def error(self, summary, msg, extended_msg=None):
" display a error "
logging.error("%s %s (%s)" % (summary, msg, extended_msg))
# DistUpgradeViewText.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 sys
import logging
import time
import subprocess
import apt
import apt_pkg
import os
from apt.progress import InstallProgress
from DistUpgradeView import DistUpgradeView, FuzzyTimeToStr, estimatedDownloadTime
import gettext
from gettext import gettext as _
class TextCdromProgressAdapter(apt.progress.CdromProgress):
""" Report the cdrom add progress """
def update(self, text, step):
""" update is called regularly so that the gui can be redrawn """
if text:
print "%s (%f)" % (text, step/float(self.totalSteps)*100)
def askCdromName(self):
return (False, "")
def changeCdrom(self):
return False
class DistUpgradeViewText(DistUpgradeView):
" text frontend of the distUpgrade tool "
def __init__(self, datadir=None):
if not datadir:
localedir=os.path.join(os.getcwd(),"mo")
else:
localedir="/usr/share/locale/update-manager"
try:
gettext.bindtextdomain("update-manager", localedir)
gettext.textdomain("update-manager")
except Exception, e:
logging.warning("Error setting locales (%s)" % e)
self.last_step = 0 # keep a record of the latest step
self._opCacheProgress = apt.progress.OpTextProgress()
self._fetchProgress = apt.progress.TextFetchProgress()
self._cdromProgress = TextCdromProgressAdapter()
self._installProgress = apt.progress.InstallProgress()
sys.excepthook = self._handleException
def _handleException(self, type, value, tb):
import traceback
lines = traceback.format_exception(type, value, tb)
logging.error("not handled expection:\n%s" % "\n".join(lines))
self.error(_("A fatal error occured"),
_("Please report this as a bug and include the "
"files /var/log/dist-upgrade/main.log and "
"/var/log/dist-upgrade/apt.log "
"in your report. The upgrade aborts now.\n"
"Your original sources.list was saved in "
"/etc/apt/sources.list.distUpgrade."),
"\n".join(lines))
sys.exit(1)
def getFetchProgress(self):
return self._fetchProgress
def getInstallProgress(self, cache):
self._installProgress._cache = cache
return self._installProgress
def getOpCacheProgress(self):
return self._opCacheProgress
def getCdromProgress(self):
return self._cdromProgress
def updateStatus(self, msg):
print msg
def abort(self):
print _("Aborting")
def setStep(self, step):
self.last_step = step
def information(self, summary, msg, extended_msg=None):
print summary
print msg
if extended_msg:
print extended_msg
def error(self, summary, msg, extended_msg=None):
print summary
print msg
if extended_msg:
print extended_msg
return False
def confirmChanges(self, summary, changes, downloadSize, actions=None):
DistUpgradeView.confirmChanges(self, summary, changes, downloadSize, actions)
pkgs_remove = len(self.toRemove)
pkgs_inst = len(self.toInstall)
pkgs_upgrade = len(self.toUpgrade)
msg = ""
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("%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("%d new package is going to be "
"installed.",
"%d new packages are going to be "
"installed.",pkgs_inst) % pkgs_inst
msg += " "
if pkgs_upgrade > 0:
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:
msg += _("\n\nYou have to download a total of %s. ") %\
apt_pkg.SizeToStr(downloadSize)
msg += estimatedDownloadTime(downloadSize)
msg += "."
if (pkgs_upgrade + pkgs_inst + pkgs_remove) > 100:
msg += "\n\n%s" % _("Fetching and installing the upgrade can take several hours and "\
"cannot be canceled at any time later.")
# Show an error if no actions are planned
if (pkgs_upgrade + pkgs_inst + pkgs_remove) < 1:
# FIXME: this should go into DistUpgradeController
summary = _("Your system is up-to-date")
msg = _("There are no upgrades available for your system. "
"The upgrade will now be canceled.")
self.error(summary, msg)
return False
return self.askYesNoQuestion(summary, msg)
def askYesNoQuestion(self, summary, msg):
print summary
print msg
print _("Continue [Yn] "),
res = sys.stdin.readline()
if res.strip().lower().startswith("y"):
return True
return False
def confirmRestart(self):
return self.askYesNoQuestion(_("Restart required"),
_("To fully ugprade, please restart"))
if __name__ == "__main__":
view = DistUpgradeViewText()
view.confirmChanges("xx",[], 100)
sys.exit(0)
fp = apt.progress.TextFetchProgress()
ip = apt.progress.InstallProgress()
cache = apt.Cache()
for pkg in sys.argv[1:]:
cache[pkg].markInstall()
cache.commit(fp,ip)
#sys.exit(0)
view.getTerminal().call(["dpkg","--configure","-a"])
#view.getTerminal().call(["ls","-R","/usr"])
view.error("short","long",
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
"asfds afsdj af asdf asdf asf dsa fadsf asdf as fasf sextended\n"
)
view.confirmChanges("xx",[], 100)
print view.askYesNoQuestion("hello", "Icecream?")