Hello community, here is the log from the commit of package yum checked in at Mon Apr 9 11:45:48 CEST 2007. -------- --- yum/yum.changes 2007-03-27 15:57:35.000000000 +0200 +++ /mounts/work_src_done/STABLE/yum/yum.changes 2007-04-06 11:44:30.000000000 +0200 @@ -1,0 +2,9 @@ +Fri Apr 6 11:44:03 CEST 2007 - cthiel@suse.de + +- update to version 3.1.6 + * 3.1.6 brings with it another round of fixes and optimizations to the + depsolver. It also ports forward some changes from 3.0.X that were + needed. This release should provide depsolver speed experience more + inline with what we want. + +------------------------------------------------------------------- Old: ---- yum-3.1.5.tar.bz2 New: ---- yum-3.1.6.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yum.spec ++++++ --- /var/tmp/diff_new_pack.q12034/_old 2007-04-09 11:45:34.000000000 +0200 +++ /var/tmp/diff_new_pack.q12034/_new 2007-04-09 11:45:34.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package yum (Version 3.1.5) +# spec file for package yum (Version 3.1.6) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -12,7 +12,7 @@ Name: yum BuildRequires: python-devel -Version: 3.1.5 +Version: 3.1.6 Release: 1 Summary: RPM installer/updater Group: System/Packages @@ -95,6 +95,12 @@ %{py_sitedir}/* %changelog +* Fri Apr 06 2007 - cthiel@suse.de +- update to version 3.1.6 + * 3.1.6 brings with it another round of fixes and optimizations to the + depsolver. It also ports forward some changes from 3.0.X that were + needed. This release should provide depsolver speed experience more + inline with what we want. * Tue Mar 27 2007 - cthiel@suse.de - update to version 3.1.5 * This is a substantially less sucky yum 3.1.X release for those folks ++++++ yum-3.1.5.tar.bz2 -> yum-3.1.6.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/ChangeLog new/yum-3.1.6/ChangeLog --- old/yum-3.1.5/ChangeLog 2007-03-22 04:12:45.000000000 +0100 +++ new/yum-3.1.6/ChangeLog 2007-04-04 06:05:50.000000000 +0200 @@ -1,3 +1,172 @@ +2007-04-04 00:03 skvidal + + * yum.spec, yum/__init__.py: mark as 3.1.6 + +2007-04-03 17:24 katzj + + * yum/depsolve.py: I made anaconda's tscheck callback less crappy. + +2007-04-03 16:07 skvidal + + * cli.py: + merge up perl/perl-devel case and a bunch of other similar ones. + fixes rh bug: 231549 thanks to Robin Norwood for the easy + replicator. + +2007-04-03 15:53 skvidal + + * yum/__init__.py: make 'search' case insensitive + +2007-04-03 13:57 skvidal + + * yum/depsolve.py: + don't constantly reset the tsInfo if there's nothing in it. + +2007-04-03 11:18 jbowes + + * yum/sqlitecache.py: Create pkgKey index on PRCO data, as + suggested by Florian Festi + +2007-04-03 01:16 skvidal + + * yum/__init__.py: don't refer to self.pkgSack until we're positive + it's setup, otherwise we get good and recursive in the wrong place + - should make --enablerepo/--disablrepo work properly when combined + with excludes + +2007-04-02 12:06 skvidal + + * yum/rpmsack.py: + fix breakage in lookup of rpmsack - idx was being used nested in a + for loop and overwriting itself. fixes issue with installonlyn and + all lookups by name + +2007-04-01 21:30 jbowes + + * yum/depsolve.py: Remove _checkUpdate + + If a transaction member was marked as 'update', we'd run + _checkInstall on it, then run _checkRemove on all of the packages + that it was updating. After this, we'd then run _checkRemove on all + transaction members marked as 'updated'. So we were running + _checkRemove on every 'updated' package twice. Get rid of this. + +2007-04-01 14:07 jbowes + + * yum/depsolve.py: Only call pkgAdded if the transaction member has + a state + +2007-04-01 13:48 jbowes + + * yum/rpmsack.py: Rpmsack _search optimization + + If we have the full pkgtup, then just look it up in the header + dict. Takes 'yum remove glibc' from 1m2s to 0m41s on my machine. + +2007-04-01 10:56 jbowes + + * yum/depsolve.py: Simplify provideToPkg code + +2007-04-01 10:04 jbowes + + * yum/depsolve.py: fix recent tscheck breakage + +2007-03-31 20:37 katzj + + * yum/depsolve.py: From Chris Lumens (clumens AT redhat DOT com) + + Looking at why the anaconda dependency progress bar never moves, I + found two small things. First, we're never calling pkgAdded in + _resolveDeps so the progress bar is never getting updated. Second, + we're never initializing the progress bar with the number of things + to check so we don't know how big to make the increments. + +2007-03-31 20:35 katzj + + * yum/depsolve.py: split up checking on package erasure into things + from the rpmdb and things in the tsinfo. given the lack of + searchability with the tsinfo, we're better off just going through + it once with the set of provides rather than looping over it for + each provide. + +2007-03-31 20:11 jbowes + + * yum/transactioninfo.py: Fix a misnamed variable in getMembers, + and rearrange the code a bit + +2007-03-30 15:47 katzj + + * yum/depsolve.py: switch back to logic we were previously using on + removal as it handled some of the corner cases better. but add + checking to ensure that nothing in the tsinfo requires the provide. + this should fix the problem where quux requires bar, bar is + currently installed remove bar, install quux in same transaction + +2007-03-30 13:03 katzj + + * yum/sqlitesack.py: and re-fix handling of the filesystem package. + the split of the filenames gets confused with / being in + filesystem which is what the uniq got added for originally + +2007-03-30 11:32 katzj + + * yum/rpmsack.py: some speedups * don't use yield with + _get_pkglist; we've already generated the list and just returning + it is faster * remove inner match() function of _search() so that + we don't have the overhead of a bazillion function calls. yes, + this is noticable. + +2007-03-29 17:57 katzj + + * yum/sqlitesack.py: fix filelist/dirlist population to be correct! + + we've been doing sort/uniq on the filenames which makes + (illustrative example..) /lib + dff|dbus-1.0/lidbus-1.so.3.2.0/libdbus-1.so.3 end up giving + /lib/libdbus-1.so.3 (dir) /lib/libdbus-1.so.3.2.0 (file) + /lib/dbus-1.0 (file) + + This is clearly *not* what it's supposed to be :) + +2007-03-28 12:00 katzj + + * yum-updatesd.py: make it so that we can pass back initialization + errors to callers over the bus. Patch from Ray Strode (halfline AT + gmail DOT com) + +2007-03-28 11:59 katzj + + * yum/plugins.py: allow YumPluginExit to have a translation domain + set so that we can get a localized error message + +2007-03-28 04:48 skvidal + + * yum/depsolve.py: + make it a small amount faster. searching the transaction set + members is slow - it needs to be faster + +2007-03-28 04:09 skvidal + + * yum/depsolve.py: + - catch the case where we remove something needed in the + transaction - partial limited delta case + +2007-03-26 00:37 skvidal + + * yum/transactioninfo.py: + allow getMembers() to return a package sack, optionally. + +2007-03-23 03:41 skvidal + + * yum/depsolve.py: + just a stub - need to fill it out tomorrow to act as a simplifier + for _checkRemove() + +2007-03-21 23:11 skvidal + + * ChangeLog: + changelog merge + 2007-03-21 23:09 skvidal * yum.spec, yum/__init__.py: diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/cli.py new/yum-3.1.6/cli.py --- old/yum-3.1.5/cli.py 2007-02-23 08:29:08.000000000 +0100 +++ new/yum-3.1.6/cli.py 2007-04-03 22:08:40.000000000 +0200 @@ -436,18 +436,33 @@ arg = unmatched[0] #only one in there self.verbose_logger.debug('Checking for virtual provide or file-provide for %s', arg) + # let's make sure we don't have this dep installed already try: - mypkg = self.returnPackageByDep(arg) + my_inst_pkgs = self.returnInstalledPackagesByDep(arg) + except yum.Errors.YumBaseError, e: + my_inst_pkgs = [] + + if my_inst_pkgs: + self.verbose_logger.log(yum.logginglevels.DEBUG_3, + 'Requested dep: %s is provided by installed package', str(arg)) + + continue # we don't need to look, we have it + try: + mypkgs = self.returnPackagesByDep(arg) except yum.Errors.YumBaseError, e: self.logger.critical(_('No Match for argument: %s') % arg) else: - arg = '%s:%s-%s-%s.%s' % (mypkg.epoch, mypkg.name, - mypkg.version, mypkg.release, - mypkg.arch) - emtch, mtch, unmtch = self.pkgSack.matchPackageNames([arg]) - exactmatch.extend(emtch) - matched.extend(mtch) - + for mypkg in mypkgs: + if self._installable(mypkg, True): + self.verbose_logger.log(yum.logginglevels.DEBUG_3, + 'Solving package %s is installable, not going through the rest', mypkg) + exactmatch.append(mypkg) + break + else: + self.verbose_logger.log(yum.logginglevels.DEBUG_3, + 'Solving package %s is not installable, skipping', mypkg) + + installable = yum.misc.unique(exactmatch + matched) exactarchlist = self.conf.exactarchlist @@ -993,8 +1008,58 @@ def shellUsage(self): ''' Print out the shell usage ''' print self.optparser.print_usage() - - + + def _installable(self, pkg, ematch=False): + + """check if the package is reasonably installable, true/false""" + + exactarchlist = self.conf.exactarchlist + # we look through each returned possibility and rule out the + # ones that we obviously can't use + + if self.rpmdb.installed(po=pkg): + self.verbose_logger.log(yum.logginglevels.DEBUG_3, + 'Package %s is already installed, skipping', pkg) + return False + + # everything installed that matches the name + installedByKey = self.rpmdb.searchNevra(name=pkg.name) + comparable = [] + for instpo in installedByKey: + if rpmUtils.arch.isMultiLibArch(instpo.arch) == rpmUtils.arch.isMultiLibArch(pkg.arch): + comparable.append(instpo) + else: + self.verbose_logger.log(yum.logginglevels.DEBUG_3, + 'Discarding non-comparable pkg %s.%s', instpo.name, instpo.arch) + continue + + # go through each package + if len(comparable) > 0: + for instpo in comparable: + if pkg.EVR > instpo.EVR: # we're newer - this is an update, pass to them + if instpo.name in exactarchlist: + if pkg.arch == instpo.arch: + return True + else: + return True + + elif pkg.EVR == instpo.EVR: # same, ignore + return False + + elif pkg.EVR < instpo.EVR: # lesser, check if the pkgtup is an exactmatch + # if so then add it to be installed + # if it can be multiply installed + # this is where we could handle setting + # it to be an 'oldpackage' revert. + + if ematch and self.allowedMultipleInstalls(pkg): + return True + + else: # we've not got any installed that match n or n+a + self.verbose_logger.log(yum.logginglevels.DEBUG_1, 'No other %s installed, adding to list for potential install', pkg.name) + return True + + return False class YumOptionParser(OptionParser): '''Subclass that makes some minor tweaks to make OptionParser do things the diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/output.pyort new/yum-3.1.6/output.pyort --- old/yum-3.1.5/output.pyort 2007-03-21 20:33:57.000000000 +0100 +++ new/yum-3.1.6/output.pyort 1970-01-01 01:00:00.000000000 +0100 @@ -1,468 +0,0 @@ -#!/usr/bin/python -t - -"""This handles actual output from the cli""" - -# 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 Library 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. -# Copyright 2005 Duke University - -import sys -import time -import logging -from i18n import _ - -from urlgrabber.progress import TextMeter -from urlgrabber.grabber import URLGrabError -from yum.misc import sortPkgObj, prco_tuple_to_string - -from yum import logginglevels - -class YumOutput: - - def __init__(self): - self.logger = logging.getLogger("yum.cli") - self.verbose_logger = logging.getLogger("yum.verbose.cli") - - def printtime(self): - months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - now = time.localtime(time.time()) - ret = months[int(time.strftime('%m', now)) - 1] + \ - time.strftime(' %d %T ', now) - return ret - - def failureReport(self, errobj): - """failure output for failovers from urlgrabber""" - - self.logger.error('%s: %s', errobj.url, str(errobj.exception)) - self.logger.error('Trying other mirror.') - raise errobj.exception - - - def simpleProgressBar(self, current, total, name=None): - progressbar(current, total, name) - - def simpleList(self, pkg): - ver = pkg.printVer() - na = '%s.%s' % (pkg.name, pkg.arch) - - print "%-40.40s %-22.22s %-16.16s" % (na, ver, pkg.repoid) - - - def infoOutput(self, pkg): - print _("Name : %s") % pkg.name - print _("Arch : %s") % pkg.arch - if pkg.epoch != "0": - print _("Epoch : %s") % pkg.epoch - print _("Version: %s") % pkg.version - print _("Release: %s") % pkg.release - print _("Size : %s") % self.format_number(float(pkg.size)) - print _("Repo : %s") % pkg.repoid - print _("Summary: %s") % pkg.summary - print _("Description:\n%s") % pkg.description - print "" - - def updatesObsoletesList(self, uotup, changetype): - """takes an updates or obsoletes tuple of pkgobjects and - returns a simple printed string of the output and a string - explaining the relationship between the tuple members""" - (changePkg, instPkg) = uotup - c_compact = changePkg.compactPrint() - i_compact = '%s.%s' % (instPkg.name, instPkg.arch) - c_repo = changePkg.repoid - # FIXME - other ideas for how to print this out? - print '%-35.35s [%.12s] %.10s %-20.20s' % (c_compact, c_repo, changetype, i_compact) - - def listPkgs(self, lst, description, outputType): - """outputs based on whatever outputType is. Current options: - 'list' - simple pkg list - 'info' - similar to rpm -qi output""" - - if outputType in ['list', 'info']: - thingslisted = 0 - if len(lst) > 0: - thingslisted = 1 - print '%s' % description - lst.sort(sortPkgObj) - for pkg in lst: - if outputType == 'list': - self.simpleList(pkg) - elif outputType == 'info': - self.infoOutput(pkg) - else: - pass - - if thingslisted == 0: - return 1, ['No Packages to list'] - - - - def userconfirm(self): - """gets a yes or no from the user, defaults to No""" - - while True: - choice = raw_input('Is this ok [y/N]: ') - choice = choice.lower() - if len(choice) == 0 or choice[0] in ['y', 'n']: - break - - if len(choice) == 0 or choice[0] != 'y': - return False - else: - return True - - - def displayPkgsInGroups(self, group): - print '\nGroup: %s' % group.name - if group.description != "": - print ' Description: %s' % group.description - if len(group.mandatory_packages.keys()) > 0: - print ' Mandatory Packages:' - for item in group.mandatory_packages.keys(): - print ' %s' % item - - if len(group.default_packages.keys()) > 0: - print ' Default Packages:' - for item in group.default_packages.keys(): - print ' %s' % item - - if len(group.optional_packages.keys()) > 0: - print ' Optional Packages:' - for item in group.optional_packages.keys(): - print ' %s' % item - - if len(group.conditional_packages.keys()) > 0: - print ' Conditional Packages:' - for item, cond in group.conditional_packages.iteritems(): - print ' %s' % (item,) - - def depListOutput(self, results): - """take a list of findDeps results and 'pretty print' the output""" - - for pkg in results.keys(): - print "package: %s" % pkg.compactPrint() - if len(results[pkg].keys()) == 0: - print " No dependencies for this package" - continue - - for req in results[pkg].keys(): - reqlist = results[pkg][req] - print " dependency: %s" % prco_tuple_to_string(req) - if not reqlist: - print " Unsatisfied dependency" - continue - - for po in reqlist: - print " provider: %s" % po.compactPrint() - - - - def format_number(self, number, SI=0, space=' '): - """Turn numbers into human-readable metric-like numbers""" - symbols = ['', # (none) - 'k', # kilo - 'M', # mega - 'G', # giga - 'T', # tera - 'P', # peta - 'E', # exa - 'Z', # zetta - 'Y'] # yotta - - if SI: step = 1000.0 - else: step = 1024.0 - - thresh = 999 - depth = 0 - - # we want numbers between - while number > thresh: - depth = depth + 1 - number = number / step - - # just in case someone needs more than 1000 yottabytes! - diff = depth - len(symbols) + 1 - if diff > 0: - depth = depth - diff - number = number * thresh**depth - - if type(number) == type(1) or type(number) == type(1L): - format = '%i%s%s' - elif number < 9.95: - # must use 9.95 for proper sizing. For example, 9.99 will be - # rounded to 10.0 with the .1f format string (which is too long) - format = '%.1f%s%s' - else: - format = '%.0f%s%s' - - return(format % (number, space, symbols[depth])) - - def matchcallback(self, po, values): - self.verbose_logger.log(logginglevels.INFO_2, '\n\n') - self.simpleList(po) - self.verbose_logger.log(logginglevels.INFO_2, 'Matched from:') - for item in values: - self.verbose_logger.log(logginglevels.INFO_2, '%s', item) - - def reportDownloadSize(self, packages): - """Report the total download size for a set of packages""" - totsize = 0 - error = False - for pkg in packages: - # Just to be on the safe side, if for some reason getting - # the package size fails, log the error and don't report download - # size - try: - size = int(pkg.size) - totsize += size - except: - error = True - self.logger.error('There was an error calculating total download size') - break - - if (not error): - self.verbose_logger.log(logginglevels.INFO_1, "Total download size: %s", - self.format_number(totsize)) - - def listTransaction(self): - """returns a string rep of the transaction in an easy-to-read way.""" - - self.tsInfo.makelists() - if len(self.tsInfo) > 0: - out = """ -============================================================================= - %-22s %-9s %-15s %-16s %-5s -============================================================================= -""" % ('Package', 'Arch', 'Version', 'Repository', 'Size') - else: - out = "" - - for (action, pkglist) in [('Installing', self.tsInfo.installed), - ('Updating', self.tsInfo.updated), - ('Removing', self.tsInfo.removed), - ('Installing for dependencies', self.tsInfo.depinstalled), - ('Updating for dependencies', self.tsInfo.depupdated), - ('Removing for dependencies', self.tsInfo.depremoved)]: - if pkglist: - totalmsg = "%s:\n" % action - for txmbr in pkglist: - (n,a,e,v,r) = txmbr.pkgtup - evr = txmbr.po.printVer() - repoid = txmbr.repoid - pkgsize = float(txmbr.po.size) - size = self.format_number(pkgsize) - msg = " %-22s %-9s %-15s %-16s %5s\n" % (n, a, - evr, repoid, size) - for obspo in txmbr.obsoletes: - appended = ' replacing %s.%s %s\n\n' % (obspo.name, - obspo.arch, obspo.printVer()) - msg = msg+appended - totalmsg = totalmsg + msg - - if pkglist: - out = out + totalmsg - - summary = """ -Transaction Summary -============================================================================= -Install %5.5s Package(s) -Update %5.5s Package(s) -Remove %5.5s Package(s) -""" % (len(self.tsInfo.installed + self.tsInfo.depinstalled), - len(self.tsInfo.updated + self.tsInfo.depupdated), - len(self.tsInfo.removed + self.tsInfo.depremoved)) - out = out + summary - - return out - - def postTransactionOutput(self): - out = '' - - self.tsInfo.makelists() - - for (action, pkglist) in [('Removed', self.tsInfo.removed), - ('Dependency Removed', self.tsInfo.depremoved), - ('Installed', self.tsInfo.installed), - ('Dependency Installed', self.tsInfo.depinstalled), - ('Updated', self.tsInfo.updated), - ('Dependency Updated', self.tsInfo.depupdated), - ('Replaced', self.tsInfo.obsoleted)]: - - if len(pkglist) > 0: - out += '\n%s:' % action - for txmbr in pkglist: - (n,a,e,v,r) = txmbr.pkgtup - msg = " %s.%s %s:%s-%s" % (n,a,e,v,r) - out += msg - - return out - - def setupProgessCallbacks(self): - """sets up the progress callbacks and various - output bars based on debug level""" - - # if we're below 2 on the debug level we don't need to be outputting - # progress bars - this is hacky - I'm open to other options - # One of these is a download - if self.conf.debuglevel < 2 or not sys.stdout.isatty(): - self.repos.setProgressBar(None) - self.repos.callback = None - else: - self.repos.setProgressBar(TextMeter(fo=sys.stdout)) - self.repos.callback = CacheProgressCallback() - - # setup our failure report for failover - freport = (self.failureReport,(),{}) - self.repos.setFailureCallback(freport) - - # setup callback for CTRL-C's - self.repos.setInterruptCallback(self.interrupt_callback) - - # setup our depsolve progress callback - dscb = DepSolveProgressCallBack() - self.dsCallback = dscb - - def interrupt_callback(self, cbobj): - '''Handle CTRL-C's during downloads - - If a CTRL-C occurs a URLGrabError will be raised to push the download - onto the next mirror. - - If two CTRL-C's occur in quick succession then yum will exit. - - @param cbobj: urlgrabber callback obj - ''' - now = time.time() - if hasattr(self, '_last_interrupt') and now - self._last_interrupt < 0.2: - # Two quick CTRL-C's, quit - raise KeyboardInterrupt - - # Go to next mirror - self._last_interrupt = now - raise URLGrabError(15, 'user interrupt') - -class DepSolveProgressCallBack: - """provides text output callback functions for Dependency Solver callback""" - - def __init__(self): - """requires yum-cli log and errorlog functions as arguments""" - self.verbose_logger = logging.getLogger("yum.verbose.cli") - self.loops = 0 - - def pkgAdded(self, pkgtup, mode): - modedict = { 'i': 'installed', - 'u': 'updated', - 'o': 'obsoleted', - 'e': 'erased'} - (n, a, e, v, r) = pkgtup - modeterm = modedict[mode] - self.verbose_logger.log(logginglevels.INFO_2, - '---> Package %s.%s %s:%s-%s set to be %s', n, a, e, v, r, - modeterm) - - def start(self): - self.loops += 1 - - def tscheck(self): - self.verbose_logger.log(logginglevels.INFO_2, '--> Running transaction check') - - def restartLoop(self): - self.loops += 1 - self.verbose_logger.log(logginglevels.INFO_2, - '--> Restarting Dependency Resolution with new changes.') - self.verbose_logger.debug('---> Loop Number: %d', self.loops) - - def end(self): - self.verbose_logger.log(logginglevels.INFO_2, - '--> Finished Dependency Resolution') - - - def procReq(self, name, formatted_req): - self.verbose_logger.log(logginglevels.INFO_2, - '--> Processing Dependency: %s for package: %s', formatted_req, - name) - - - def unresolved(self, msg): - self.verbose_logger.log(logginglevels.INFO_2, '--> Unresolved Dependency: %s', - msg) - - - def procConflict(self, name, confname): - self.verbose_logger.log(logginglevels.INFO_2, - '--> Processing Conflict: %s conflicts %s', name, confname) - - def transactionPopulation(self): - self.verbose_logger.log(logginglevels.INFO_2, '--> Populating transaction set ' - 'with selected packages. Please wait.') - - def downloadHeader(self, name): - self.verbose_logger.log(logginglevels.INFO_2, '---> Downloading header for %s ' - 'to pack into transaction set.', name) - - -class CacheProgressCallback: - - ''' - The class handles text output callbacks during metadata cache updates. - ''' - - def __init__(self): - self.logger = logging.getLogger("yum.cli") - self.verbose_logger = logging.getLogger("yum.verbose.cli") - self.file_logger = logging.getLogger("yum.filelogging.cli") - - def log(self, level, message): - self.verbose_logger.log(level, message) - - def errorlog(self, level, message): - self.logger.log(level, message) - - def filelog(self, level, message): - self.file_logger.log(level, message) - - def progressbar(self, current, total, name=None): - progressbar(current, total, name) - - -def progressbar(current, total, name=None): - """simple progress bar 50 # marks""" - - mark = '#' - if not sys.stdout.isatty(): - return - - if current == 0: - percent = 0 - else: - if total != 0: - percent = current*100/total - else: - percent = 0 - - numblocks = int(percent/2) - hashbar = mark * numblocks - if name is None: - output = '\r%-50s %d/%d' % (hashbar, current, total) - else: - output = '\r%-10.10s: %-50s %d/%d' % (name, hashbar, current, total) - - if current <= total: - sys.stdout.write(output) - - if current == total: - sys.stdout.write('\n') - - sys.stdout.flush() - diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/depsolve.py new/yum-3.1.6/yum/depsolve.py --- old/yum-3.1.5/yum/depsolve.py 2007-03-21 19:42:48.000000000 +0100 +++ new/yum-3.1.6/yum/depsolve.py 2007-04-04 01:03:50.000000000 +0200 @@ -43,7 +43,6 @@ self.dsCallback = None self.logger = logging.getLogger("yum.Depsolve") self.verbose_logger = logging.getLogger("yum.verbose.Depsolve") - self.tsInfoDelta = [] def doTsSetup(self): warnings.warn('doTsSetup() will go away in a future version of Yum.\n', @@ -65,7 +64,7 @@ self.initActionTs() def _getTsInfo(self): - if not self._tsInfo: + if self._tsInfo is None: self._tsInfo = self._transactionDataFactory() return self._tsInfo @@ -510,7 +509,6 @@ requiringPo, needname) txmbr = self.tsInfo.addErase(requiringPo) txmbr.setAsDep(po=needpo) - self.tsInfoDelta.append(txmbr) checkdeps = 1 if needmode in ['i', 'u']: @@ -532,7 +530,6 @@ txmbr = self.tsInfo.addObsoleting(po, requiringPo) self.tsInfo.addObsoleted(requiringPo, po) txmbr.setAsDep(po=needpo) - self.tsInfoDelta.append(txmbr) self.verbose_logger.log(logginglevels.DEBUG_2, 'TSINFO: Obsoleting %s with %s to resolve dep.', requiringPo, po) checkdeps = 1 @@ -564,7 +561,6 @@ if po.pkgtup == new: txmbr = self.tsInfo.addUpdate(po, requiringPo) txmbr.setAsDep(po=needpo) - self.tsInfoDelta.append(txmbr) self.verbose_logger.log(logginglevels.DEBUG_2, 'TSINFO: Updating %s to resolve dep.', po) checkdeps = 1 @@ -706,13 +702,11 @@ # FIXME: we should probably handle updating multiple packages... txmbr = self.tsInfo.addUpdate(best, inst[0]) txmbr.setAsDep() - self.tsInfoDelta.append(txmbr) else: self.verbose_logger.debug('TSINFO: Marking %s as install for %s', best, name) txmbr = self.tsInfo.addInstall(best) txmbr.setAsDep() - self.tsInfoDelta.append(txmbr) checkdeps = 1 @@ -773,7 +767,6 @@ 'TSINFO: Updating %s to resolve conflict.', po) txmbr = self.tsInfo.addUpdate(po, confpkg) txmbr.setAsDep() - self.tsInfoDelta.append(txmbr) CheckDeps = 1 else: @@ -814,16 +807,11 @@ for pkgtup in self.rpmdb.whatProvides(r, f, v): # check the rpmdb first for something providing it that's not # set to be removed - txmbrs = self.tsInfo.getMembers(pkgtup) + txmbrs = self.tsInfo.getMembers(pkgtup, TS_REMOVE_STATES) if not txmbrs: po = self.getInstalledPackageObject(pkgtup) self.deps[req] = po return po - for txmbr in txmbrs: - if txmbr.output_state not in TS_REMOVE_STATES: - po = self.getInstalledPackageObject(pkgtup) - self.deps[req] = po - return po for po in self.whatProvides(r, f, v): # if we already have something to be installed which @@ -869,7 +857,7 @@ p = pstats.Stats('yumprof') p.strip_dirs() - p.sort_stats('time', 'calls') + p.sort_stats('time') p.print_stats(20) return rc @@ -887,16 +875,21 @@ ret = [] for txmbr in self.tsInfo.getMembers(): + + if self.dcobj.already_seen.has_key(txmbr): + continue + + if self.dsCallback and txmbr.ts_state: + self.dsCallback.pkgAdded(txmbr.pkgtup, txmbr.ts_state) + self.verbose_logger.log(logginglevels.INFO_2, "Checking deps for %s" %(txmbr,)) - if txmbr.output_state in (TS_INSTALL, TS_TRUEINSTALL, TS_OBSOLETING): + if txmbr.output_state in TS_INSTALL_STATES: ret.extend(self._checkInstall(txmbr)) - elif txmbr.output_state in (TS_UPDATE,): - ret.extend(self._checkUpdate(txmbr)) elif txmbr.output_state in TS_REMOVE_STATES: ret.extend(self._checkRemove(txmbr)) - - self.tsInfoDelta = [] + self.dcobj.already_seen[txmbr] = 1 + return ret def _resolveDeps(self): @@ -909,7 +902,6 @@ errors = [] if self.dsCallback: self.dsCallback.start() - self.tsInfoDelta = self.tsInfo.getMembers() while CheckDeps: self.cheaterlookup = {} # short cache for some information we'd resolve # (needname, needversion) = pkgtup @@ -1072,14 +1064,6 @@ member.setAsDep(txmbr.po) return ret - def _checkUpdate(self, txmbr): - ret = self._checkInstall(txmbr) - for oldpo in txmbr.updates: - for this_txmbr in self.tsInfo.getMembers(oldpo.pkgtup): - ret.extend(self._checkRemove(this_txmbr)) - # this is probably incomplete, but it does create curious results - return ret - def _checkRemove(self, txmbr): po = txmbr.po provs = po.returnPrco('provides') @@ -1099,8 +1083,13 @@ newpoprovs[(f, None, (None, None, None))] = 1 ret = [] - removing = [] + self._removing = [] + goneprovs = {} + gonefiles = {} + removes = {} + # iterate over the provides of the package being removed + # and see what's actually going away for prov in provs: if prov[0].startswith('rpmlib('): # ignore rpmlib() provides continue @@ -1108,99 +1097,40 @@ continue if newpoprovs.has_key(prov): continue + if not prov[0].startswith("/"): + goneprovs[prov[0]] = prov + else: + gonefiles[prov[0]] = prov + # now see what from the rpmdb really requires these + for (provname, prov) in goneprovs.items() + gonefiles.items(): + instrequirers = [] + for pkgtup in self.rpmdb.whatRequires(provname, None, None): + instpo = self.getInstalledPackageObject(pkgtup) + instrequirers.append(instpo) + self.verbose_logger.log(logginglevels.DEBUG_4, "looking to see what requires %s of %s", prov, po) + removes[prov] = self._requiredByPkg(prov, instrequirers) + # now, let's see if anything that we're installing requires anything + # that this provides + for txmbr in self.tsInfo.getMembers(None, TS_INSTALL_STATES): + for r in txmbr.po.requires_names: + prov = None + if r in goneprovs.keys(): + prov = goneprovs[r] + elif r.startswith("/") and r in gonefiles: + prov = gonefiles[r] + + if prov and not removes.has_key(prov): + removes[prov] = self._requiredByPkg(prov, [txmbr.po]) + elif prov: + removes[prov].extend(self._requiredByPkg(prov, [txmbr.po])) + + # now we know what needs to be removed and the provide causing it + # to be removed. let's stick them in the ret list + for (prov, removeList) in removes.items(): (r, f, v) = prov - - removeList = [] - # see what requires this provide name - for pkgtup in self.rpmdb.whatRequires(r, None, None): - self.verbose_logger.log(logginglevels.DEBUG_2, "looking at %s as a requirement of %s", r, pkgtup) - isok = False - # ignore stuff already being removed - if self.tsInfo.getMembers(pkgtup, TS_REMOVE_STATES): - continue - if pkgtup in removing: - continue - instpo = self.getInstalledPackageObject(pkgtup) - - # check to ensure that we really fulfill instpo's need for r - if not instpo.checkPrco('requires', (r,f,v)): - continue - - # now see if anything else is providing what we need - for provtup in self.rpmdb.whatProvides(r, None, None): - # check if this provider is being removed - if provtup in removing: - continue - if self.tsInfo.getMembers(provtup, TS_REMOVE_STATES): - continue - - provpo = self.getInstalledPackageObject(provtup) - if provpo in removeList: - continue - # check if provpo actually satisfies instpo's need for r - # if so, we're golden - ok = True - for (rr, rf, rv) in instpo.requires: - if rr != r: - continue - if not provpo.checkPrco('provides', (rr, rf, rv)): - ok = False - if ok: - isok = True - break - - if isok: - continue - - # for files, we need to do a searchProvides() to take - # advantage of the shortcut of the files globbed into - # primary.xml.gz. this is a bit of a hack, but saves us - # from having to download the filelists for a lot of cases - if r.startswith("/"): - for po in self.pkgSack.searchProvides(r): - if self.tsInfo.getMembers(po.pkgtup, TS_INSTALL_STATES): - isok = True - break - for po in self.rpmdb.searchFiles(r): - if not self.tsInfo.getMembers(po.pkgtup, TS_REMOVE_STATES): - isok = True - break - if isok: - continue - - # now do the same set of checks with packages that are - # set to be installed. - for txmbr in self.tsInfo.getMembers(None, TS_INSTALL_STATES): - if txmbr.po.checkPrco('provides', - (r, None, (None,None,None))): - ok = True - for (rr, rf, rv) in instpo.requires: - if rr != r: - continue - if not txmbr.po.checkPrco('provides', (rr, rf, rv)): - ok = False - if ok: - isok = True - break - - # FIXME: it's ugly to have to check files separately here - elif r.startswith("/") and r in txmbr.po.filelist: - isok = True - break - - if isok: - continue - - if not isok: - removeList.append(instpo) - - - # we have a list of all the items impacted and - # left w/unresolved deps - # by this remove. stick them in the ret list with their for po in removeList: flags = {"GT": rpm.RPMSENSE_GREATER, "GE": rpm.RPMSENSE_EQUAL | rpm.RPMSENSE_GREATER, @@ -1215,7 +1145,7 @@ v = rv break - removing.append(pkgtup) + self._removing.append(po.pkgtup) reqtuple = (r, version_tuple_to_string(v), flags[f]) self.dcobj.addRequires(po, [reqtuple]) @@ -1225,7 +1155,98 @@ return ret + def _requiredByPkg(self, prov, pos = []): + """check to see if anything will or does require the provide, return + list of requiring pkg objects if so""" + + (r, f, v) = prov + + removeList = [] + # see what requires this provide name + + for instpo in pos: + pkgtup = instpo.pkgtup + # ignore stuff already being removed + if self.tsInfo.getMembers(pkgtup, TS_REMOVE_STATES): + continue + if pkgtup in self._removing: + continue + # check to ensure that we really fulfill instpo's need for r + if not instpo.checkPrco('requires', (r,f,v)): + continue + + self.verbose_logger.log(logginglevels.DEBUG_2, "looking at %s as a requirement of %s", r, pkgtup) + isok = False + # now see if anything else is providing what we need + for provtup in self.rpmdb.whatProvides(r, None, None): + # check if this provider is being removed + if provtup in self._removing: + continue + if self.tsInfo.getMembers(provtup, TS_REMOVE_STATES): + continue + + provpo = self.getInstalledPackageObject(provtup) + if provpo in removeList: + continue + # check if provpo actually satisfies instpo's need for r + # if so, we're golden + ok = True + for (rr, rf, rv) in instpo.requires: + if rr != r: + continue + if not provpo.checkPrco('provides', (rr, rf, rv)): + ok = False + if ok: + isok = True + break + + if isok: + continue + + # for files, we need to do a searchProvides() to take + # advantage of the shortcut of the files globbed into + # primary.xml.gz. this is a bit of a hack, but saves us + # from having to download the filelists for a lot of cases + if r.startswith("/"): + for po in self.pkgSack.searchProvides(r): + if self.tsInfo.getMembers(po.pkgtup, TS_INSTALL_STATES): + isok = True + break + for po in self.rpmdb.searchFiles(r): + if not self.tsInfo.getMembers(po.pkgtup, TS_REMOVE_STATES): + isok = True + break + if isok: + continue + + # now do the same set of checks with packages that are + # set to be installed. + for txmbr in self.tsInfo.getMembers(None, TS_INSTALL_STATES): + if txmbr.po.checkPrco('provides', + (r, None, (None,None,None))): + ok = True + for (rr, rf, rv) in instpo.requires: + if rr != r: + continue + if not txmbr.po.checkPrco('provides', (rr, rf, rv)): + ok = False + if ok: + isok = True + break + + # FIXME: it's ugly to have to check files separately here + elif r.startswith("/") and r in txmbr.po.filelist: + isok = True + break + + if isok: + continue + if not isok: + removeList.append(instpo) + self._removing.append(instpo.pkgtup) + return removeList + class DepCheck(object): """object that YumDepsolver uses to see what things are needed to close the transaction set. attributes: requires, conflicts are a list of @@ -1234,7 +1255,8 @@ def __init__(self): self.requires = [] self.conflicts = [] - + self.already_seen = {} + def addRequires(self, po, req_tuple_list): # fixme - do checking for duplicates or additions in here to zip things along reqobj = Requires(po, req_tuple_list) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/__init__.py new/yum-3.1.6/yum/__init__.py --- old/yum-3.1.5/yum/__init__.py 2007-03-22 01:22:34.000000000 +0100 +++ new/yum-3.1.6/yum/__init__.py 2007-04-04 05:45:12.000000000 +0200 @@ -53,7 +53,7 @@ from packages import parsePackages, YumAvailablePackage, YumLocalPackage, YumInstalledPackage from constants import * -__version__ = '3.1.5' +__version__ = '3.1.6' class YumBase(depsolve.YumDepsolver): """This is a primary structure and base class. It houses the objects and @@ -366,6 +366,7 @@ else: repos = self.repos.findRepos(thisrepo) + self.verbose_logger.debug('Setting up Package Sacks') if not archlist: archlist = rpmUtils.arch.getArchList() @@ -587,7 +588,7 @@ repo.name) exactmatch, matched, unmatched = \ - parsePackages(self.pkgSack.returnPackages(repoid), excludelist, casematch=1) + parsePackages(self._pkgSack.returnPackages(repoid), excludelist, casematch=1) for po in exactmatch + matched: self.verbose_logger.debug('Excluding %s', po) @@ -1195,7 +1196,7 @@ tmpvalues = [] for field in fields: value = getattr(po, field) - if value and value.find(s) != -1: + if value and value.lower().find(s.lower()) != -1: tmpvalues.append(value) if len(tmpvalues) > 0: @@ -1205,7 +1206,7 @@ tmpvalues = [] for field in fields: value = getattr(po, field) - if value and value.find(s) != -1: + if value and value.lower().find(s.lower()) != -1: tmpvalues.append(value) if len(tmpvalues) > 0: diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/plugins.py new/yum-3.1.6/yum/plugins.py --- old/yum-3.1.5/yum/plugins.py 2007-02-22 23:44:02.000000000 +0100 +++ new/yum-3.1.6/yum/plugins.py 2007-03-30 20:14:56.000000000 +0200 @@ -18,6 +18,7 @@ import imp import warnings import atexit +import gettext import logging import logginglevels from constants import * @@ -89,7 +90,15 @@ class PluginYumExit(Exception): '''Used by plugins to signal that yum should stop ''' - + def __init__(self, value="", translation_domain=""): + self.value = value + self.translation_domain = translation_domain + def __str__(self): + if self.translation_domain: + return gettext.dgettext(self.translation_domain, self.value) + else: + return self.value + class YumPlugins: ''' Manager class for Yum plugins. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/rpmsack.py new/yum-3.1.6/yum/rpmsack.py --- old/yum-3.1.5/yum/rpmsack.py 2007-02-27 18:36:41.000000000 +0100 +++ new/yum-3.1.6/yum/rpmsack.py 2007-04-02 18:07:54.000000000 +0200 @@ -56,8 +56,7 @@ if len(self._header_dict.keys()) == 0 : self._make_header_dict() - for pkgtup in self._header_dict.keys(): - yield pkgtup + return self._header_dict.keys() pkglist = property(_get_pkglist, None) @@ -257,40 +256,27 @@ if val != None: lookfor.append((i, val)) - def match(tup): - for idx, val in lookfor: - if tup[idx] != val: - return False - return True - # Find and yield matches if not self._header_dict: self._make_header_dict() - - for pkgtup in self._header_dict.keys(): - if match(pkgtup): - (hdr, idx) = self._header_dict[pkgtup] - yield hdr, pkgtup, idx - - def _search2(self, name=None, epoch=None, version=None, release=None, arch=None): - '''Generator that yield (header, index) for matching packages - - This version uses RPM to do the work but it's significantly slower than _search() - Not actually used. - ''' - ts = self.readOnlyTS() - mi = ts.dbMatch() - # Set up the search patterns - for arg in ('name', 'epoch', 'version', 'release', 'arch'): - val = locals()[arg] - if val != None: - mi.pattern(arg, rpm.RPMMIRE_DEFAULT, val) - - # Report matches - for hdr in mi: - if hdr['name'] != 'gpg-pubkey': - yield (hdr, mi.instance()) + ret = [] + # We have the full pkgtup, just grab it from the header dict + if len(lookfor) == 5: + pkgtup = (name, arch, epoch, ver, rel) + if self._header_dict.has_key(pkgtup): + hdr, idx = self._header_dict[pkgtup] + ret.append( (hdr, pkgtup, idx) ) + else: + for (pkgtup, (hdr, idx)) in self._header_dict.items(): + ok = True + for thisindex, val in lookfor: + if pkgtup[thisindex] != val: + ok = False + break + if ok: + ret.append( (hdr, pkgtup, idx) ) + return ret def _makePackageObject(self, hdr, index): @@ -429,7 +415,7 @@ returns a list of pkgtuples of providing packages, possibly empty""" pkgs = self.searchRequires(name) - + if flags == 0: flags = None if type(version) is types.StringType: diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/sqlitecache.py new/yum-3.1.6/yum/sqlitecache.py --- old/yum-3.1.5/yum/sqlitecache.py 2007-03-04 20:30:35.000000000 +0100 +++ new/yum-3.1.6/yum/sqlitecache.py 2007-04-04 01:03:50.000000000 +0200 @@ -189,6 +189,8 @@ release TEXT, pkgKey TEXT %s) """ % (t, extraCol)) + executeSQL(cur, "CREATE INDEX IF NOT EXISTS pkg%s on %s (pkgKey)" + % (t, t)) # Create the files table to hold all the file information executeSQL(cur, """CREATE TABLE files ( name TEXT, diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/sqlitesack.py new/yum-3.1.6/yum/sqlitesack.py --- old/yum-3.1.5/yum/sqlitesack.py 2007-03-16 21:27:52.000000000 +0100 +++ new/yum-3.1.6/yum/sqlitesack.py 2007-03-30 20:14:56.000000000 +0200 @@ -35,7 +35,6 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase): def __init__(self, repo, db_obj): - self._checksums = [] self.prco = { 'obsoletes': [], 'conflicts': [], @@ -109,7 +108,7 @@ def _loadFiles(self): if self._loadedfiles: return self._files - + result = {} #FIXME - this should be try, excepting @@ -125,7 +124,7 @@ dirname = ob['dirname'] filetypes = decodefiletypelist(ob['filetypes']) filenames = decodefilenamelist(ob['filenames']) - while(filenames): + while(filetypes): if dirname: filename = dirname+'/'+filenames.pop() else: @@ -134,7 +133,7 @@ result.setdefault(filetype,[]).append(filename) self._loadedfiles = True self._files = result - + return self._files def _loadChangelog(self): @@ -204,7 +203,7 @@ self.filelistsdb = {} self.otherdb = {} self.excludes = {} - + def __len__(self): for (rep,cache) in self.primarydb.items(): cur = cache.cursor() @@ -712,7 +711,7 @@ # Return a list representing filestring (filenames can not contain /) def decodefilenamelist(filenamestring): - return misc.unique(filenamestring.split('/')) + return filenamestring.split('/') # Return a string representing filetypeslist # filetypes should be file, dir or ghost diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum/transactioninfo.py new/yum-3.1.6/yum/transactioninfo.py --- old/yum-3.1.5/yum/transactioninfo.py 2007-02-21 08:14:52.000000000 +0100 +++ new/yum-3.1.6/yum/transactioninfo.py 2007-04-01 04:44:10.000000000 +0200 @@ -21,6 +21,7 @@ # with the given txmbr. from constants import * +from packageSack import ListPackageSack import Errors import warnings @@ -62,26 +63,26 @@ print msg - def getMembers(self, pkgtup=None, output_states=None): + def getMembers(self, pkgtup=None, output_states=None, asSack=False): """takes an optional package tuple and returns all transaction members matching, no pkgtup means it returns all transaction members""" + returnlist = [] + if pkgtup is None: - returnlist = [] for key in self.pkgdict.keys(): for p in self.pkgdict[key]: if not output_states or p.output_state in output_states: returnlist.append(p) - return returnlist - if self.pkgdict.has_key(pkgtup): - ret = [] + elif self.pkgdict.has_key(pkgtup): for p in self.pkgdict[pkgtup]: if not output_states or p.output_state in output_states: - ret.append(p) - return ret - else: - return [] + returnlist.append(p) + + if asSack: + return ListPackageSack(map(lambda x: x.po, returnlist)) + return returnlist def getMode(self, name=None, arch=None, epoch=None, ver=None, rel=None): """returns the mode of the first match from the transaction set, diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum.spec new/yum-3.1.6/yum.spec --- old/yum-3.1.5/yum.spec 2007-03-22 01:23:38.000000000 +0100 +++ new/yum-3.1.6/yum.spec 2007-04-04 05:45:25.000000000 +0200 @@ -1,6 +1,6 @@ Summary: RPM installer/updater Name: yum -Version: 3.1.5 +Version: 3.1.6 Release: 1 License: GPL Group: System Environment/Base @@ -89,6 +89,9 @@ %{_mandir}/man*/yum-updatesd* %changelog +* Tue Apr 3 2007 Seth Vidal <skvidal at linux.duke.edu> +- 3.1.6 + * Wed Mar 21 2007 Seth Vidal <skvidal at linux.duke.edu> - 3.1.5 diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/yum-3.1.5/yum-updatesd.py new/yum-3.1.6/yum-updatesd.py --- old/yum-3.1.5/yum-updatesd.py 2007-03-19 21:32:33.000000000 +0100 +++ new/yum-3.1.6/yum-updatesd.py 2007-03-30 20:14:56.000000000 +0200 @@ -28,6 +28,7 @@ # $ dbus-send --system --print-reply --type=method_call \ # --dest=edu.duke.linux.yum /Updatesd edu.duke.linux.yum.CheckNow +import gettext import os import sys import time @@ -57,7 +58,7 @@ import callback config_file = '/etc/yum/yum-updatesd.conf' - +initial_directory = os.getcwd() class UpdateEmitter(object): """Abstract object for implementing different types of emitters.""" @@ -82,6 +83,11 @@ """Emitted when checking for updates failed.""" pass + def setupFailed(self, error, translation_domain): + """Emitted when plugin initialization failed.""" + pass + + class SyslogUpdateEmitter(UpdateEmitter): def __init__(self, syslog_facility, ident = "yum-updatesd", level = "WARN"): @@ -196,6 +202,10 @@ def checkFailed(self, error): self.dbusintf.CheckFailedSignal(error) + def setupFailed(self, error, translation_domain): + self.dbusintf.SetupFailedSignal(error, translation_domain) + + class YumDbusInterface(dbus.service.Object): def __init__(self, bus_name, object_path='/UpdatesAvail'): dbus.service.Object.__init__(self, bus_name, object_path) @@ -220,6 +230,11 @@ def CheckFailedSignal(self, message): pass + @dbus.service.signal('edu.duke.linux.yum') + def SetupFailedSignal(self, message, translation_domain=""): + pass + + class UDConfig(BaseConfig): """Config format for the daemon""" run_interval = IntOption(3600) @@ -316,7 +331,7 @@ def __init__(self, opts): yum.YumBase.__init__(self) self.opts = opts - self.doSetup() + self.didSetup = False self.emitters = [] if 'dbus' in self.opts.emit_via: @@ -432,6 +447,27 @@ self.tsInfo.addObsoleted(installed, obsoleting) def updatesCheck(self): + if not self.didSetup: + try: + self.doSetup() + except Exception, e: + syslog.syslog(syslog.LOG_WARNING, + "error initializing: %s" % e) + + if isinstance(e, yum.plugins.PluginYumExit): + self.emitSetupFailed(e.value, e.translation_domain) + else: + # if we don't know where the string is from, then assume + # it's not marked for translation (versus sending + # gettext.textdomain() and assuming it's from the default + # domain for this app) + self.emitSetupFailed(str(e)) + # Setup failed, let's restart and try again after the update + # interval + restart() + else: + self.didSetup = True + try: if not self.refreshUpdates(): return @@ -519,6 +555,10 @@ """method to emit a notice when checking for updates failed""" map(lambda x: x.checkFailed(error), self.emitters) + def emitSetupFailed(self, error, translation_domain=""): + """method to emit a notice when checking for updates failed""" + map(lambda x: x.setupFailed(error, translation_domain), self.emitters) + class YumDbusListener(dbus.service.Object): def __init__(self, updd, bus_name, object_path='/Updatesd', @@ -558,6 +598,10 @@ def shutDown(): sys.exit(0) +def restart(): + os.chdir(initial_directory) + os.execve(sys.argv[0], sys.argv, os.environ) + def main(): # we'll be threading for downloads/updates gobject.threads_init() ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org