diff --git a/yum-HEAD.patch b/yum-HEAD.patch index a6156a1..9a66d9a 100644 --- a/yum-HEAD.patch +++ b/yum-HEAD.patch @@ -96,7 +96,7 @@ index 2f6154e..2e5a052 100644 diff --git a/cli.py b/cli.py old mode 100644 new mode 100755 -index 6056d38..4122d5d +index 6056d38..9225d5a --- a/cli.py +++ b/cli.py @@ -25,7 +25,7 @@ import sys @@ -308,10 +308,11 @@ index 6056d38..4122d5d summary = '' # do disk space report first p = re.compile('needs (\d+)MB on the (\S+) filesystem') -@@ -408,16 +452,17 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -407,17 +451,45 @@ class YumBaseCli(yum.YumBase, output.YumOutput): + return summary - def doCommands(self): +- def doCommands(self): - """ - Calls the base command passes the extended commands/args out to be - parsed (most notably package globs). @@ -320,8 +321,35 @@ index 6056d38..4122d5d - - 0 = we're done, exit - - 1 = we've errored, exit with error string - - 2 = we've got work yet to do, onto the next stage -- """ ++ def waitForLock(self): ++ """Establish the yum lock. If another process is already ++ holding the yum lock, by default this method will keep trying ++ to establish the lock until it is successful. However, if ++ :attr:`self.conf.exit_on_lock` is set to True, it will ++ raise a :class:`Errors.YumBaseError`. + """ - ++ lockerr = "" ++ while True: ++ try: ++ self.doLock() ++ except yum.Errors.LockError, e: ++ if exception2msg(e) != lockerr: ++ lockerr = exception2msg(e) ++ self.logger.critical(lockerr) ++ if e.errno: ++ raise yum.Errors.YumBaseError, _("Can't create lock file; exiting") ++ if not self.conf.exit_on_lock: ++ self.logger.critical("Another app is currently holding the yum lock; waiting for it to exit...") ++ import utils ++ utils.show_lock_owner(e.pid, self.logger) ++ time.sleep(2) ++ else: ++ raise yum.Errors.YumBaseError, _("Another app is currently holding the yum lock; exiting as configured by exit_on_lock") ++ else: ++ break ++ ++ def doCommands(self): + """Call the base command, and pass it the extended commands or + arguments. + @@ -336,7 +364,7 @@ index 6056d38..4122d5d # at this point we know the args are valid - we don't know their meaning # but we know we're not being sent garbage -@@ -435,14 +480,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -435,14 +507,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput): try: self._getTs(needTsRemove) except yum.Errors.YumBaseError, e: @@ -359,7 +387,7 @@ index 6056d38..4122d5d # just make sure there's not, well, nothing to do if len(self.tsInfo) == 0: self.verbose_logger.info(_('Trying to run the transaction but nothing to do. Exiting.')) -@@ -453,7 +502,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -453,7 +529,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): lsts = self.listTransaction() if self.verbose_logger.isEnabledFor(yum.logginglevels.INFO_1): self.verbose_logger.log(yum.logginglevels.INFO_1, lsts) @@ -368,7 +396,7 @@ index 6056d38..4122d5d # If we are in quiet, and assumeyes isn't on we want to output # at least the transaction list anyway. self.logger.warn(lsts) -@@ -463,7 +512,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -463,7 +539,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): rmpkgs = [] stuff_to_download = False install_only = True @@ -376,7 +404,7 @@ index 6056d38..4122d5d for txmbr in self.tsInfo.getMembers(): if txmbr.ts_state not in ('i', 'u'): install_only = False -@@ -471,7 +519,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -471,7 +546,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): if po: rmpkgs.append(po) else: @@ -384,7 +412,7 @@ index 6056d38..4122d5d stuff_to_download = True po = txmbr.po if po: -@@ -489,9 +536,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -489,9 +563,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput): else: self.reportDownloadSize(downloadpkgs, install_only) @@ -406,7 +434,7 @@ index 6056d38..4122d5d self.verbose_logger.info(_('Exiting on user Command')) return -1 -@@ -609,12 +667,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -609,12 +694,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return resultobject.return_code def gpgsigcheck(self, pkgs): @@ -426,7 +454,7 @@ index 6056d38..4122d5d for po in pkgs: result, errmsg = self.sigCheckPkg(po) -@@ -623,7 +683,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -623,7 +710,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput): continue elif result == 1: @@ -436,7 +464,7 @@ index 6056d38..4122d5d raise yum.Errors.YumBaseError, \ _('Refusing to automatically import keys when running ' \ 'unattended.\nUse "-y" to override.') -@@ -691,12 +752,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -691,12 +779,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput): ", ".join(matches)) self.verbose_logger.log(yum.logginglevels.INFO_2, msg) @@ -505,7 +533,7 @@ index 6056d38..4122d5d # get the list of available packages # iterate over the user's list # add packages to Transaction holding class if they match. -@@ -710,11 +821,36 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -710,11 +848,36 @@ class YumBaseCli(yum.YumBase, output.YumOutput): for arg in userlist: if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or os.path.exists(arg))): @@ -544,7 +572,7 @@ index 6056d38..4122d5d except yum.Errors.InstallError: self.verbose_logger.log(yum.logginglevels.INFO_2, _('No package %s%s%s available.'), -@@ -723,6 +859,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -723,6 +886,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): self._maybeYouMeant(arg) else: done = True @@ -552,7 +580,7 @@ index 6056d38..4122d5d if len(self.tsInfo) > oldcount: change = len(self.tsInfo) - oldcount return 2, [P_('%d package to install', '%d packages to install', change) % change] -@@ -732,9 +869,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -732,9 +896,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 0, [_('Nothing to do')] def updatePkgs(self, userlist, quiet=0, update_to=False): @@ -583,7 +611,7 @@ index 6056d38..4122d5d # if there is no userlist, then do global update below # this is probably 90% of the calls # if there is a userlist then it's for updating pkgs, not obsoleting -@@ -745,21 +900,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -745,21 +927,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput): else: # go through the userlist - look for items that are local rpms. If we find them @@ -614,7 +642,7 @@ index 6056d38..4122d5d if len(self.tsInfo) > oldcount: change = len(self.tsInfo) - oldcount -@@ -770,9 +922,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -770,9 +949,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput): # Note that we aren't in __init__ yet for a couple of reasons, but we # probably will get there for 3.2.28. def distroSyncPkgs(self, userlist): @@ -642,7 +670,7 @@ index 6056d38..4122d5d level = 'diff' if userlist and userlist[0] in ('full', 'diff', 'different'): -@@ -831,6 +998,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -831,6 +1025,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): continue nayi = napkg.yumdb_info @@ -650,7 +678,7 @@ index 6056d38..4122d5d for apkg in self.pkgSack.searchPkgTuple(napkg.pkgtup): if ('checksum_type' in nayi and 'checksum_data' in nayi and -@@ -865,15 +1033,54 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -865,15 +1060,54 @@ class YumBaseCli(yum.YumBase, output.YumOutput): else: return 0, [_('No Packages marked for Distribution Synchronization')] @@ -711,7 +739,7 @@ index 6056d38..4122d5d if not rms: self._checkMaybeYouMeant(arg, always_output=False, rpmdb_only=True) all_rms.extend(rms) -@@ -884,12 +1091,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -884,12 +1118,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 0, [_('No Packages marked for removal')] def downgradePkgs(self, userlist): @@ -739,7 +767,7 @@ index 6056d38..4122d5d for arg in userlist: if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or os.path.exists(arg))): -@@ -905,26 +1124,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -905,26 +1151,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput): self.term.MODE['bold'], arg, self.term.MODE['normal']) self._maybeYouMeant(arg) @@ -788,7 +816,7 @@ index 6056d38..4122d5d except yum.Errors.ReinstallRemoveError: self._checkMaybeYouMeant(arg, always_output=False) except yum.Errors.ReinstallInstallError, e: -@@ -940,15 +1177,31 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -940,15 +1204,31 @@ class YumBaseCli(yum.YumBase, output.YumOutput): except yum.Errors.ReinstallError, e: assert False, "Shouldn't happen, but just in case" self.verbose_logger.log(yum.logginglevels.INFO_2, e) @@ -823,7 +851,7 @@ index 6056d38..4122d5d # read in each package into a YumLocalPackage Object # append it to self.localPackages # check if it can be installed or updated based on nevra versus rpmdb -@@ -972,20 +1225,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -972,20 +1252,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 0, [_('Nothing to do')] def returnPkgLists(self, extcmds, installed_available=False): @@ -863,7 +891,7 @@ index 6056d38..4122d5d special = ['available', 'installed', 'all', 'extras', 'updates', 'recent', 'obsoletes'] -@@ -1017,8 +1275,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1017,8 +1302,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return ypl def search(self, args): @@ -891,7 +919,7 @@ index 6056d38..4122d5d # call the yum module search function with lists of tags to search # and what to search for -@@ -1108,9 +1383,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1108,9 +1410,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 0, matching def deplist(self, args): @@ -914,7 +942,7 @@ index 6056d38..4122d5d pkgs = [] for arg in args: if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or -@@ -1131,10 +1417,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1131,10 +1444,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 0, [] def provides(self, args): @@ -938,7 +966,7 @@ index 6056d38..4122d5d old_sdup = self.conf.showdupesfromrepos # For output, as searchPackageProvides() is always in showdups mode self.conf.showdupesfromrepos = True -@@ -1147,6 +1442,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1147,6 +1469,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput): paths = set(sys.path + os.environ['PATH'].split(':')) nargs = [] for arg in args: @@ -947,7 +975,7 @@ index 6056d38..4122d5d if yum.misc.re_filename(arg) or yum.misc.re_glob(arg): continue for path in paths: -@@ -1163,20 +1460,77 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1163,20 +1487,77 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 0, [] def resolveDepCli(self, args): @@ -1030,20 +1058,20 @@ index 6056d38..4122d5d hdrcode = pkgcode = xmlcode = dbcode = expccode = 0 pkgresults = hdrresults = xmlresults = dbresults = expcresults = [] msg = self.fmtKeyValFill(_('Cleaning repos: '), -@@ -1228,130 +1582,257 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1228,130 +1609,257 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return code, [] def returnGroupLists(self, userlist): + """Print out a list of groups that match the given names or + wildcards. - -- uservisible=1 ++ + :param extcmds: a list of names or wildcards specifying + groups to list + :return: (exit_code, [ errors ]) + + exit_code is:: -+ + +- uservisible=1 + 0 = we're done, exit + 1 = we've errored, exit with error string + 2 = we've got work yet to do, onto the next stage @@ -1368,17 +1396,17 @@ index 6056d38..4122d5d except yum.Errors.GroupsError: self.logger.critical(_('Warning: Group %s does not exist.'), group_string) continue -@@ -1368,17 +1849,61 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1368,17 +1876,61 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)] def removeGroups(self, grouplist): - """Remove only packages of the named group(s). Do not recurse.""" + """Mark the packages in the given groups for removal. -+ + + :param grouplist: a list of names or wildcards specifying + groups to be removed + :return: (exit_code, [ errors ]) - ++ + exit_code is:: + + 0 = we're done, exit @@ -1438,7 +1466,7 @@ index 6056d38..4122d5d if not pkgs_used: return 0, [_('No packages to remove from groups')] -@@ -1389,7 +1914,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1389,7 +1941,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput): def _promptWanted(self): # shortcut for the always-off/always-on options @@ -1447,7 +1475,7 @@ index 6056d38..4122d5d return False if self.conf.alwaysprompt: return True -@@ -1400,7 +1925,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1400,7 +1952,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput): # package wasn't explictly given on the command line for txmbr in self.tsInfo.getMembers(): if txmbr.isDep or \ @@ -1455,7 +1483,7 @@ index 6056d38..4122d5d txmbr.name not in self.extcmds: return True -@@ -1408,11 +1932,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1408,11 +1959,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return False def usage(self): @@ -1469,7 +1497,7 @@ index 6056d38..4122d5d sys.stdout.write(self.optparser.get_usage()) def _installable(self, pkg, ematch=False): -@@ -1468,9 +1992,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput): +@@ -1468,9 +2019,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput): return False class YumOptionParser(OptionParser): @@ -1481,7 +1509,7 @@ index 6056d38..4122d5d def __init__(self,base, **kwargs): # check if this is called with a utils=True/False parameter -@@ -1488,13 +2012,23 @@ class YumOptionParser(OptionParser): +@@ -1488,13 +2039,23 @@ class YumOptionParser(OptionParser): self._addYumBasicOptions() def error(self, msg): @@ -1507,7 +1535,7 @@ index 6056d38..4122d5d try: args = _filtercmdline( ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), -@@ -1521,7 +2055,15 @@ class YumOptionParser(OptionParser): +@@ -1521,7 +2082,15 @@ class YumOptionParser(OptionParser): return ret def setupYumConfig(self, args=None): @@ -1524,7 +1552,7 @@ index 6056d38..4122d5d if not args: (opts, cmds) = self.parse_args() else: -@@ -1533,16 +2075,22 @@ class YumOptionParser(OptionParser): +@@ -1533,16 +2102,22 @@ class YumOptionParser(OptionParser): try: # config file is parsed and moving us forward # set some things in it. @@ -1553,7 +1581,7 @@ index 6056d38..4122d5d self.base.conf.cache = 1 if opts.obsoletes: -@@ -1610,10 +2158,6 @@ class YumOptionParser(OptionParser): +@@ -1610,10 +2185,6 @@ class YumOptionParser(OptionParser): self.base.usage() sys.exit(1) @@ -1564,7 +1592,7 @@ index 6056d38..4122d5d # Disable all gpg key checking, if requested. if opts.nogpgcheck: # Altering the normal configs. doesn't work too well, esp. with -@@ -1640,10 +2184,18 @@ class YumOptionParser(OptionParser): +@@ -1640,10 +2211,18 @@ class YumOptionParser(OptionParser): sys.exit(1) def getRoot(self,opts): @@ -1584,7 +1612,7 @@ index 6056d38..4122d5d if os.access(opts.installroot+'/'+opts.conffile, os.R_OK): opts.conffile = opts.installroot+'/'+opts.conffile elif opts.conffile == '/etc/yum/yum.conf': -@@ -1701,6 +2253,9 @@ class YumOptionParser(OptionParser): +@@ -1701,6 +2280,9 @@ class YumOptionParser(OptionParser): group.add_option("--showduplicates", dest="showdupesfromrepos", action="store_true", help=_("show duplicates, in repos, in list/search commands")) @@ -1594,7 +1622,7 @@ index 6056d38..4122d5d group.add_option("-e", "--errorlevel", dest="errorlevel", default=None, help=_("error output level"), type='int', metavar='[error level]') -@@ -1713,6 +2268,10 @@ class YumOptionParser(OptionParser): +@@ -1713,6 +2295,10 @@ class YumOptionParser(OptionParser): help=_("verbose operation")) group.add_option("-y", "--assumeyes", dest="assumeyes", action="store_true", help=_("answer yes for all questions")) @@ -1605,7 +1633,7 @@ index 6056d38..4122d5d group.add_option("--version", action="store_true", help=_("show Yum version and exit")) group.add_option("--installroot", help=_("set install root"), -@@ -1748,6 +2307,10 @@ class YumOptionParser(OptionParser): +@@ -1748,6 +2334,10 @@ class YumOptionParser(OptionParser): help=_("control whether color is used")) group.add_option("", "--releasever", dest="releasever", default=None, help=_("set value of $releasever in yum config and repo files")) @@ -1618,10 +1646,10 @@ index 6056d38..4122d5d diff --git a/completion-helper.py b/completion-helper.py new file mode 100755 -index 0000000..05801d1 +index 0000000..999b9ad --- /dev/null +++ b/completion-helper.py -@@ -0,0 +1,90 @@ +@@ -0,0 +1,95 @@ +#!/usr/bin/python -t +# -*- coding: utf-8 -*- +# @@ -1665,14 +1693,19 @@ index 0000000..05801d1 + +class ListCompletionCommand(yumcommands.ListCommand): + def doCommand(self, base, basecmd, extcmds): ++ def printPkgs(pkgs): ++ for pkg in pkgs: ++ if base.allowedMultipleInstalls(pkg): ++ print pkg.nvra ++ else: ++ print pkg.na ++ + ypl = base.doPackageLists(pkgnarrow=extcmds[0], + patterns=[get_pattern(extcmds)]) + if extcmds[0] in ("installed", "all"): -+ for pkg in ypl.installed: -+ print pkg.na ++ printPkgs(ypl.installed) + if extcmds[0] in ("available", "all"): -+ for pkg in ypl.available: -+ print pkg.na ++ printPkgs(ypl.available) + +class RepoListCompletionCommand(yumcommands.RepoListCommand): + def doCommand(self, base, basecmd, extcmds): @@ -3309,7 +3342,7 @@ index c60fa08..0000000 -ts run -exit diff --git a/etc/yum.bash b/etc/yum.bash -index f1e06e8..d484f8d 100644 +index f1e06e8..ac06316 100644 --- a/etc/yum.bash +++ b/etc/yum.bash @@ -1,53 +1,17 @@ @@ -3461,7 +3494,7 @@ index f1e06e8..d484f8d 100644 - check-update|grouplist|makecache|provides|whatprovides|resolvedep|\ - search) -+ check-update|makecache|provides|whatprovides|resolvedep|search) ++ check-update|makecache|resolvedep|search) return 0 ;; @@ -3571,7 +3604,7 @@ index f1e06e8..d484f8d 100644 ;; esac return 0 -@@ -288,42 +286,56 @@ _yum() +@@ -288,42 +286,61 @@ _yum() ;; install) @@ -3606,6 +3639,11 @@ index f1e06e8..d484f8d 100644 return 0 ;; ++ provides|whatprovides) ++ COMPREPLY=( $( compgen -f -o plusdirs -- "$cur" ) ) ++ return 0 ++ ;; ++ repolist) - [ "$prev" = "$cmd" ] && \ + [[ $prev == $cmd ]] && \ @@ -3635,7 +3673,7 @@ index f1e06e8..d484f8d 100644 COMPREPLY=( $( compgen -W 'all installed available nogroups grouplist groupinfo' -- "$cur" ) ) return 0 -@@ -337,7 +349,11 @@ _yum() +@@ -337,7 +354,11 @@ _yum() $split && return 0 @@ -150007,7 +150045,7 @@ index fa3e57c..ea4e683 100644 diff --git a/utils.py b/utils.py old mode 100644 new mode 100755 -index ced6ba0..e465cf7 +index ced6ba0..28fdd70 --- a/utils.py +++ b/utils.py @@ -13,6 +13,9 @@ @@ -150211,7 +150249,7 @@ index ced6ba0..e465cf7 try: self.closeRpmDB() self.doUnlock() -@@ -205,13 +247,27 @@ class YumUtilBase(YumBaseCli): +@@ -205,34 +247,31 @@ class YumUtilBase(YumBaseCli): def getOptionParser(self): @@ -150230,17 +150268,25 @@ index ced6ba0..e465cf7 + """ return self._option_group - def waitForLock(self): -+ """Establish the yum lock. If another process is already -+ holding the yum lock, by default this method will keep trying -+ to establish the lock until it is successful. However, if -+ :attr:`self.conf.exit_on_lock` is set to True, it will -+ raise a :class:`Errors.YumBaseError`. -+ """ - lockerr = "" - while True: - try: -@@ -233,6 +289,13 @@ class YumUtilBase(YumBaseCli): +- def waitForLock(self): +- lockerr = "" +- while True: +- try: +- self.doLock() +- except Errors.LockError, e: +- if exception2msg(e) != lockerr: +- lockerr = exception2msg(e) +- self.logger.critical(lockerr) +- if not self.conf.exit_on_lock: +- self.logger.critical("Another app is currently holding the yum lock; waiting for it to exit...") +- show_lock_owner(e.pid, self.logger) +- time.sleep(2) +- else: +- raise Errors.YumBaseError, _("Another app is currently holding the yum lock; exiting as configured by exit_on_lock") +- else: +- break +- + def _printUtilVersion(self): print "%s - %s (yum - %s)" % (self._utilName,self._utilVer,yum.__version__) def doUtilConfigSetup(self,args = sys.argv[1:],pluginsTypes=(plugins.TYPE_CORE,)): @@ -150254,7 +150300,7 @@ index ced6ba0..e465cf7 # Parse only command line options that affect basic yum setup opts = self._parser.firstParse(args) -@@ -305,8 +368,9 @@ class YumUtilBase(YumBaseCli): +@@ -305,8 +344,9 @@ class YumUtilBase(YumBaseCli): return opts def doUtilYumSetup(self): @@ -150266,7 +150312,7 @@ index ced6ba0..e465cf7 # FIXME - we need another way to do this, I think. try: self.waitForLock() -@@ -319,6 +383,11 @@ class YumUtilBase(YumBaseCli): +@@ -319,6 +359,11 @@ class YumUtilBase(YumBaseCli): sys.exit(1) def doUtilBuildTransaction(self, unfinished_transactions_check=True): @@ -150278,7 +150324,7 @@ index ced6ba0..e465cf7 try: (result, resultmsgs) = self.buildTransaction(unfinished_transactions_check = unfinished_transactions_check) except plugins.PluginYumExit, e: -@@ -361,6 +430,7 @@ class YumUtilBase(YumBaseCli): +@@ -361,6 +406,7 @@ class YumUtilBase(YumBaseCli): self.verbose_logger.log(logginglevels.INFO_2, _('\nDependencies Resolved')) def doUtilTransaction(self): @@ -152444,7 +152490,7 @@ index c1af4ad..e3e3956 100644 pass diff --git a/yum/__init__.py b/yum/__init__.py -index 99039e0..6401645 100644 +index 99039e0..abed04d 100644 --- a/yum/__init__.py +++ b/yum/__init__.py @@ -21,6 +21,7 @@ The Yum RPM software updater. @@ -152883,7 +152929,32 @@ index 99039e0..6401645 100644 self.repos.callback = prerepoconf.callback self.repos.setFailureCallback(prerepoconf.failure_callback) self.repos.setInterruptCallback(prerepoconf.interrupt_callback) -@@ -630,6 +729,14 @@ class YumBase(depsolve.Depsolve): +@@ -602,24 +701,6 @@ class YumBase(depsolve.Depsolve): + + + if doSetup: +- if (hasattr(urlgrabber, 'grabber') and +- hasattr(urlgrabber.grabber, 'pycurl')): +- # Must do basename checking, on cert. files... +- cert_basenames = {} +- for repo in self._repos.listEnabled(): +- if not repo.sslclientcert: +- continue +- bn = os.path.basename(repo.sslclientcert) +- if bn not in cert_basenames: +- cert_basenames[bn] = repo +- continue +- if repo.sslclientcert == cert_basenames[bn].sslclientcert: +- # Exactly the same path is fine too +- continue +- +- msg = 'sslclientcert basename shared between %s and %s' +- raise Errors.ConfigError, msg % (repo, cert_basenames[bn]) +- + repo_st = time.time() + self._repos.doSetup(thisrepo) + self.verbose_logger.debug('repo time: %0.3f' % (time.time() - repo_st)) +@@ -630,6 +711,14 @@ class YumBase(depsolve.Depsolve): self._repos = RepoStorage(self) def doSackSetup(self, archlist=None, thisrepo=None): @@ -152898,7 +152969,7 @@ index 99039e0..6401645 100644 warnings.warn(_('doSackSetup() will go away in a future version of Yum.\n'), Errors.YumFutureDeprecationWarning, stacklevel=2) -@@ -711,6 +818,9 @@ class YumBase(depsolve.Depsolve): +@@ -711,6 +800,9 @@ class YumBase(depsolve.Depsolve): def doUpdateSetup(self): @@ -152908,7 +152979,7 @@ index 99039e0..6401645 100644 warnings.warn(_('doUpdateSetup() will go away in a future version of Yum.\n'), Errors.YumFutureDeprecationWarning, stacklevel=2) -@@ -765,6 +875,8 @@ class YumBase(depsolve.Depsolve): +@@ -765,6 +857,8 @@ class YumBase(depsolve.Depsolve): return self._up def doGroupSetup(self): @@ -152917,7 +152988,7 @@ index 99039e0..6401645 100644 warnings.warn(_('doGroupSetup() will go away in a future version of Yum.\n'), Errors.YumFutureDeprecationWarning, stacklevel=2) -@@ -820,16 +932,14 @@ class YumBase(depsolve.Depsolve): +@@ -820,16 +914,14 @@ class YumBase(depsolve.Depsolve): self.verbose_logger.log(logginglevels.DEBUG_4, _('Adding group file from repository: %s'), repo) groupfile = repo.getGroups() @@ -152939,7 +153010,7 @@ index 99039e0..6401645 100644 self.logger.critical(msg) else: repo.groups_added = True -@@ -837,7 +947,10 @@ class YumBase(depsolve.Depsolve): +@@ -837,7 +929,10 @@ class YumBase(depsolve.Depsolve): if self._comps.compscount == 0: raise Errors.GroupsError, _('No Groups Available in any repository') @@ -152951,7 +153022,7 @@ index 99039e0..6401645 100644 self.verbose_logger.debug('group time: %0.3f' % (time.time() - group_st)) return self._comps -@@ -868,7 +981,7 @@ class YumBase(depsolve.Depsolve): +@@ -868,7 +963,7 @@ class YumBase(depsolve.Depsolve): # feed it into _tags.add() self._tags.add(repo.id, tag_sqlite) except (Errors.RepoError, Errors.PkgTagsError), e: @@ -152960,7 +153031,7 @@ index 99039e0..6401645 100644 self.logger.critical(msg) -@@ -881,9 +994,18 @@ class YumBase(depsolve.Depsolve): +@@ -881,9 +976,18 @@ class YumBase(depsolve.Depsolve): if self._history is None: pdb_path = self.conf.persistdir + "/history" self._history = yum.history.YumHistory(root=self.conf.installroot, @@ -152980,7 +153051,7 @@ index 99039e0..6401645 100644 # properties so they auto-create themselves with defaults repos = property(fget=lambda self: self._getRepos(), fset=lambda self, value: setattr(self, "_repos", value), -@@ -921,6 +1043,11 @@ class YumBase(depsolve.Depsolve): +@@ -921,6 +1025,11 @@ class YumBase(depsolve.Depsolve): fdel=lambda self: setattr(self, "_history", None), doc="Yum History Object") @@ -152992,7 +153063,7 @@ index 99039e0..6401645 100644 pkgtags = property(fget=lambda self: self._getTags(), fset=lambda self, value: setattr(self, "_tags",value), fdel=lambda self: setattr(self, "_tags", None), -@@ -928,9 +1055,10 @@ class YumBase(depsolve.Depsolve): +@@ -928,9 +1037,10 @@ class YumBase(depsolve.Depsolve): def doSackFilelistPopulate(self): @@ -153006,7 +153077,7 @@ index 99039e0..6401645 100644 necessary = False # I can't think of a nice way of doing this, we have to have the sack here -@@ -951,8 +1079,12 @@ class YumBase(depsolve.Depsolve): +@@ -951,8 +1061,12 @@ class YumBase(depsolve.Depsolve): self.repos.populateSack(mdtype='filelists') def yumUtilsMsg(self, func, prog): @@ -153021,7 +153092,7 @@ index 99039e0..6401645 100644 if self.rpmdb.contains(name="yum-utils"): return -@@ -964,8 +1096,17 @@ class YumBase(depsolve.Depsolve): +@@ -964,8 +1078,17 @@ class YumBase(depsolve.Depsolve): (hibeg, prog, hiend)) def buildTransaction(self, unfinished_transactions_check=True): @@ -153041,7 +153112,7 @@ index 99039e0..6401645 100644 if (unfinished_transactions_check and misc.find_unfinished_transactions(yumlibpath=self.conf.persistdir)): msg = _('There are unfinished transactions remaining. You might ' \ -@@ -1004,7 +1145,7 @@ class YumBase(depsolve.Depsolve): +@@ -1004,7 +1127,7 @@ class YumBase(depsolve.Depsolve): # If transaction was changed by postresolve plugins then we should run skipbroken again (rescode, restring) = self._doSkipBroken(rescode, restring, clear_skipped=False ) @@ -153050,7 +153121,7 @@ index 99039e0..6401645 100644 self.tsInfo.pkgSack.dropCachedData() # FIXME: This is horrible, see below and yummain. Maybe create a real -@@ -1044,6 +1185,39 @@ class YumBase(depsolve.Depsolve): +@@ -1044,6 +1167,39 @@ class YumBase(depsolve.Depsolve): if first.verEQ(other): continue msg = _('Protected multilib versions: %s != %s') @@ -153090,7 +153161,7 @@ index 99039e0..6401645 100644 xrestring.append(msg % (first, other)) if xrestring: rescode = 1 -@@ -1242,13 +1416,15 @@ class YumBase(depsolve.Depsolve): +@@ -1242,13 +1398,15 @@ class YumBase(depsolve.Depsolve): if None in pkgtup: return None return pkgtup @@ -153110,7 +153181,7 @@ index 99039e0..6401645 100644 if pkgtup is None: return self._not_found_i[pkgtup] = YumNotFoundPackage(pkgtup) -@@ -1382,6 +1558,8 @@ class YumBase(depsolve.Depsolve): +@@ -1382,6 +1540,8 @@ class YumBase(depsolve.Depsolve): for txmbr in self.tsInfo.getMembers(dep.pkgtup): for pkg in (txmbr.updates + txmbr.obsoletes): toRemove.add(pkg) @@ -153119,7 +153190,7 @@ index 99039e0..6401645 100644 toRemove.add(dep) self._getDepsToRemove(dep, deptree, toRemove) -@@ -1454,8 +1632,14 @@ class YumBase(depsolve.Depsolve): +@@ -1454,8 +1614,14 @@ class YumBase(depsolve.Depsolve): return probs def runTransaction(self, cb): @@ -153135,7 +153206,7 @@ index 99039e0..6401645 100644 self.plugins.run('pretrans') # We may want to put this other places, eventually, but for now it's -@@ -1516,10 +1700,23 @@ class YumBase(depsolve.Depsolve): +@@ -1516,10 +1682,23 @@ class YumBase(depsolve.Depsolve): pass self._ts_save_file = None @@ -153159,7 +153230,7 @@ index 99039e0..6401645 100644 # make resultobject - just a plain yumgenericholder object resultobject = misc.GenericHolder() -@@ -1567,13 +1764,24 @@ class YumBase(depsolve.Depsolve): +@@ -1567,13 +1746,24 @@ class YumBase(depsolve.Depsolve): self.plugins.run('posttrans') # sync up what just happened versus what is in the rpmdb if not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST): @@ -153189,7 +153260,7 @@ index 99039e0..6401645 100644 # check to see that the rpmdb and the tsInfo roughly matches # push package object metadata outside of rpmdb into yumdb # delete old yumdb metadata entries -@@ -1584,9 +1792,16 @@ class YumBase(depsolve.Depsolve): +@@ -1584,9 +1774,16 @@ class YumBase(depsolve.Depsolve): # that there is not also an install of this pkg in the tsInfo (reinstall) # for any kind of install add from_repo to the yumdb, and the cmdline # and the install reason @@ -153206,7 +153277,7 @@ index 99039e0..6401645 100644 for txmbr in self.tsInfo: if txmbr.output_state in TS_INSTALL_STATES: if not self.rpmdb.contains(po=txmbr.po): -@@ -1596,7 +1811,9 @@ class YumBase(depsolve.Depsolve): +@@ -1596,7 +1793,9 @@ class YumBase(depsolve.Depsolve): ' but is not!' % txmbr.po)) # Note: Get Panu to do te.Failed() so we don't have to txmbr.output_state = TS_FAILED @@ -153216,7 +153287,7 @@ index 99039e0..6401645 100644 po = self.getInstalledPackageObject(txmbr.pkgtup) rpo = txmbr.po po.yumdb_info.from_repo = rpo.repoid -@@ -1630,6 +1847,10 @@ class YumBase(depsolve.Depsolve): +@@ -1630,6 +1829,10 @@ class YumBase(depsolve.Depsolve): if md: po.yumdb_info.from_repo_timestamp = str(md.timestamp) @@ -153227,7 +153298,7 @@ index 99039e0..6401645 100644 loginuid = misc.getloginuid() if txmbr.updates or txmbr.downgrades or txmbr.reinstall: if txmbr.updates: -@@ -1640,11 +1861,16 @@ class YumBase(depsolve.Depsolve): +@@ -1640,11 +1843,16 @@ class YumBase(depsolve.Depsolve): opo = po if 'installed_by' in opo.yumdb_info: po.yumdb_info.installed_by = opo.yumdb_info.installed_by @@ -153244,7 +153315,7 @@ index 99039e0..6401645 100644 # Remove old ones after installing new ones, so we can copy values. for txmbr in self.tsInfo: if txmbr.output_state in TS_INSTALL_STATES: -@@ -1662,10 +1888,13 @@ class YumBase(depsolve.Depsolve): +@@ -1662,10 +1870,13 @@ class YumBase(depsolve.Depsolve): ' but is not!' % txmbr.po)) # Note: Get Panu to do te.Failed() so we don't have to txmbr.output_state = TS_FAILED @@ -153258,7 +153329,7 @@ index 99039e0..6401645 100644 self.verbose_logger.log(logginglevels.DEBUG_2, 'What is this? %s' % txmbr.po) self.plugins.run('postverifytrans') -@@ -1680,10 +1909,11 @@ class YumBase(depsolve.Depsolve): +@@ -1680,10 +1891,11 @@ class YumBase(depsolve.Depsolve): self.verbose_logger.debug('VerifyTransaction time: %0.3f' % (time.time() - vt_st)) def costExcludePackages(self): @@ -153274,7 +153345,7 @@ index 99039e0..6401645 100644 # if all the repo.costs are equal then don't bother running things costs = {} for r in self.repos.listEnabled(): -@@ -1705,10 +1935,12 @@ class YumBase(depsolve.Depsolve): +@@ -1705,10 +1917,12 @@ class YumBase(depsolve.Depsolve): done = True def excludePackages(self, repo=None): @@ -153290,7 +153361,7 @@ index 99039e0..6401645 100644 if "all" in self.conf.disable_excludes: return -@@ -1735,9 +1967,11 @@ class YumBase(depsolve.Depsolve): +@@ -1735,9 +1949,11 @@ class YumBase(depsolve.Depsolve): self.pkgSack.addPackageExcluder(repoid, exid,'exclude.match', match) def includePackages(self, repo): @@ -153305,7 +153376,7 @@ index 99039e0..6401645 100644 includelist = repo.getIncludePkgList() if len(includelist) == 0: -@@ -1757,8 +1991,11 @@ class YumBase(depsolve.Depsolve): +@@ -1757,8 +1973,11 @@ class YumBase(depsolve.Depsolve): self.pkgSack.addPackageExcluder(repo.id, exid, 'exclude.marked') def doLock(self, lockfile = YUM_PID_FILE): @@ -153319,7 +153390,7 @@ index 99039e0..6401645 100644 if self.conf.uid != 0: # If we are a user, assume we are using the root cache ... so don't # bother locking. -@@ -1774,38 +2011,26 @@ class YumBase(depsolve.Depsolve): +@@ -1774,38 +1993,26 @@ class YumBase(depsolve.Depsolve): mypid=str(os.getpid()) while not self._lock(lockfile, mypid, 0644): @@ -153373,7 +153444,7 @@ index 99039e0..6401645 100644 # if we're not root then we don't lock - just return nicely # Note that we can get here from __del__, so if we haven't created # YumBase.conf we don't want to do so here as creating stuff inside -@@ -1830,31 +2055,69 @@ class YumBase(depsolve.Depsolve): +@@ -1830,31 +2037,69 @@ class YumBase(depsolve.Depsolve): self._unlock(lockfile) self._lockfile = None @@ -153453,7 +153524,7 @@ index 99039e0..6401645 100644 failed = False if type(fo) is types.InstanceType: -@@ -1894,9 +2157,16 @@ class YumBase(depsolve.Depsolve): +@@ -1894,9 +2139,16 @@ class YumBase(depsolve.Depsolve): def verifyChecksum(self, fo, checksumType, csum): @@ -153473,7 +153544,7 @@ index 99039e0..6401645 100644 try: filesum = misc.checksum(checksumType, fo) except Errors.MiscError, e: -@@ -1908,6 +2178,17 @@ class YumBase(depsolve.Depsolve): +@@ -1908,6 +2160,17 @@ class YumBase(depsolve.Depsolve): return 0 def downloadPkgs(self, pkglist, callback=None, callback_total=None): @@ -153491,7 +153562,7 @@ index 99039e0..6401645 100644 def mediasort(apo, bpo): # FIXME: we should probably also use the mediaid; else we # could conceivably ping-pong between different disc1's -@@ -1943,6 +2224,7 @@ class YumBase(depsolve.Depsolve): +@@ -1943,6 +2206,7 @@ class YumBase(depsolve.Depsolve): self.history.close() self.plugins.run('predownload', pkglist=pkglist) @@ -153499,7 +153570,7 @@ index 99039e0..6401645 100644 repo_cached = False remote_pkgs = [] remote_size = 0 -@@ -1961,6 +2243,14 @@ class YumBase(depsolve.Depsolve): +@@ -1961,6 +2225,14 @@ class YumBase(depsolve.Depsolve): self.verbose_logger.debug(_("using local copy of %s") %(po,)) continue @@ -153514,7 +153585,7 @@ index 99039e0..6401645 100644 remote_pkgs.append(po) remote_size += po.size -@@ -1969,7 +2259,11 @@ class YumBase(depsolve.Depsolve): +@@ -1969,7 +2241,11 @@ class YumBase(depsolve.Depsolve): # way to save this, report the error and return if (self.conf.cache or repo_cached) and errors: return errors @@ -153527,7 +153598,7 @@ index 99039e0..6401645 100644 remote_pkgs.sort(mediasort) # This is kind of a hack and does nothing in non-Fedora versions, -@@ -1979,8 +2273,9 @@ class YumBase(depsolve.Depsolve): +@@ -1979,8 +2255,9 @@ class YumBase(depsolve.Depsolve): urlgrabber.progress.text_meter_total_size(remote_size) beg_download = time.time() i = 0 @@ -153538,7 +153609,7 @@ index 99039e0..6401645 100644 for po in remote_pkgs: # Recheck if the file is there, works around a couple of weird # edge cases. -@@ -1992,67 +2287,94 @@ class YumBase(depsolve.Depsolve): +@@ -1992,67 +2269,94 @@ class YumBase(depsolve.Depsolve): remote_size -= po.size if hasattr(urlgrabber.progress, 'text_meter_total_size'): urlgrabber.progress.text_meter_total_size(remote_size, @@ -153666,7 +153737,7 @@ index 99039e0..6401645 100644 if type(fo) is types.InstanceType: fo = fo.filename -@@ -2076,9 +2398,12 @@ class YumBase(depsolve.Depsolve): +@@ -2076,9 +2380,12 @@ class YumBase(depsolve.Depsolve): return 1 def downloadHeader(self, po): @@ -153681,7 +153752,7 @@ index 99039e0..6401645 100644 if hasattr(po, 'pkgtype') and po.pkgtype == 'local': return -@@ -2122,15 +2447,17 @@ class YumBase(depsolve.Depsolve): +@@ -2122,15 +2429,17 @@ class YumBase(depsolve.Depsolve): return def sigCheckPkg(self, po): @@ -153707,7 +153778,7 @@ index 99039e0..6401645 100644 if self._override_sigchecks: check = False hasgpgkey = 0 -@@ -2181,6 +2508,9 @@ class YumBase(depsolve.Depsolve): +@@ -2181,6 +2490,9 @@ class YumBase(depsolve.Depsolve): return result, msg def cleanUsedHeadersPackages(self): @@ -153717,7 +153788,7 @@ index 99039e0..6401645 100644 filelist = [] for txmbr in self.tsInfo: if txmbr.po.state not in TS_INSTALL_STATES: -@@ -2218,27 +2548,42 @@ class YumBase(depsolve.Depsolve): +@@ -2218,27 +2530,42 @@ class YumBase(depsolve.Depsolve): _('%s removed'), fn) def cleanHeaders(self): @@ -153762,7 +153833,7 @@ index 99039e0..6401645 100644 cachedir = self.conf.persistdir + "/rpmdb-indexes/" if not os.path.exists(cachedir): filelist = [] -@@ -2272,8 +2617,29 @@ class YumBase(depsolve.Depsolve): +@@ -2272,8 +2599,29 @@ class YumBase(depsolve.Depsolve): def doPackageLists(self, pkgnarrow='all', patterns=None, showdups=None, ignore_case=False): @@ -153794,7 +153865,7 @@ index 99039e0..6401645 100644 if showdups is None: showdups = self.conf.showdupesfromrepos ygh = misc.GenericHolder(iter=pkgnarrow) -@@ -2323,10 +2689,22 @@ class YumBase(depsolve.Depsolve): +@@ -2323,10 +2671,22 @@ class YumBase(depsolve.Depsolve): key = (pkg.name, pkg.arch) if pkg.pkgtup in dinst: reinstall_available.append(pkg) @@ -153820,7 +153891,7 @@ index 99039e0..6401645 100644 # produce the updates list of tuples elif pkgnarrow == 'updates': -@@ -2461,14 +2839,13 @@ class YumBase(depsolve.Depsolve): +@@ -2461,14 +2821,13 @@ class YumBase(depsolve.Depsolve): def findDeps(self, pkgs): @@ -153840,7 +153911,7 @@ index 99039e0..6401645 100644 results = {} for pkg in pkgs: -@@ -2495,10 +2872,22 @@ class YumBase(depsolve.Depsolve): +@@ -2495,10 +2854,22 @@ class YumBase(depsolve.Depsolve): # pre 3.2.10 API used to always showdups, so that's the default atm. def searchGenerator(self, fields, criteria, showdups=True, keys=False, searchtags=True, searchrpmdb=True): @@ -153867,7 +153938,7 @@ index 99039e0..6401645 100644 sql_fields = [] for f in fields: sql_fields.append(RPM_TO_SQLITE.get(f, f)) -@@ -2661,6 +3050,14 @@ class YumBase(depsolve.Depsolve): +@@ -2661,6 +3032,14 @@ class YumBase(depsolve.Depsolve): yield (po, vs) def searchPackageTags(self, criteria): @@ -153882,7 +153953,7 @@ index 99039e0..6401645 100644 results = {} # name = [(criteria, taglist)] for c in criteria: c = c.lower() -@@ -2677,11 +3074,16 @@ class YumBase(depsolve.Depsolve): +@@ -2677,11 +3056,16 @@ class YumBase(depsolve.Depsolve): return results def searchPackages(self, fields, criteria, callback=None): @@ -153904,7 +153975,7 @@ index 99039e0..6401645 100644 warnings.warn(_('searchPackages() will go away in a future version of Yum.\ Use searchGenerator() instead. \n'), Errors.YumFutureDeprecationWarning, stacklevel=2) -@@ -2700,13 +3102,23 @@ class YumBase(depsolve.Depsolve): +@@ -2700,13 +3084,23 @@ class YumBase(depsolve.Depsolve): def searchPackageProvides(self, args, callback=None, callback_has_matchfor=False): @@ -153932,7 +154003,7 @@ index 99039e0..6401645 100644 else: isglob = True canBeFile = misc.re_filename(arg) -@@ -2723,7 +3135,7 @@ class YumBase(depsolve.Depsolve): +@@ -2723,7 +3117,7 @@ class YumBase(depsolve.Depsolve): where = self.returnPackagesByDep(arg) else: usedDepString = False @@ -153941,7 +154012,7 @@ index 99039e0..6401645 100644 self.verbose_logger.log(logginglevels.DEBUG_1, P_('Searching %d package', 'Searching %d packages', len(where)), len(where)) -@@ -2817,25 +3229,160 @@ class YumBase(depsolve.Depsolve): +@@ -2817,25 +3211,160 @@ class YumBase(depsolve.Depsolve): return matches @@ -154114,7 +154185,7 @@ index 99039e0..6401645 100644 if uservisible: if grp.user_visible: installed.append(grp) -@@ -2847,34 +3394,98 @@ class YumBase(depsolve.Depsolve): +@@ -2847,34 +3376,98 @@ class YumBase(depsolve.Depsolve): available.append(grp) else: available.append(grp) @@ -154223,7 +154294,7 @@ index 99039e0..6401645 100644 thesegroups = self.comps.return_groups(grpid) if not thesegroups: raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid) -@@ -2898,13 +3509,58 @@ class YumBase(depsolve.Depsolve): +@@ -2898,13 +3491,58 @@ class YumBase(depsolve.Depsolve): self.tsInfo.remove(txmbr.po.pkgtup) @@ -154289,7 +154360,7 @@ index 99039e0..6401645 100644 """ if not self.comps.has_group(grpid): -@@ -2920,6 +3576,9 @@ class YumBase(depsolve.Depsolve): +@@ -2920,6 +3558,9 @@ class YumBase(depsolve.Depsolve): if group_package_types: package_types = group_package_types @@ -154299,7 +154370,7 @@ index 99039e0..6401645 100644 for thisgroup in thesegroups: if thisgroup.selected: continue -@@ -2934,12 +3593,49 @@ class YumBase(depsolve.Depsolve): +@@ -2934,12 +3575,49 @@ class YumBase(depsolve.Depsolve): if 'optional' in package_types: pkgs.extend(thisgroup.optional_packages) @@ -154350,7 +154421,7 @@ index 99039e0..6401645 100644 except Errors.InstallError, e: self.verbose_logger.debug(_('No package named %s available to be installed'), pkg) -@@ -2953,7 +3649,9 @@ class YumBase(depsolve.Depsolve): +@@ -2953,7 +3631,9 @@ class YumBase(depsolve.Depsolve): group_conditionals = enable_group_conditionals count_cond_test = 0 @@ -154361,7 +154432,7 @@ index 99039e0..6401645 100644 for condreq, cond in thisgroup.conditional_packages.iteritems(): if self.isPackageInstalled(cond): try: -@@ -2990,17 +3688,22 @@ class YumBase(depsolve.Depsolve): +@@ -2990,17 +3670,23 @@ class YumBase(depsolve.Depsolve): if cond not in self.tsInfo.conditionals: self.tsInfo.conditionals[cond] = [] self.tsInfo.conditionals[cond].extend(pkgs) @@ -154371,7 +154442,9 @@ index 99039e0..6401645 100644 + if not upgrade and len(txmbrs_used) == old_txmbrs: + self.logger.critical(_('Warning: Group %s does not have any packages to install.'), thisgroup.groupid) if count_cond_test: - self.logger.critical(_('Group %s does have %u conditional packages, which may get installed.'), count_cond_test) +- self.logger.critical(_('Group %s does have %u conditional packages, which may get installed.'), count_cond_test) ++ self.logger.critical(_('Group %s does have %u conditional packages, which may get installed.'), ++ thisgroup.groupid, count_cond_test) return txmbrs_used def deselectGroup(self, grpid, force=False): @@ -154390,7 +154463,7 @@ index 99039e0..6401645 100644 if not self.comps.has_group(grpid): raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid) -@@ -3008,7 +3711,8 @@ class YumBase(depsolve.Depsolve): +@@ -3008,7 +3694,8 @@ class YumBase(depsolve.Depsolve): thesegroups = self.comps.return_groups(grpid) if not thesegroups: raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid) @@ -154400,7 +154473,7 @@ index 99039e0..6401645 100644 for thisgroup in thesegroups: thisgroup.selected = False -@@ -3034,13 +3738,102 @@ class YumBase(depsolve.Depsolve): +@@ -3034,13 +3721,102 @@ class YumBase(depsolve.Depsolve): for pkg in self.tsInfo.conditionals.get(txmbr.name, []): self.tsInfo.remove(pkg.pkgtup) @@ -154509,7 +154582,7 @@ index 99039e0..6401645 100644 # look it up in the self.localPackages first: for po in self.localPackages: if po.pkgtup == pkgtup: -@@ -3049,7 +3842,7 @@ class YumBase(depsolve.Depsolve): +@@ -3049,7 +3825,7 @@ class YumBase(depsolve.Depsolve): pkgs = self.pkgSack.searchPkgTuple(pkgtup) if len(pkgs) == 0: @@ -154518,7 +154591,7 @@ index 99039e0..6401645 100644 if allow_missing: # This can happen due to excludes after .up has return None # happened. raise Errors.DepError, _('Package tuple %s could not be found in packagesack') % str(pkgtup) -@@ -3065,13 +3858,21 @@ class YumBase(depsolve.Depsolve): +@@ -3065,13 +3841,21 @@ class YumBase(depsolve.Depsolve): return result def getInstalledPackageObject(self, pkgtup): @@ -154545,7 +154618,7 @@ index 99039e0..6401645 100644 raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup) # Dito. FIXME from getPackageObject() for len() > 1 ... :) -@@ -3079,9 +3880,11 @@ class YumBase(depsolve.Depsolve): +@@ -3079,9 +3863,11 @@ class YumBase(depsolve.Depsolve): return po def gpgKeyCheck(self): @@ -154559,7 +154632,7 @@ index 99039e0..6401645 100644 gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum' if os.path.exists(gpgkeyschecked): return 1 -@@ -3106,9 +3909,13 @@ class YumBase(depsolve.Depsolve): +@@ -3106,9 +3892,13 @@ class YumBase(depsolve.Depsolve): return 1 def returnPackagesByDep(self, depstring): @@ -154575,7 +154648,7 @@ index 99039e0..6401645 100644 if not depstring: return [] -@@ -3135,9 +3942,16 @@ class YumBase(depsolve.Depsolve): +@@ -3135,9 +3925,16 @@ class YumBase(depsolve.Depsolve): return self.pkgSack.getProvides(depname, depflags, depver).keys() def returnPackageByDep(self, depstring): @@ -154595,7 +154668,7 @@ index 99039e0..6401645 100644 # we get all sorts of randomness here errstring = depstring if type(depstring) not in types.StringTypes: -@@ -3149,16 +3963,22 @@ class YumBase(depsolve.Depsolve): +@@ -3149,16 +3946,22 @@ class YumBase(depsolve.Depsolve): raise Errors.YumBaseError, _('No Package found for %s') % errstring ps = ListPackageSack(pkglist) @@ -154622,7 +154695,7 @@ index 99039e0..6401645 100644 if not depstring: return [] -@@ -3184,12 +4004,47 @@ class YumBase(depsolve.Depsolve): +@@ -3184,12 +3987,47 @@ class YumBase(depsolve.Depsolve): return self.rpmdb.getProvides(depname, depflags, depver).keys() @@ -154672,7 +154745,7 @@ index 99039e0..6401645 100644 if len(pkglist) == 0: -@@ -3198,14 +4053,23 @@ class YumBase(depsolve.Depsolve): +@@ -3198,14 +4036,23 @@ class YumBase(depsolve.Depsolve): if len(pkglist) == 1: return pkglist[0] @@ -154702,7 +154775,7 @@ index 99039e0..6401645 100644 returnlist = [] compatArchList = self.arch.get_arch_list(arch) multiLib = [] -@@ -3222,9 +4086,9 @@ class YumBase(depsolve.Depsolve): +@@ -3222,9 +4069,9 @@ class YumBase(depsolve.Depsolve): singleLib.append(po) # we now have three lists. find the best package(s) of each @@ -154715,7 +154788,7 @@ index 99039e0..6401645 100644 if single_name and multi and single and multi.name != single.name: # Sinlge _must_ match multi, if we want a single package name -@@ -3238,7 +4102,7 @@ class YumBase(depsolve.Depsolve): +@@ -3238,7 +4085,7 @@ class YumBase(depsolve.Depsolve): # if there's a noarch and it's newer than the multilib, we want # just the noarch. otherwise, we want multi + single elif multi: @@ -154724,7 +154797,7 @@ index 99039e0..6401645 100644 if best.arch == "noarch": returnlist.append(no) else: -@@ -3246,7 +4110,7 @@ class YumBase(depsolve.Depsolve): +@@ -3246,7 +4093,7 @@ class YumBase(depsolve.Depsolve): if single: returnlist.append(single) # similar for the non-multilib case elif single: @@ -154733,7 +154806,7 @@ index 99039e0..6401645 100644 if best.arch == "noarch": returnlist.append(no) else: -@@ -3350,28 +4214,58 @@ class YumBase(depsolve.Depsolve): +@@ -3350,28 +4197,58 @@ class YumBase(depsolve.Depsolve): done = True slow = next_func(slow) @@ -154797,7 +154870,7 @@ index 99039e0..6401645 100644 try: txmbrs = self.groupRemove(group_string) except yum.Errors.GroupsError: -@@ -3387,6 +4281,8 @@ class YumBase(depsolve.Depsolve): +@@ -3387,6 +4264,8 @@ class YumBase(depsolve.Depsolve): assert pattern[0] == '@' grpid = pattern[1:] @@ -154806,7 +154879,7 @@ index 99039e0..6401645 100644 thesegroups = self.comps.return_groups(grpid) if not thesegroups: raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid) -@@ -3398,7 +4294,11 @@ class YumBase(depsolve.Depsolve): +@@ -3398,7 +4277,11 @@ class YumBase(depsolve.Depsolve): def _minus_deselect(self, pattern): """ Remove things from the transaction, like kickstart. """ assert pattern[0] == '-' @@ -154819,7 +154892,7 @@ index 99039e0..6401645 100644 if pat and pat[0] == '@': pat = pat[1:] -@@ -3437,14 +4337,87 @@ class YumBase(depsolve.Depsolve): +@@ -3437,14 +4320,87 @@ class YumBase(depsolve.Depsolve): if flag not in self.tsInfo.probFilterFlags: self.tsInfo.probFilterFlags.append(flag) @@ -154913,7 +154986,7 @@ index 99039e0..6401645 100644 pkgs = [] was_pattern = False if po: -@@ -3477,20 +4450,12 @@ class YumBase(depsolve.Depsolve): +@@ -3477,20 +4433,12 @@ class YumBase(depsolve.Depsolve): self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'), arg) @@ -154940,7 +155013,7 @@ index 99039e0..6401645 100644 else: nevra_dict = self._nevra_kwarg_parse(kwargs) -@@ -3577,17 +4542,20 @@ class YumBase(depsolve.Depsolve): +@@ -3577,17 +4525,20 @@ class YumBase(depsolve.Depsolve): continue # make sure this shouldn't be passed to update: @@ -154964,7 +155037,7 @@ index 99039e0..6401645 100644 obsoleting_pkg = self._test_loop(po, self._pkg2obspkg) if obsoleting_pkg is not None: # this is not a definitive check but it'll make sure we don't -@@ -3600,23 +4568,23 @@ class YumBase(depsolve.Depsolve): +@@ -3600,23 +4551,23 @@ class YumBase(depsolve.Depsolve): already_obs = pkgs[0] if already_obs: @@ -154995,7 +155068,7 @@ index 99039e0..6401645 100644 continue # make sure we don't have a name.arch of this already installed -@@ -3630,7 +4598,7 @@ class YumBase(depsolve.Depsolve): +@@ -3630,7 +4581,7 @@ class YumBase(depsolve.Depsolve): found = True break if not found: @@ -155004,7 +155077,7 @@ index 99039e0..6401645 100644 txmbrs = self.update(po=po) tx_return.extend(txmbrs) continue -@@ -3719,19 +4687,47 @@ class YumBase(depsolve.Depsolve): +@@ -3719,19 +4670,47 @@ class YumBase(depsolve.Depsolve): return txmbr def update(self, po=None, requiringPo=None, update_to=False, **kwargs): @@ -155059,7 +155132,7 @@ index 99039e0..6401645 100644 tx_return = [] if not po and not kwargs: # update everything (the easy case) self.verbose_logger.log(logginglevels.DEBUG_2, _('Updating Everything')) -@@ -3765,7 +4761,14 @@ class YumBase(depsolve.Depsolve): +@@ -3765,7 +4744,14 @@ class YumBase(depsolve.Depsolve): if new is None: continue tx_return.extend(self.update(po=new)) @@ -155075,7 +155148,7 @@ index 99039e0..6401645 100644 return tx_return # complications -@@ -3787,7 +4790,7 @@ class YumBase(depsolve.Depsolve): +@@ -3787,7 +4773,7 @@ class YumBase(depsolve.Depsolve): return self._minus_deselect(kwargs['pattern']) if kwargs['pattern'] and kwargs['pattern'][0] == '@': @@ -155084,7 +155157,7 @@ index 99039e0..6401645 100644 arg = kwargs['pattern'] if not update_to: -@@ -3843,7 +4846,7 @@ class YumBase(depsolve.Depsolve): +@@ -3843,7 +4829,7 @@ class YumBase(depsolve.Depsolve): availpkgs = self._compare_providers(availpkgs, requiringPo) availpkgs = map(lambda x: x[0], availpkgs) elif not availpkgs: @@ -155093,7 +155166,7 @@ index 99039e0..6401645 100644 # for any thing specified # get the list of available pkgs matching it (or take the po) -@@ -3920,6 +4923,21 @@ class YumBase(depsolve.Depsolve): +@@ -3920,6 +4906,21 @@ class YumBase(depsolve.Depsolve): tx_return.append(txmbr) for available_pkg in availpkgs: @@ -155115,7 +155188,7 @@ index 99039e0..6401645 100644 # Make sure we're not installing a package which is obsoleted by # something else in the repo. Unless there is a obsoletion loop, # at which point ignore everything. -@@ -3985,11 +5003,18 @@ class YumBase(depsolve.Depsolve): +@@ -3985,11 +4986,18 @@ class YumBase(depsolve.Depsolve): return tx_return def remove(self, po=None, **kwargs): @@ -155139,7 +155212,7 @@ index 99039e0..6401645 100644 if not po and not kwargs: raise Errors.RemoveError, 'Nothing specified to remove' -@@ -4055,17 +5080,19 @@ class YumBase(depsolve.Depsolve): +@@ -4055,17 +5063,19 @@ class YumBase(depsolve.Depsolve): return tx_return def installLocal(self, pkg, po=None, updateonly=False): @@ -155169,7 +155242,7 @@ index 99039e0..6401645 100644 # read in the package into a YumLocalPackage Object # append it to self.localPackages # check if it can be installed or updated based on nevra versus rpmdb -@@ -4183,16 +5210,15 @@ class YumBase(depsolve.Depsolve): +@@ -4183,16 +5193,15 @@ class YumBase(depsolve.Depsolve): return tx_return def reinstallLocal(self, pkg, po=None): @@ -155194,7 +155267,7 @@ index 99039e0..6401645 100644 if not po: try: po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg, -@@ -4215,9 +5241,19 @@ class YumBase(depsolve.Depsolve): +@@ -4215,9 +5224,19 @@ class YumBase(depsolve.Depsolve): return self.reinstall(po=po) def reinstall(self, po=None, **kwargs): @@ -155217,7 +155290,7 @@ index 99039e0..6401645 100644 self._add_prob_flags(rpm.RPMPROB_FILTER_REPLACEPKG, rpm.RPMPROB_FILTER_REPLACENEWFILES, rpm.RPMPROB_FILTER_REPLACEOLDFILES) -@@ -4259,16 +5295,15 @@ class YumBase(depsolve.Depsolve): +@@ -4259,16 +5278,15 @@ class YumBase(depsolve.Depsolve): return tx_mbrs def downgradeLocal(self, pkg, po=None): @@ -155242,7 +155315,7 @@ index 99039e0..6401645 100644 if not po: try: po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg, -@@ -4309,13 +5344,19 @@ class YumBase(depsolve.Depsolve): +@@ -4309,13 +5327,19 @@ class YumBase(depsolve.Depsolve): return False def downgrade(self, po=None, **kwargs): @@ -155269,7 +155342,7 @@ index 99039e0..6401645 100644 if not po and not kwargs: raise Errors.DowngradeError, 'Nothing specified to downgrade' -@@ -4397,6 +5438,10 @@ class YumBase(depsolve.Depsolve): +@@ -4397,6 +5421,10 @@ class YumBase(depsolve.Depsolve): # installed version. Indexed fromn the latest installed pkgtup. downgrade_apkgs = {} for pkg in sorted(apkgs): @@ -155280,7 +155353,7 @@ index 99039e0..6401645 100644 na = (pkg.name, pkg.arch) # Here we allow downgrades from .i386 => .noarch, or .i586 => .i386 -@@ -4421,6 +5466,9 @@ class YumBase(depsolve.Depsolve): +@@ -4421,6 +5449,9 @@ class YumBase(depsolve.Depsolve): warned_nas.add(na) continue @@ -155290,7 +155363,7 @@ index 99039e0..6401645 100644 if pkg.verGE(lipkg): if na not in warned_nas: msg = _('Only Upgrade available on package: %s') % pkg -@@ -4457,7 +5505,7 @@ class YumBase(depsolve.Depsolve): +@@ -4457,7 +5488,7 @@ class YumBase(depsolve.Depsolve): if e and v and r: evr = '%s:%s-%s' % (e, v, r) elif v and r: @@ -155299,7 +155372,7 @@ index 99039e0..6401645 100644 elif e and v: evr = '%s:%s' % (e, v) elif v: # e and r etc. is just too weird to print -@@ -4500,12 +5548,24 @@ class YumBase(depsolve.Depsolve): +@@ -4500,12 +5531,24 @@ class YumBase(depsolve.Depsolve): return returndict @@ -155327,7 +155400,7 @@ index 99039e0..6401645 100644 old_conf_obs = self.conf.obsoletes self.conf.obsoletes = False done = False -@@ -4515,19 +5575,46 @@ class YumBase(depsolve.Depsolve): +@@ -4515,19 +5558,46 @@ class YumBase(depsolve.Depsolve): done = True for pkg in transaction.trans_data: if pkg.state == 'Downgrade': @@ -155374,7 +155447,7 @@ index 99039e0..6401645 100644 if self.install(pkgtup=pkg.pkgtup): done = True for pkg in transaction.trans_data: -@@ -4538,8 +5625,14 @@ class YumBase(depsolve.Depsolve): +@@ -4538,8 +5608,14 @@ class YumBase(depsolve.Depsolve): return done def history_undo(self, transaction): @@ -155391,7 +155464,7 @@ index 99039e0..6401645 100644 # NOTE: This is somewhat basic atm. ... for instance we don't check # that we are going from the old new version. However it's still # better than the RHN rollback code, and people pay for that :). -@@ -4616,7 +5709,7 @@ class YumBase(depsolve.Depsolve): +@@ -4616,7 +5692,7 @@ class YumBase(depsolve.Depsolve): except urlgrabber.grabber.URLGrabError, e: raise Errors.YumBaseError(_('GPG key retrieval failed: ') + @@ -155400,7 +155473,7 @@ index 99039e0..6401645 100644 # check for a .asc file accompanying it - that's our gpg sig on the key # suck it down and do the check -@@ -4649,7 +5742,7 @@ class YumBase(depsolve.Depsolve): +@@ -4649,7 +5725,7 @@ class YumBase(depsolve.Depsolve): keys_info = misc.getgpgkeyinfo(rawkey, multiple=True) except ValueError, e: raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') % @@ -155409,7 +155482,7 @@ index 99039e0..6401645 100644 keys = [] for keyinfo in keys_info: thiskey = {} -@@ -4674,39 +5767,49 @@ class YumBase(depsolve.Depsolve): +@@ -4674,39 +5750,49 @@ class YumBase(depsolve.Depsolve): if pkgs: pkgs = sorted(pkgs)[-1] msg = (_('Importing %s key 0x%s:\n' @@ -155477,7 +155550,7 @@ index 99039e0..6401645 100644 user_cb_fail = False for keyurl in keyurls: keys = self._retrievePublicKey(keyurl, repo) -@@ -4725,7 +5828,9 @@ class YumBase(depsolve.Depsolve): +@@ -4725,7 +5811,9 @@ class YumBase(depsolve.Depsolve): # Try installing/updating GPG key self._getKeyImportMessage(info, keyurl) rc = False @@ -155488,7 +155561,7 @@ index 99039e0..6401645 100644 rc = True # grab the .sig/.asc for the keyurl, if it exists -@@ -4751,8 +5856,8 @@ class YumBase(depsolve.Depsolve): +@@ -4751,8 +5839,8 @@ class YumBase(depsolve.Depsolve): ts = self.rpmdb.readOnlyTS() result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key'])) if result != 0: @@ -155499,7 +155572,7 @@ index 99039e0..6401645 100644 self.logger.info(_('Key imported successfully')) key_installed = True -@@ -4760,18 +5865,20 @@ class YumBase(depsolve.Depsolve): +@@ -4760,18 +5848,20 @@ class YumBase(depsolve.Depsolve): raise Errors.YumBaseError, _("Didn't install any keys") if not key_installed: @@ -155525,7 +155598,7 @@ index 99039e0..6401645 100644 def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None): """ -@@ -4788,6 +5895,18 @@ class YumBase(depsolve.Depsolve): +@@ -4788,6 +5878,18 @@ class YumBase(depsolve.Depsolve): """ key_installed = False @@ -155544,7 +155617,7 @@ index 99039e0..6401645 100644 user_cb_fail = False for keyurl in keyurl_list: keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey) -@@ -4819,8 +5938,11 @@ class YumBase(depsolve.Depsolve): +@@ -4819,8 +5921,11 @@ class YumBase(depsolve.Depsolve): if not key_installed: self._getKeyImportMessage(info, keyurl, keytype) rc = False @@ -155557,7 +155630,7 @@ index 99039e0..6401645 100644 elif callback: rc = callback({"repo": repo, "userid": info['userid'], "hexkeyid": info['hexkeyid'], "keyurl": keyurl, -@@ -4835,7 +5957,8 @@ class YumBase(depsolve.Depsolve): +@@ -4835,7 +5940,8 @@ class YumBase(depsolve.Depsolve): # Import the key result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir) if not result: @@ -155567,7 +155640,7 @@ index 99039e0..6401645 100644 self.logger.info(_('Key imported successfully')) key_installed = True # write out the key id to imported_cakeys in the repos basedir -@@ -4851,36 +5974,35 @@ class YumBase(depsolve.Depsolve): +@@ -4851,36 +5957,35 @@ class YumBase(depsolve.Depsolve): pass if not key_installed and user_cb_fail: @@ -155620,16 +155693,30 @@ index 99039e0..6401645 100644 self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback) def _limit_installonly_pkgs(self): -@@ -4927,6 +6049,7 @@ class YumBase(depsolve.Depsolve): +@@ -4889,7 +5994,7 @@ class YumBase(depsolve.Depsolve): + New in 3.2.24: Obey yumdb_info.installonly data. """ + + def _sort_and_filter_installonly(pkgs): +- """ Allow the admin to specify some overrides fo installonly pkgs. ++ """ Allow the admin to specify some overrides for installonly pkgs. + using the yumdb. """ + ret_beg = [] + ret_mid = [] +@@ -4926,23 +6031,30 @@ class YumBase(depsolve.Depsolve): + # so self.rpmdb.ts should be valid. ts = self.rpmdb.readOnlyTS() (cur_kernel_v, cur_kernel_r) = misc.get_running_kernel_version_release(ts) - install_only_names = set(self.conf.installonlypkgs) +- install_only_names = set(self.conf.installonlypkgs) + found = {} for m in self.tsInfo.getMembers(): if m.ts_state not in ('i', 'u'): continue -@@ -4937,12 +6060,21 @@ class YumBase(depsolve.Depsolve): - if not po_names.intersection(install_only_names): + if m.reinstall: + continue +- +- po_names = set([m.name] + m.po.provides_names) +- if not po_names.intersection(install_only_names): ++ if not self.allowedMultipleInstalls(m.po): continue - installed = self.rpmdb.searchNevra(name=m.name) @@ -155654,7 +155741,7 @@ index 99039e0..6401645 100644 for po in installed: if (po.version, po.release) == (cur_kernel_v, cur_kernel_r): # don't remove running -@@ -4959,19 +6091,22 @@ class YumBase(depsolve.Depsolve): +@@ -4959,19 +6071,22 @@ class YumBase(depsolve.Depsolve): txmbr.depends_on.append(rel) def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None): @@ -155690,7 +155777,7 @@ index 99039e0..6401645 100644 if not callback: callback = callbacks.ProcessTransNoOutputCallback() -@@ -5114,13 +6249,19 @@ class YumBase(depsolve.Depsolve): +@@ -5114,13 +6229,19 @@ class YumBase(depsolve.Depsolve): return results def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs): @@ -155717,7 +155804,7 @@ index 99039e0..6401645 100644 # out of place fixme - maybe we should make this the default repo addition # routine and use it from getReposFromConfigFile(), etc. newrepo = yumRepo.YumRepository(repoid) -@@ -5167,9 +6308,15 @@ class YumBase(depsolve.Depsolve): +@@ -5167,9 +6288,15 @@ class YumBase(depsolve.Depsolve): def setCacheDir(self, force=False, tmpdir=None, reuse=True, suffix='/$basearch/$releasever'): @@ -155736,7 +155823,7 @@ index 99039e0..6401645 100644 if not force and os.geteuid() == 0: return True # We are root, not forced, so happy with the global dir. if tmpdir is None: -@@ -5179,7 +6326,7 @@ class YumBase(depsolve.Depsolve): +@@ -5179,7 +6306,7 @@ class YumBase(depsolve.Depsolve): try: cachedir = misc.getCacheDir(tmpdir, reuse) except (IOError, OSError), e: @@ -155745,7 +155832,7 @@ index 99039e0..6401645 100644 cachedir = None if cachedir is None: -@@ -5190,6 +6337,7 @@ class YumBase(depsolve.Depsolve): +@@ -5190,6 +6317,7 @@ class YumBase(depsolve.Depsolve): self.prerepoconf.cachedir = cachedir else: self.repos.setCacheDir(cachedir) @@ -155753,7 +155840,7 @@ index 99039e0..6401645 100644 self.conf.cachedir = cachedir return True # We got a new cache dir -@@ -5220,13 +6368,24 @@ class YumBase(depsolve.Depsolve): +@@ -5220,13 +6348,24 @@ class YumBase(depsolve.Depsolve): self.history.write_addon_data('config-repos', myrepos) def verify_plugins_cb(self, verify_package): @@ -155781,7 +155868,7 @@ index 99039e0..6401645 100644 if self.tsInfo._unresolvedMembers: if auto: self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction.")) -@@ -5234,7 +6393,7 @@ class YumBase(depsolve.Depsolve): +@@ -5234,7 +6373,7 @@ class YumBase(depsolve.Depsolve): raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction.")) if not filename: @@ -155790,7 +155877,7 @@ index 99039e0..6401645 100644 fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix) f = os.fdopen(fd, 'w') else: -@@ -5244,13 +6403,17 @@ class YumBase(depsolve.Depsolve): +@@ -5244,13 +6383,17 @@ class YumBase(depsolve.Depsolve): msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0] msg += "%s\n" % self.ts.getTsFlags() @@ -155811,7 +155898,7 @@ index 99039e0..6401645 100644 msg += "%s\n" % len(self.tsInfo.getMembers()) for txmbr in self.tsInfo.getMembers(): msg += txmbr._dump() -@@ -5260,13 +6423,25 @@ class YumBase(depsolve.Depsolve): +@@ -5260,13 +6403,25 @@ class YumBase(depsolve.Depsolve): except (IOError, OSError), e: self._ts_save_file = None if auto: @@ -155843,7 +155930,7 @@ index 99039e0..6401645 100644 # check rpmversion - if not match throw a fit # check repoversions (and repos)- if not match throw a fit # load each txmbr - if pkgs being updated don't exist, bail w/error -@@ -5276,26 +6451,45 @@ class YumBase(depsolve.Depsolve): +@@ -5276,26 +6431,45 @@ class YumBase(depsolve.Depsolve): try: data = open(filename, 'r').readlines() except (IOError, OSError), e: @@ -155891,7 +155978,7 @@ index 99039e0..6401645 100644 if ignorerpm: msg += _(" ignoring, as requested.") self.logger.critical(_(msg)) -@@ -5318,8 +6512,17 @@ class YumBase(depsolve.Depsolve): +@@ -5318,8 +6492,17 @@ class YumBase(depsolve.Depsolve): numrepos = int(data[2].strip()) repos = [] rindex=3+numrepos @@ -155910,7 +155997,7 @@ index 99039e0..6401645 100644 # pkgs/txmbrs numpkgs = int(data[rindex].strip()) -@@ -5329,6 +6532,7 @@ class YumBase(depsolve.Depsolve): +@@ -5329,6 +6512,7 @@ class YumBase(depsolve.Depsolve): pkgcount = 0 pkgprob = False curpkg = None @@ -155918,7 +156005,7 @@ index 99039e0..6401645 100644 for l in data[pkgstart:]: l = l.rstrip() # our main txmbrs -@@ -5356,6 +6560,7 @@ class YumBase(depsolve.Depsolve): +@@ -5356,6 +6540,7 @@ class YumBase(depsolve.Depsolve): if not ignoremissing: raise Errors.YumBaseError(msg) else: @@ -155926,7 +156013,7 @@ index 99039e0..6401645 100644 self.logger.critical(msg) else: pkgcount += 1 -@@ -5432,12 +6637,18 @@ class YumBase(depsolve.Depsolve): +@@ -5432,12 +6617,18 @@ class YumBase(depsolve.Depsolve): if pkgprob: msg = _("Transaction members, relations are missing or ts has been modified,") if ignoremissing: @@ -155945,7 +156032,7 @@ index 99039e0..6401645 100644 return self.tsInfo.getMembers() def _remove_old_deps(self): -@@ -5470,18 +6681,6 @@ class YumBase(depsolve.Depsolve): +@@ -5470,18 +6661,6 @@ class YumBase(depsolve.Depsolve): if requiring == required: # if they are self-requiring skip them continue @@ -155964,7 +156051,7 @@ index 99039e0..6401645 100644 #for tbi_pkg in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES): # for reqtuple in tbi_pkg.po.requires: # if required.provides_for(reqtuple): -@@ -5533,7 +6732,24 @@ class YumBase(depsolve.Depsolve): +@@ -5533,7 +6712,24 @@ class YumBase(depsolve.Depsolve): # Debugging output self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has revdep %s which was user-installed."), pkg, curpkg) ok_to_remove[pkg] = False @@ -155989,7 +156076,7 @@ index 99039e0..6401645 100644 visited[curpkg] = True all_leaves_visited = True leaves = curpkg.requiring_packages() -@@ -5547,4 +6763,3 @@ class YumBase(depsolve.Depsolve): +@@ -5547,4 +6743,3 @@ class YumBase(depsolve.Depsolve): # Debugging output self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg) return False @@ -156142,9 +156229,27 @@ index 7ad25ce..a9a8e53 100644 pass diff --git a/yum/comps.py b/yum/comps.py -index 65f6d5e..4e765ef 100755 +index 65f6d5e..fe5649d 100755 --- a/yum/comps.py +++ b/yum/comps.py +@@ -16,14 +16,14 @@ + + import types + import sys +-from constants import * +-from Errors import CompsException ++from yum.constants import * ++from yum.Errors import CompsException + #FIXME - compsexception isn't caught ANYWHERE so it's pointless to raise it + # switch all compsexceptions to grouperrors after api break + import fnmatch + import re + from yum.i18n import to_unicode +-from misc import get_my_lang_code ++from yum.misc import get_my_lang_code + from yum.misc import cElementTree_iterparse as iterparse + + lang_attr = '{http://www.w3.org/XML/1998/namespace}lang' @@ -43,6 +43,16 @@ class CompsObj(object): return self.name @@ -156171,9 +156276,9 @@ index 65f6d5e..4e765ef 100755 self.groupid = None self.display_order = 1024 self.installed = False -@@ -272,6 +282,137 @@ class Group(CompsObj): - return msg +@@ -271,6 +281,136 @@ class Group(CompsObj): + return msg +class Environment(CompsObj): + """ Environment object parsed from group data in each repo, and merged """ @@ -156305,22 +156410,78 @@ index 65f6d5e..4e765ef 100755 + msg += """ \n""" + + return msg -+ + class Category(CompsObj): """ Category object parsed from group data in each repo. and merged. """ +@@ -371,12 +511,61 @@ class Category(CompsObj): + msg += """ \n""" + + return msg +- ++ ++class Langpacks(CompsObj): ++ def __init__(self, elem=None): ++ self.langpacks = [] ++ self.name = "" # prevent CompsObj.__str__() throwing an AttributeError ++ if elem is not None: ++ self.parse(elem) ++ ++ def __getitem__(self, indx): ++ return self.langpacks[indx] ++ ++ def __iter__(self): ++ for i in self.langpacks: ++ yield i ++ ++ def __len__(self): ++ return len(self.langpacks) ++ ++ def add(self, name, install): ++ langpack = { ++ "name": name, ++ "install": install, ++ } ++ self.langpacks.append(langpack) ++ ++ def parse(self, elem): ++ for child in elem: ++ if child.tag == "match": ++ langpack = { ++ "name": child.attrib.get("name"), ++ "install": child.attrib.get("install"), ++ } ++ self.langpacks.append(langpack) ++ else: ++ raise CompsException("Unexpected element in : %s" % child.tag) ++ ++ self.name = elem.attrib.get("name") ++ self.install = elem.attrib.get("install") ++ ++ def xml(self): ++ """write out an xml stanza for the Langpacks object""" ++ if not self.langpacks: ++ return '' ++ msg = ' \n' ++ for i in self: ++ msg += ' \n' % (i["name"], i["install"]) ++ msg += ' \n' ++ return msg -@@ -376,6 +517,7 @@ class Category(CompsObj): class Comps(object): def __init__(self, overwrite_groups=False): self._groups = {} + self._environments = {} self._categories = {} ++ self._langpacks = Langpacks() self.compscount = 0 self.overwrite_groups = overwrite_groups -@@ -388,12 +530,18 @@ class Comps(object): + self.compiled = False # have groups been compiled into avail/installed +@@ -387,14 +576,24 @@ class Comps(object): + grps = self._groups.values() grps.sort(key=lambda x: (x.display_order, x.name)) return grps - +- ++ + def get_environments(self): + environments = self._environments.values() + environments.sort(key=lambda x: (x.display_order, x.name)) @@ -156330,13 +156491,18 @@ index 65f6d5e..4e765ef 100755 cats = self._categories.values() cats.sort(key=lambda x: (x.display_order, x.name)) return cats ++ ++ def get_langpacks(self): ++ return self._langpacks groups = property(get_groups) + environments = property(get_environments) categories = property(get_categories) ++ langpacks = property(get_langpacks) def has_group(self, grpid): -@@ -447,6 +595,57 @@ class Comps(object): + exists = self.return_groups(grpid) +@@ -447,6 +646,57 @@ class Comps(object): return returns.values() @@ -156394,7 +156560,7 @@ index 65f6d5e..4e765ef 100755 # This is close to returnPackages() etc. API ... need to std. these names # the above return_groups uses different, but equal, API. def return_categories(self, pattern, ignore_case=True): -@@ -490,6 +689,13 @@ class Comps(object): +@@ -490,6 +740,13 @@ class Comps(object): else: self._groups[group.groupid] = group @@ -156408,7 +156574,17 @@ index 65f6d5e..4e765ef 100755 def add_category(self, category): if category.categoryid in self._categories: thatcat = self._categories[category.categoryid] -@@ -520,6 +726,9 @@ class Comps(object): +@@ -497,6 +754,9 @@ class Comps(object): + else: + self._categories[category.categoryid] = category + ++ def add_langpack(self, name, install): ++ self._langpacks.add(name, install) ++ + def add(self, srcfile = None): + if not srcfile: + raise CompsException +@@ -520,9 +780,14 @@ class Comps(object): if elem.tag == "group": group = Group(elem) self.add_group(group) @@ -156418,7 +156594,12 @@ index 65f6d5e..4e765ef 100755 if elem.tag == "category": category = Category(elem) self.add_category(category) -@@ -557,13 +766,32 @@ class Comps(object): ++ if elem.tag == "langpacks": ++ self._langpacks.parse(elem) + except SyntaxError, e: + raise CompsException, "comps file is empty/damaged" + +@@ -557,13 +822,32 @@ class Comps(object): if pkgname in inst_pkg_names: group.installed = True break @@ -156448,33 +156629,60 @@ index 65f6d5e..4e765ef 100755 - if not self._groups and not self._categories: + if not self._groups and not self._categories and \ -+ not self._environments: ++ not self._environments and not len(self._langpacks): return "" msg = """ -@@ -575,6 +803,8 @@ class Comps(object): +@@ -575,7 +859,9 @@ class Comps(object): msg += g.xml() for c in self.get_categories(): msg += c.xml() +- + for e in self.get_environments(): + msg += e.xml() - ++ msg += self.get_langpacks().xml() msg += """\n\n""" -@@ -595,6 +825,13 @@ def main(): + return msg +@@ -590,16 +876,34 @@ def main(): + for srcfile in sys.argv[1:]: + p.add(srcfile) + ++ print ++ print "===== GROUPS =====" + for group in p.groups: +- print group ++ print "%s (id: %s)" % (group, group.groupid) for pkg in group.packages: print ' ' + pkg - +- ++ ++ print ++ print "===== ENVIRONMENTS =====" + for environment in p.environments: -+ print environment.name ++ print "%s (id: %s)" % (environment.name, environment.environmentid) + for group in environment.groups: + print ' ' + group + for group in environment.options: + print ' *' + group + ++ print ++ print "===== CATEGORIES =====" for category in p.categories: - print category.name +- print category.name ++ print "%s (id: %s)" % (category.name, category.categoryid) for group in category.groups: + print ' ' + group +- ++ ++ print ++ print "===== LANGPACKS =====" ++ for langpack in p.langpacks: ++ print ' %s (%s)' % (langpack["name"], langpack["install"]) ++ + except IOError: + print >> sys.stderr, "newcomps.py: No such file:\'%s\'" % sys.argv[1] + sys.exit(1) diff --git a/yum/config.py b/yum/config.py index d09511f..74be397 100644 --- a/yum/config.py @@ -160369,10 +160577,14 @@ index 31b1080..97256c6 100755 tags += """ \n""" msg += tags diff --git a/yum/repos.py b/yum/repos.py -index 3793bad..de5da1e 100644 +index 3793bad..3522512 100644 --- a/yum/repos.py +++ b/yum/repos.py -@@ -22,6 +22,7 @@ import misc +@@ -19,9 +19,11 @@ import fnmatch + import types + import logging + import misc ++import os import Errors from packageSack import MetaSack @@ -160380,7 +160592,7 @@ index 3793bad..de5da1e 100644 from weakref import proxy as weakref -@@ -67,6 +68,47 @@ class RepoStorage: +@@ -67,6 +69,47 @@ class RepoStorage: self._cache_enabled_repos = [] self.quick_enable_disable = {} @@ -160428,7 +160640,25 @@ index 3793bad..de5da1e 100644 def doSetup(self, thisrepo = None): self.ayum.plugins.run('prereposetup') -@@ -87,8 +129,13 @@ class RepoStorage: +@@ -79,6 +122,17 @@ class RepoStorage: + if len(repos) < 1: + self.logger.debug('No Repositories Available to Set Up') + ++ if hasattr(urlgrabber.grabber, 'pycurl'): ++ # Must do basename checking, on cert. files... ++ cert_basenames = {} ++ for repo in self.listEnabled(): ++ if repo.sslclientcert: ++ bn = os.path.basename(repo.sslclientcert) ++ other = cert_basenames.setdefault(bn, repo) ++ if repo.sslclientcert != other.sslclientcert: ++ msg = 'sslclientcert basename shared between %s and %s' ++ raise Errors.ConfigError, msg % (repo, other) ++ + for repo in repos: + repo.setup(self.ayum.conf.cache, self.ayum.mediagrabber, + gpg_import_func = self.gpg_import_func, confirm_func=self.confirm_func, +@@ -87,8 +141,13 @@ class RepoStorage: # so nothing else touches us if not repo.enabled: self.disableRepo(repo.id) @@ -160442,7 +160672,7 @@ index 3793bad..de5da1e 100644 self.ayum.plugins.run('postreposetup') def __str__(self): -@@ -223,15 +270,16 @@ class RepoStorage: +@@ -223,15 +282,16 @@ class RepoStorage: self._cachedir = cachedir for repo in self.repos.values(): @@ -160463,7 +160693,7 @@ index 3793bad..de5da1e 100644 def setFailureCallback(self, obj): """sets the failure callback for all repos""" -@@ -288,6 +336,16 @@ class RepoStorage: +@@ -288,6 +348,16 @@ class RepoStorage: else: data = [ mdtype ] @@ -160826,7 +161056,7 @@ index 8a6f6f3..65401a9 100644 """Returns a list of pkg tuples (n, a, e, v, r), optionally from a single repoid. Note that the packages are always filtered to those diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py -index 4d89d83..e7377bf 100644 +index 4d89d83..2fdd8f0 100644 --- a/yum/transactioninfo.py +++ b/yum/transactioninfo.py @@ -87,7 +87,8 @@ class TransactionData: @@ -160888,7 +161118,16 @@ index 4d89d83..e7377bf 100644 pkgs = [] else: pkgs = self.pkgSack.returnPackages(patterns=[pattern]) -@@ -334,6 +354,8 @@ class TransactionData: +@@ -236,6 +256,8 @@ class TransactionData: + # happens IRL. + return txmember.ts_state in ('u', 'i') and not isinstance(txmember.po, (YumInstalledPackage, YumAvailablePackageSqlite)) + ++ # NOTE: This is a copy of Depsolve.allowedMultipleInstalls() because ++ # we can't get to YumBase from here. Use that as the main/public API. + def _allowedMultipleInstalls(self, po): + """takes a packageObject, returns 1 or 0 depending on if the package + should/can be installed multiple times with different vers +@@ -334,6 +356,8 @@ class TransactionData: self.instgroups = [] self.removedgroups = [] @@ -160897,7 +161136,7 @@ index 4d89d83..e7377bf 100644 self.removed = [] self.installed = [] self.updated = [] -@@ -365,6 +387,10 @@ class TransactionData: +@@ -365,6 +389,10 @@ class TransactionData: for g in txmbr.groups: if g not in self.instgroups: self.instgroups.append(g) @@ -160908,7 +161147,7 @@ index 4d89d83..e7377bf 100644 if txmbr.isDep: self.depinstalled.append(txmbr) else: -@@ -377,6 +403,9 @@ class TransactionData: +@@ -377,6 +405,9 @@ class TransactionData: for g in txmbr.groups: if g not in self.instgroups: self.removedgroups.append(g) @@ -160918,7 +161157,7 @@ index 4d89d83..e7377bf 100644 if txmbr.isDep: self.depremoved.append(txmbr) else: -@@ -402,6 +431,8 @@ class TransactionData: +@@ -402,6 +433,8 @@ class TransactionData: self.depremoved.sort() self.instgroups.sort() self.removedgroups.sort() @@ -160927,7 +161166,7 @@ index 4d89d83..e7377bf 100644 self.reinstalled.sort() self.downgraded.sort() self.failed.sort() -@@ -547,9 +578,10 @@ class TransactionData: +@@ -547,9 +580,10 @@ class TransactionData: return txmbr @@ -160940,7 +161179,7 @@ index 4d89d83..e7377bf 100644 def getNewProvides(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides } -@@ -619,6 +651,12 @@ class TransactionData: +@@ -619,6 +653,12 @@ class TransactionData: """ Return a simple version for the future rpmdb. Works like rpmdb.simpleVersion(main_only=True)[0], but for the state the rpmdb will be in after the transaction. """ @@ -160953,7 +161192,7 @@ index 4d89d83..e7377bf 100644 pkgs = self.rpmdb.returnPackages() _reinstalled_pkgtups = {} for txmbr in self.getMembersWithState(None, TS_INSTALL_STATES): -@@ -658,6 +696,7 @@ class TransactionData: +@@ -658,6 +698,7 @@ class TransactionData: self.rpmdb.transactionCachePackageChecksums(pkg_checksum_tups) @@ -160961,7 +161200,7 @@ index 4d89d83..e7377bf 100644 return main def findObsoletedByThisMember(self, txmbr): -@@ -752,6 +791,7 @@ class TransactionMember: +@@ -752,6 +793,7 @@ class TransactionMember: self.downgraded_by = [] self.reinstall = False self.groups = [] # groups it's in @@ -160969,7 +161208,7 @@ index 4d89d83..e7377bf 100644 self._poattr = ['pkgtup', 'repoid', 'name', 'arch', 'epoch', 'version', 'release'] -@@ -825,5 +865,7 @@ class TransactionMember: +@@ -825,5 +867,7 @@ class TransactionMember: if self.groups: msg += " groups: %s\n" % ' '.join(self.groups) @@ -160978,21 +161217,25 @@ index 4d89d83..e7377bf 100644 return msg diff --git a/yum/update_md.py b/yum/update_md.py -index 2cb1acb..0586c1c 100644 +index 2cb1acb..d719be8 100644 --- a/yum/update_md.py +++ b/yum/update_md.py -@@ -79,11 +79,31 @@ class UpdateNotice(object): +@@ -79,11 +79,37 @@ class UpdateNotice(object): def __getitem__(self, item): """ Allows scriptable metadata access (ie: un['update_id']). """ +- return self._md.get(item) or None + if type(item) is int: + return sorted(self._md)[item] - return self._md.get(item) or None - ++ ret = self._md.get(item) ++ if ret == '': ++ ret = None ++ return ret ++ + def __contains__(self, item): + """ Allows quick tests for foo in blah. """ + return item in self._md -+ + def __setitem__(self, item, val): self._md[item] = val @@ -161010,10 +161253,33 @@ index 2cb1acb..0586c1c 100644 + return False + return True + ++ def __ne__(self, other): ++ return not (self == other) ++ def text(self, skip_data=('files', 'summary', 'rights', 'solution')): head = """ =============================================================================== -@@ -423,9 +443,42 @@ class UpdateMetadata(object): +@@ -304,7 +330,9 @@ class UpdateNotice(object): + to_xml(self._md['title']), to_xml(self._md['release']), + to_xml(self._md['issued'], attrib=True), + to_xml(self._md['description'])) +- ++ if self._md['updated']: ++ # include the updated date in the generated xml ++ msg += """ \n""" % (to_xml(self._md['updated'], attrib=True)) + if self._md['summary']: + msg += """ %s\n""" % (to_xml(self._md['summary'])) + if self._md['solution']: +@@ -345,7 +373,7 @@ class UpdateNotice(object): + to_xml(pkg['version'], attrib=True), + to_xml(pkg['filename'])) + msg += """ \n""" +- msg += """ \n""" ++ msg += """ \n""" + msg += """\n""" + return msg + +@@ -423,9 +451,42 @@ class UpdateMetadata(object): def add_notice(self, un): """ Add an UpdateNotice object. This should be fully populated with data, esp. update_id and pkglist/packages. """ @@ -164457,7 +164723,7 @@ index 4dcbea7..a2e0b1b 100644 return True diff --git a/yummain.py b/yummain.py -index 9f79f4f..648cf86 100755 +index 9f79f4f..a9f001b 100755 --- a/yummain.py +++ b/yummain.py @@ -29,13 +29,13 @@ from yum import Errors @@ -164469,7 +164735,7 @@ index 9f79f4f..648cf86 100755 import yum.misc import cli -from utils import suppress_keyboard_interrupt_message, show_lock_owner, exception2msg -+from utils import suppress_keyboard_interrupt_message, show_lock_owner ++from utils import suppress_keyboard_interrupt_message def main(args): - """This does all the real work""" @@ -164501,9 +164767,12 @@ index 9f79f4f..648cf86 100755 # our core object for the cli base = cli.YumBaseCli() -@@ -101,17 +118,6 @@ def main(args): +@@ -100,41 +117,10 @@ def main(args): + return exPluginExit(e) except Errors.YumBaseError, e: return exFatal(e) ++ except (OSError, IOError), e: ++ return exIOError(e) - # Try to open the current directory to see if we have - # read and write access. If not, chdir to / @@ -164516,13 +164785,14 @@ index 9f79f4f..648cf86 100755 - else: - close(f) - - lockerr = "" - while True: - try: -@@ -120,16 +126,14 @@ def main(args): - if exception2msg(e) != lockerr: - lockerr = exception2msg(e) - logger.critical(lockerr) +- lockerr = "" +- while True: +- try: +- base.doLock() +- except Errors.LockError, e: +- if exception2msg(e) != lockerr: +- lockerr = exception2msg(e) +- logger.critical(lockerr) - if (e.errno not in (errno.EPERM, errno.EACCES) and - not base.conf.exit_on_lock): - logger.critical(_("Another app is currently holding the yum lock; waiting for it to exit...")) @@ -164531,18 +164801,18 @@ index 9f79f4f..648cf86 100755 - tm = 2 - time.sleep(tm) - elif e.errno in (errno.EPERM, errno.EACCES): -+ if e.errno in (errno.EPERM, errno.EACCES, errno.ENOSPC): - logger.critical(_("Can't create lock file; exiting")) - return 1 -+ -+ if not base.conf.exit_on_lock: -+ logger.critical(_("Another app is currently holding the yum lock; waiting for it to exit...")) -+ show_lock_owner(e.pid, logger) -+ time.sleep(2) - else: - logger.critical(_("Another app is currently holding the yum lock; exiting as configured by exit_on_lock")) - return 1 -@@ -154,7 +158,7 @@ def main(args): +- logger.critical(_("Can't create lock file; exiting")) +- return 1 +- else: +- logger.critical(_("Another app is currently holding the yum lock; exiting as configured by exit_on_lock")) +- return 1 +- else: +- break ++ base.waitForLock() + + try: + result, resultmsgs = base.doCommands() +@@ -154,7 +140,7 @@ def main(args): for msg in resultmsgs: verbose_logger.log(logginglevels.INFO_2, '%s', msg) if unlock(): return 200 @@ -164551,7 +164821,7 @@ index 9f79f4f..648cf86 100755 elif result == 1: # Fatal error for msg in resultmsgs: -@@ -193,7 +197,7 @@ def main(args): +@@ -193,7 +179,7 @@ def main(args): if result == 0: # Normal exit if unlock(): return 200 @@ -164560,7 +164830,7 @@ index 9f79f4f..648cf86 100755 elif result == 1: # Fatal error for msg in resultmsgs: -@@ -238,16 +242,27 @@ def main(args): +@@ -238,16 +224,27 @@ def main(args): rpmdb_warn_checks() return_code = result if base._ts_save_file: @@ -164590,7 +164860,7 @@ index 9f79f4f..648cf86 100755 import hotshot.stats fn = os.path.expanduser("~/yum.prof") prof = hotshot.Profile(fn) -@@ -257,6 +272,11 @@ def hotshot(func, *args, **kwargs): +@@ -257,6 +254,11 @@ def hotshot(func, *args, **kwargs): return rc def cprof(func, *args, **kwargs): @@ -164602,7 +164872,7 @@ index 9f79f4f..648cf86 100755 import cProfile, pstats fn = os.path.expanduser("~/yum.prof") prof = cProfile.Profile() -@@ -266,6 +286,10 @@ def cprof(func, *args, **kwargs): +@@ -266,6 +268,10 @@ def cprof(func, *args, **kwargs): return rc def print_stats(stats): @@ -164613,7 +164883,7 @@ index 9f79f4f..648cf86 100755 stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats(20) -@@ -273,7 +297,14 @@ def print_stats(stats): +@@ -273,7 +279,14 @@ def print_stats(stats): stats.print_stats(40) def user_main(args, exit_code=False): diff --git a/yum.spec b/yum.spec index 719e0b5..4a0cd5f 100644 --- a/yum.spec +++ b/yum.spec @@ -18,7 +18,7 @@ Summary: RPM package installer/updater/manager Name: yum Version: 3.4.3 -Release: 50%{?dist} +Release: 51%{?dist} License: GPLv2+ Group: System Environment/Base Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz @@ -317,6 +317,17 @@ exit 0 %endif %changelog +* Wed Jan 9 2013 Zdeněk Pavlas - 3.4.3-51 +- update to latest HEAD +- Include langpacks when reading and writing comps. BZ 879030 +- selectGroup(): Fix a typo. BZ 885139 +- move the basename checking into _repos.doSetup(). BZ 885159 +- bash completion: offer nvra for multi-install packages +- fixes extra '' tags on multi-collection errata. BZ 887407 +- Include the update date in updateinfo xml. BZ 887935 +- Complete provides/whatprovides with filenames. BZ 891561 +- New locking code. BZ 865601 + * Thu Dec 06 2012 Zdeněk Pavlas - 3.4.3-50 - update to latest HEAD. - Check for possible inf. recursion and workaround in skip-broken. BZ 874065