[yum/f17] update to latest HEAD
Zdeněk Pavlas
zpavlas at fedoraproject.org
Thu Jun 7 15:44:24 UTC 2012
commit 100fd66aa3e36e43d0fcf57e811db2b95b0ba7b5
Author: Zdeněk Pavlas <zpavlas at redhat.com>
Date: Thu Jun 7 17:42:48 2012 +0200
update to latest HEAD
BZ-809469-completion-helper.patch | 76 --
arm-arch-detection.patch | 104 --
yum-HEAD.patch | 1896 +++++++++++++++++++++++++++++++------
yum-ppc64-preferred.patch | 4 +-
yum.spec | 14 +-
5 files changed, 1598 insertions(+), 496 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index 1fa8c87..1d38d0a 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..afa7447
+index 6056d38..597efd6
--- a/cli.py
+++ b/cli.py
@@ -25,7 +25,7 @@ import sys
@@ -372,8 +372,22 @@ index 6056d38..afa7447
stuff_to_download = True
po = txmbr.po
if po:
-@@ -491,7 +538,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -489,9 +536,21 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+ else:
+ self.reportDownloadSize(downloadpkgs, install_only)
++ cfr = self.tsInfo._check_future_rpmdbv
++ if (cfr is not None and
++ cfr[0] == self.tsInfo.state_counter and
++ self.tsInfo.futureRpmDBVersion() != cfr[1]):
++ msg = _("future rpmdb ver mismatched saved transaction version,")
++ if cfr[2]:
++ msg += _(" ignoring, as requested.")
++ self.logger.critical(_(msg))
++ else:
++ msg += _(" aborting.")
++ raise yum.Errors.YumBaseError(msg)
++
# confirm with user
if self._promptWanted():
- if not self.userconfirm():
@@ -381,7 +395,7 @@ index 6056d38..afa7447
self.verbose_logger.info(_('Exiting on user Command'))
return -1
-@@ -609,12 +656,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -609,12 +668,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return resultobject.return_code
def gpgsigcheck(self, pkgs):
@@ -401,7 +415,7 @@ index 6056d38..afa7447
for po in pkgs:
result, errmsg = self.sigCheckPkg(po)
-@@ -623,7 +672,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -623,7 +684,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
continue
elif result == 1:
@@ -411,7 +425,7 @@ index 6056d38..afa7447
raise yum.Errors.YumBaseError, \
_('Refusing to automatically import keys when running ' \
'unattended.\nUse "-y" to override.')
-@@ -691,12 +741,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -691,12 +753,62 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
", ".join(matches))
self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
@@ -480,7 +494,7 @@ index 6056d38..afa7447
# get the list of available packages
# iterate over the user's list
# add packages to Transaction holding class if they match.
-@@ -710,11 +810,26 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -710,11 +822,26 @@ 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))):
@@ -509,7 +523,7 @@ index 6056d38..afa7447
except yum.Errors.InstallError:
self.verbose_logger.log(yum.logginglevels.INFO_2,
_('No package %s%s%s available.'),
-@@ -723,6 +838,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -723,6 +850,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
self._maybeYouMeant(arg)
else:
done = True
@@ -517,7 +531,7 @@ index 6056d38..afa7447
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 +848,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -732,9 +860,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, [_('Nothing to do')]
def updatePkgs(self, userlist, quiet=0, update_to=False):
@@ -548,7 +562,7 @@ index 6056d38..afa7447
# 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 +879,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -745,21 +891,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
else:
# go through the userlist - look for items that are local rpms. If we find them
@@ -579,7 +593,7 @@ index 6056d38..afa7447
if len(self.tsInfo) > oldcount:
change = len(self.tsInfo) - oldcount
-@@ -770,9 +901,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -770,9 +913,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):
@@ -607,7 +621,7 @@ index 6056d38..afa7447
level = 'diff'
if userlist and userlist[0] in ('full', 'diff', 'different'):
-@@ -831,6 +977,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -831,6 +989,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
continue
nayi = napkg.yumdb_info
@@ -615,7 +629,7 @@ index 6056d38..afa7447
for apkg in self.pkgSack.searchPkgTuple(napkg.pkgtup):
if ('checksum_type' in nayi and
'checksum_data' in nayi and
-@@ -866,10 +1013,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -866,10 +1025,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, [_('No Packages marked for Distribution Synchronization')]
def erasePkgs(self, userlist):
@@ -639,7 +653,7 @@ index 6056d38..afa7447
all_rms = []
for arg in userlist:
-@@ -884,12 +1040,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -884,12 +1052,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, [_('No Packages marked for removal')]
def downgradePkgs(self, userlist):
@@ -667,7 +681,7 @@ index 6056d38..afa7447
for arg in userlist:
if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
os.path.exists(arg))):
-@@ -905,26 +1073,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -905,26 +1085,44 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
self.term.MODE['bold'], arg,
self.term.MODE['normal'])
self._maybeYouMeant(arg)
@@ -716,7 +730,7 @@ index 6056d38..afa7447
except yum.Errors.ReinstallRemoveError:
self._checkMaybeYouMeant(arg, always_output=False)
except yum.Errors.ReinstallInstallError, e:
-@@ -940,15 +1126,31 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -940,15 +1138,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)
@@ -751,7 +765,7 @@ index 6056d38..afa7447
# 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 +1174,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -972,20 +1186,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, [_('Nothing to do')]
def returnPkgLists(self, extcmds, installed_available=False):
@@ -791,7 +805,7 @@ index 6056d38..afa7447
special = ['available', 'installed', 'all', 'extras', 'updates', 'recent',
'obsoletes']
-@@ -1017,8 +1224,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1017,8 +1236,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return ypl
def search(self, args):
@@ -819,7 +833,7 @@ index 6056d38..afa7447
# call the yum module search function with lists of tags to search
# and what to search for
-@@ -1108,9 +1332,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1108,9 +1344,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, matching
def deplist(self, args):
@@ -842,7 +856,7 @@ index 6056d38..afa7447
pkgs = []
for arg in args:
if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
-@@ -1131,10 +1366,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1131,10 +1378,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, []
def provides(self, args):
@@ -866,7 +880,16 @@ index 6056d38..afa7447
old_sdup = self.conf.showdupesfromrepos
# For output, as searchPackageProvides() is always in showdups mode
self.conf.showdupesfromrepos = True
-@@ -1163,20 +1407,77 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1147,6 +1403,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+ paths = set(sys.path + os.environ['PATH'].split(':'))
+ nargs = []
+ for arg in args:
++ if not arg:
++ continue
+ if yum.misc.re_filename(arg) or yum.misc.re_glob(arg):
+ continue
+ for path in paths:
+@@ -1163,20 +1421,77 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, []
def resolveDepCli(self, args):
@@ -949,17 +972,17 @@ index 6056d38..afa7447
hdrcode = pkgcode = xmlcode = dbcode = expccode = 0
pkgresults = hdrresults = xmlresults = dbresults = expcresults = []
msg = self.fmtKeyValFill(_('Cleaning repos: '),
-@@ -1228,7 +1529,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1228,7 +1543,19 @@ 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.
-+
+
+ :param extcmds: a list of names or wildcards specifying
+ groups to list
+ :return: (exit_code, [ errors ])
-
++
+ exit_code is::
+
+ 0 = we're done, exit
@@ -969,7 +992,7 @@ index 6056d38..afa7447
uservisible=1
if len(userlist) > 0:
-@@ -1254,7 +1567,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1254,7 +1581,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
msg += ' (%s)' % group.groupid
if group.langonly:
msg += ' [%s]' % group.langonly
@@ -978,7 +1001,7 @@ index 6056d38..afa7447
done = False
for group in installed:
-@@ -1283,7 +1596,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1283,7 +1610,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, [_('Done')]
def returnGroupSummary(self, userlist):
@@ -989,9 +1012,9 @@ index 6056d38..afa7447
+ groups to summarise. If *userlist* is an empty list, all
+ installed and available packages will be summarised
+ :return: (exit_code, [ errors ])
-+
-+ exit_code is::
++ exit_code is::
++
+ 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
@@ -999,7 +1022,7 @@ index 6056d38..afa7447
uservisible=1
if len(userlist) > 0:
-@@ -1327,7 +1653,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1327,7 +1667,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, [_('Done')]
def returnGroupInfo(self, userlist):
@@ -1020,7 +1043,7 @@ index 6056d38..afa7447
for strng in userlist:
group_matched = False
for group in self.comps.return_groups(strng):
-@@ -1339,9 +1677,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1339,9 +1691,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return 0, []
@@ -1043,7 +1066,7 @@ index 6056d38..afa7447
pkgs_used = []
for group_string in grouplist:
-@@ -1351,7 +1699,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1351,7 +1713,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
try:
@@ -1052,7 +1075,7 @@ index 6056d38..afa7447
except yum.Errors.GroupsError:
self.logger.critical(_('Warning: Group %s does not exist.'), group_string)
continue
-@@ -1368,8 +1716,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1368,8 +1730,18 @@ 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):
@@ -1062,9 +1085,9 @@ index 6056d38..afa7447
+ :param grouplist: a list of names or wildcards specifying
+ groups to be removed
+ :return: (exit_code, [ errors ])
-+
-+ exit_code is::
++ exit_code is::
++
+ 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
@@ -1072,7 +1095,7 @@ index 6056d38..afa7447
pkgs_used = []
for group_string in grouplist:
try:
-@@ -1389,7 +1747,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1389,7 +1761,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
def _promptWanted(self):
# shortcut for the always-off/always-on options
@@ -1081,7 +1104,7 @@ index 6056d38..afa7447
return False
if self.conf.alwaysprompt:
return True
-@@ -1400,7 +1758,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1400,7 +1772,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 \
@@ -1089,7 +1112,7 @@ index 6056d38..afa7447
txmbr.name not in self.extcmds:
return True
-@@ -1408,11 +1765,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1408,11 +1779,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return False
def usage(self):
@@ -1103,7 +1126,7 @@ index 6056d38..afa7447
sys.stdout.write(self.optparser.get_usage())
def _installable(self, pkg, ematch=False):
-@@ -1468,9 +1825,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+@@ -1468,9 +1839,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
return False
class YumOptionParser(OptionParser):
@@ -1115,7 +1138,7 @@ index 6056d38..afa7447
def __init__(self,base, **kwargs):
# check if this is called with a utils=True/False parameter
-@@ -1488,13 +1845,23 @@ class YumOptionParser(OptionParser):
+@@ -1488,13 +1859,23 @@ class YumOptionParser(OptionParser):
self._addYumBasicOptions()
def error(self, msg):
@@ -1141,7 +1164,7 @@ index 6056d38..afa7447
try:
args = _filtercmdline(
('--noplugins','--version','-q', '-v', "--quiet", "--verbose"),
-@@ -1521,7 +1888,15 @@ class YumOptionParser(OptionParser):
+@@ -1521,7 +1902,15 @@ class YumOptionParser(OptionParser):
return ret
def setupYumConfig(self, args=None):
@@ -1158,7 +1181,7 @@ index 6056d38..afa7447
if not args:
(opts, cmds) = self.parse_args()
else:
-@@ -1536,13 +1911,14 @@ class YumOptionParser(OptionParser):
+@@ -1536,13 +1925,14 @@ class YumOptionParser(OptionParser):
# Handle remaining options
if opts.assumeyes:
@@ -1178,7 +1201,7 @@ index 6056d38..afa7447
self.base.conf.cache = 1
if opts.obsoletes:
-@@ -1610,10 +1986,6 @@ class YumOptionParser(OptionParser):
+@@ -1610,10 +2000,6 @@ class YumOptionParser(OptionParser):
self.base.usage()
sys.exit(1)
@@ -1189,7 +1212,7 @@ index 6056d38..afa7447
# Disable all gpg key checking, if requested.
if opts.nogpgcheck:
# Altering the normal configs. doesn't work too well, esp. with
-@@ -1640,6 +2012,14 @@ class YumOptionParser(OptionParser):
+@@ -1640,6 +2026,14 @@ class YumOptionParser(OptionParser):
sys.exit(1)
def getRoot(self,opts):
@@ -1204,7 +1227,7 @@ index 6056d38..afa7447
self._checkAbsInstallRoot(opts)
# If the conf file is inside the installroot - use that.
# otherwise look for it in the normal root
-@@ -1713,6 +2093,10 @@ class YumOptionParser(OptionParser):
+@@ -1713,6 +2107,10 @@ class YumOptionParser(OptionParser):
help=_("verbose operation"))
group.add_option("-y", "--assumeyes", dest="assumeyes",
action="store_true", help=_("answer yes for all questions"))
@@ -1217,10 +1240,10 @@ index 6056d38..afa7447
group.add_option("--installroot", help=_("set install root"),
diff --git a/completion-helper.py b/completion-helper.py
new file mode 100755
-index 0000000..e4164f7
+index 0000000..0e4b96b
--- /dev/null
+++ b/completion-helper.py
-@@ -0,0 +1,83 @@
+@@ -0,0 +1,90 @@
+#!/usr/bin/python -t
+# -*- coding: utf-8 -*-
+#
@@ -1246,6 +1269,7 @@ index 0000000..e4164f7
+
+import cli
+import yumcommands
++from yum.Errors import GroupsError
+
+
+class GroupsCompletionCommand(yumcommands.GroupsCommand):
@@ -1286,7 +1310,8 @@ index 0000000..e4164f7
+
+def get_pattern(extcmds):
+ if len(extcmds) > 1 and extcmds[-1]:
-+ return shlex.split(extcmds[-1])[0] + "*"
++ try: return shlex.split(extcmds[-1])[0] + "*"
++ except ValueError: pass
+ return "*"
+
+def main(args):
@@ -1297,7 +1322,12 @@ index 0000000..e4164f7
+ base.registerCommand(RepoListCompletionCommand())
+ base.getOptionsConfig(args)
+ base.parseCommands()
-+ base.doCommands()
++ for repo in base.repos.listEnabled():
++ repo.skip_if_unavailable = True
++ try:
++ base.doCommands()
++ except GroupsError, e:
++ base.logger.error(e)
+
+if __name__ == "__main__":
+ try:
@@ -2125,7 +2155,7 @@ index 1a8202a..604377b 100644
.br
Configuration Option: \fBrpmverbosity\fP
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
-index 515aa73..df172fa 100644
+index 515aa73..b456074 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -114,15 +114,27 @@ are causing problems from the transaction.
@@ -2199,7 +2229,7 @@ index 515aa73..df172fa 100644
\fBinstallroot \fR
Specifies an alternative installroot, relative to which all packages will be
installed.
-@@ -300,6 +337,14 @@ with the \fBthrottle\fR option (above). If \fBthrottle\fR is a percentage and
+@@ -300,6 +337,21 @@ with the \fBthrottle\fR option (above). If \fBthrottle\fR is a percentage and
ignored. Default is `0' (no bandwidth throttling).
.IP
@@ -2211,10 +2241,17 @@ index 515aa73..df172fa 100644
+`6' or `IPv6': resolve to IPv6 addresses only.
+
+.IP
++\fBmax_connections \fR
++
++The maximum number of simultaneous connections. This overrides the urlgrabber
++default of 5 connections. Note that there are also implicit per-mirror limits
++and the downloader honors these too.
++
++.IP
\fBsslcacert \fR
Path to the directory containing the databases of the certificate authorities
yum should use to verify SSL certificates. Defaults to none - uses system
-@@ -331,6 +376,15 @@ Path to the SSL client key yum should use to connect to repos/remote sites
+@@ -331,6 +383,15 @@ Path to the SSL client key yum should use to connect to repos/remote sites
Defaults to none.
.IP
@@ -2230,10 +2267,12 @@ index 515aa73..df172fa 100644
\fBhistory_record \fR
Boolean - should yum record history entries for transactions. This takes some
disk space, and some extra time in the transactions. But it allows how to know a
-@@ -595,6 +649,23 @@ package's dependencies. If any of them are no longer required by any other
+@@ -593,8 +654,50 @@ See color_list_installed_older for possible values.
+ When removing packages (by removal, update or obsoletion) go through each
+ package's dependencies. If any of them are no longer required by any other
package then also mark them to be removed.
- Boolean (1, 0, True, False, yes,no) Defaults to False
-
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
+.IP
+\fBupgrade_requirements_on_install \fR
+When installing/reinstalling/upgrading packages go through each package's
@@ -2245,16 +2284,41 @@ index 515aa73..df172fa 100644
+When upgrading a package do we recheck any requirements that existed in the old
+package. Turning this on shouldn't do anything but slow yum depsolving down,
+however using rpm --nodeps etc. can break the rpmdb and then this will help.
-+Boolean (1, 0, True, False, yes,no) Defaults to False
-+
+ Boolean (1, 0, True, False, yes,no) Defaults to False
+
+.IP
+\fBreset_nice \fR
+If set to true then yum will try to reset the nice value to zero, before
+running an rpm transaction. Defaults to True.
++
++\fBexit_on_lock\fR
++Should the yum client exit immediately when something else has the lock.
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
++.IP
++\fBloadts_ignoremissing\fR
++Should the load-ts command ignore packages that are missing. This includes
++packages in the TS to be removed, which aren't installed, and packages in the
++TS to be added, which aren't available.
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
++.IP
++\fBloadts_ignorerpm\fR
++Should the load-ts command ignore the rpmdb version (yum version nogroups) or
++abort if there is a mismatch between the TS file and the current machine.
++Boolean (1, 0, True, False, yes, no) Defaults to False
++
++.IP
++\fBloadts_ignorenewrpm\fR
++Should the load-ts command ignore the future rpmdb version or
++abort if there is a mismatch between the TS file and what will happen on the
++current machine.
++Note that if loadts_ignorerpm is True, this option does nothing.
++Boolean (1, 0, True, False, yes, no) Defaults to False
.SH "[repository] OPTIONS"
-@@ -755,6 +826,11 @@ repository.
+@@ -755,6 +858,11 @@ repository.
Overrides the \fBbandwidth\fR option from the [main] section for this
repository.
@@ -2266,7 +2330,7 @@ index 515aa73..df172fa 100644
.IP
\fBsslcacert \fR
-@@ -776,6 +852,10 @@ repository.
+@@ -776,6 +884,10 @@ repository.
Overrides the \fBsslclientkey\fR option from the [main] section for this
repository.
@@ -2277,6 +2341,18 @@ index 515aa73..df172fa 100644
.IP
\fBmetadata_expire \fR
+@@ -824,7 +936,11 @@ as greater/less than any other. defaults to 1000
+ If set to True yum will continue running if this repository cannot be
+ contacted for any reason. This should be set carefully as all repos are consulted
+ for any given command. Defaults to False.
++
+ .IP
++\fBasync \fR
++If set to True Yum will download packages and metadata from this repo in
++parallel, if possible. Defaults to True.
+
+ .SH "URL INCLUDE SYNTAX"
+ .LP
diff --git a/etc/0yum.cron b/etc/0yum.cron
deleted file mode 100755
index 0cfaa4b..0000000
@@ -2631,7 +2707,7 @@ index c60fa08..0000000
-ts run
-exit
diff --git a/etc/yum.bash b/etc/yum.bash
-index f1e06e8..5945c6f 100644
+index f1e06e8..b21c594 100644
--- a/etc/yum.bash
+++ b/etc/yum.bash
@@ -1,53 +1,17 @@
@@ -2641,7 +2717,8 @@ index f1e06e8..5945c6f 100644
-# 1 = argument to "yum list" (all, available, updates etc)
-# 2 = current word to be completed
-_yum_list()
--{
++_yum_helper()
+ {
- # Fail fast for things that look like paths.
- [[ $2 == */* || $2 == [.~]* ]] && return
-
@@ -2664,8 +2741,7 @@ index f1e06e8..5945c6f 100644
-# 1 = argument to "yum repolist" (enabled, disabled etc)
-# 2 = current word to be completed
-_yum_repolist()
-+_yum_helper()
- {
+-{
- # TODO: add -d 0 when http://yum.baseurl.org/ticket/29 is fixed
- # (for now --noplugins is used to get rid of "Loaded plugins: ...")
- # Drop first ("repo id repo name") and last ("repolist: ...") rows -
@@ -2690,8 +2766,8 @@ index f1e06e8..5945c6f 100644
- COMPREPLY=( $( compgen -W "$( ${yum:-yum} -C grouplist $1 "$2*" \
- 2>/dev/null | sed -ne 's/^[[:space:]]\{1,\}\(.\{1,\}\)/\1/p' )" \
- -- "$2" ) )
-+ # Fail fast for things that look like paths.
-+ [[ $2 == */* || $2 == [.~]* ]] && return
++ # Fail fast for things that look like paths or options.
++ [[ $2 == */* || $2 == [.~-]* ]] && return
+ _yum_helper list "$@"
}
@@ -2759,8 +2835,8 @@ index f1e06e8..5945c6f 100644
- groupinfo groupinstall grouplist groupremove help history info install
- list makecache provides reinstall remove repolist resolvedep search
- shell update upgrade version )
-+ groups help history info install list makecache provides reinstall
-+ remove repolist search shell update upgrade version )
++ groups help history info install list load-transaction makecache provides
++ reinstall remove repolist search shell update upgrade version )
local i c cmd subcmd
for (( i=1; i < ${#words[@]}-1; i++ )) ; do
@@ -2769,7 +2845,7 @@ index f1e06e8..5945c6f 100644
for c in ${cmds[@]} check-rpmdb distribution-synchronization erase \
- groupupdate grouperase localinstall localupdate whatprovides ; do
+ group groupinfo groupinstall grouplist groupremove groupupdate \
-+ grouperase install-na localinstall localupdate whatprovides ; do
++ grouperase install-na load-ts localinstall localupdate whatprovides ; do
[[ ${words[i]} == $c ]] && cmd=$c && break
done
done
@@ -2889,7 +2965,7 @@ index f1e06e8..5945c6f 100644
;;
esac
return 0
-@@ -288,13 +285,20 @@ _yum()
+@@ -288,42 +285,56 @@ _yum()
;;
install)
@@ -2912,7 +2988,16 @@ index f1e06e8..5945c6f 100644
COMPREPLY=( $( compgen -W 'all available updates installed
extras obsoletes recent' -- "$cur" ) )
return 0
-@@ -306,24 +310,26 @@ _yum()
+ ;;
+
++ load-transaction|load-ts)
++ COMPREPLY=( $( compgen -f -o plusdirs -X '!*.yumtx' -- "$cur" ) )
++ return 0
++ ;;
++
+ localinstall|localupdate)
+ _yum_binrpmfiles "$cur"
+ return 0
;;
repolist)
@@ -2944,7 +3029,7 @@ index f1e06e8..5945c6f 100644
COMPREPLY=( $( compgen -W 'all installed available nogroups
grouplist groupinfo' -- "$cur" ) )
return 0
-@@ -337,7 +343,11 @@ _yum()
+@@ -337,7 +348,11 @@ _yum()
$split && return 0
@@ -147960,20 +148045,22 @@ index 704a726..05fe6bf 100644
-
-
diff --git a/rpmUtils/arch.py b/rpmUtils/arch.py
-index 6082005..7d67907 100644
+index 6082005..2226dc5 100644
--- a/rpmUtils/arch.py
+++ b/rpmUtils/arch.py
-@@ -2,6 +2,9 @@
+@@ -2,6 +2,11 @@
#
import os
+import rpm
++import ctypes
++import struct
+
+_ppc64_native_is_best = False
# dict mapping arch -> ( multicompat, best personality, biarch personality )
multilibArches = { "x86_64": ( "athlon", "x86_64", "athlon" ),
-@@ -10,6 +13,8 @@ multilibArches = { "x86_64": ( "athlon", "x86_64", "athlon" ),
+@@ -10,6 +15,8 @@ multilibArches = { "x86_64": ( "athlon", "x86_64", "athlon" ),
"ppc64": ( "ppc", "ppc", "ppc64" ),
"s390x": ( "s390", "s390x", "s390" ),
}
@@ -147982,7 +148069,15 @@ index 6082005..7d67907 100644
arches = {
# ia32
-@@ -61,6 +66,13 @@ arches = {
+@@ -26,6 +33,7 @@ arches = {
+ "ia32e": "x86_64",
+
+ # ppc
++ "ppc64p7": "ppc64",
+ "ppc64pseries": "ppc64",
+ "ppc64iseries": "ppc64",
+ "ppc64": "ppc",
+@@ -61,6 +69,13 @@ arches = {
"armv5tejl": "armv5tel",
"armv5tel": "noarch",
@@ -147996,7 +148091,54 @@ index 6082005..7d67907 100644
# super-h
"sh4a": "sh4",
"sh4": "noarch",
-@@ -231,6 +243,13 @@ def getCanonX86Arch(arch):
+@@ -70,6 +85,13 @@ arches = {
+ "ia64": "noarch",
+ }
+
++# Will contain information parsed from /proc/self/auxv via _parse_auxv().
++# Should move into rpm really.
++_aux_vector = {
++ "platform": "",
++ "hwcap": 0,
++ }
++
+ def legitMultiArchesInSameLib(arch=None):
+ # this is completely crackrock - if anyone has a better way I
+ # am all ears
+@@ -210,6 +232,32 @@ def _try_read_cpuinfo():
+ except:
+ return []
+
++def _parse_auxv():
++ """ Read /proc/self/auxv and parse it into global dict for easier access
++ later on, very similar to what rpm does. """
++ # In case we can't open and read /proc/self/auxv, just return
++ try:
++ data = open("/proc/self/auxv", "rb").read()
++ except:
++ return
++
++ # Define values from /usr/include/elf.h
++ AT_PLATFORM = 15
++ AT_HWCAP = 16
++ fmtlen = struct.calcsize("LL")
++ offset = 0
++ platform = ctypes.c_char_p()
++
++ # Parse the data and fill in _aux_vector dict
++ while offset <= len(data) - fmtlen:
++ at_type, at_val = struct.unpack_from("LL", data, offset)
++ if at_type == AT_PLATFORM:
++ platform.value = at_val
++ _aux_vector["platform"] = platform.value
++ if at_type == AT_HWCAP:
++ _aux_vector["hwcap"] = at_val
++ offset = offset + fmtlen
++
+ def getCanonX86Arch(arch):
+ #
+ if arch == "i586":
+@@ -231,6 +279,13 @@ def getCanonX86Arch(arch):
return arch
@@ -148010,7 +148152,30 @@ index 6082005..7d67907 100644
def getCanonPPCArch(arch):
# FIXME: should I do better handling for mac, etc?
if arch != "ppc64":
-@@ -308,6 +327,8 @@ def getCanonArch(skipRpmPlatform = 0):
+@@ -241,6 +296,17 @@ def getCanonPPCArch(arch):
+ if line.find("machine") != -1:
+ machine = line.split(':')[1]
+ break
++
++ platform = _aux_vector["platform"]
++ if machine is None and not platform:
++ return arch
++
++ try:
++ if platform.startswith("power") and int(platform[5:]) >= 7:
++ return "ppc64p7"
++ except:
++ pass
++
+ if machine is None:
+ return arch
+
+@@ -305,9 +371,13 @@ def getCanonArch(skipRpmPlatform = 0):
+
+ arch = os.uname()[4]
+
++ _parse_auxv()
++
if (len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86"):
return getCanonX86Arch(arch)
@@ -148019,7 +148184,7 @@ index 6082005..7d67907 100644
if arch.startswith("ppc"):
return getCanonPPCArch(arch)
if arch.startswith("sparc"):
-@@ -339,7 +360,7 @@ def getBestArch(myarch=None):
+@@ -339,7 +409,7 @@ def getBestArch(myarch=None):
if arch.startswith("sparc64"):
arch = multilibArches[arch][1]
@@ -148028,7 +148193,7 @@ index 6082005..7d67907 100644
arch = 'ppc'
return arch
-@@ -357,8 +378,12 @@ def getBaseArch(myarch=None):
+@@ -357,8 +427,12 @@ def getBaseArch(myarch=None):
if myarch.startswith("sparc64"):
return "sparc"
@@ -148309,6 +148474,82 @@ index 7af3f16..ea47b03 100644
def testUpdate_so_req_diff_arch(self):
rpo1 = FakePackage('foozoomer')
+diff --git a/test/revdepupdatetests.py b/test/revdepupdatetests.py
+new file mode 100644
+index 0000000..a98341d
+--- /dev/null
++++ b/test/revdepupdatetests.py
+@@ -0,0 +1,70 @@
++from testbase import *
++
++class RevdepUpdateTests(OperationsTests):
++
++ @staticmethod
++ def buildPkgs(pkgs, *args):
++ """ This test checks that remove_old_deps handles reverse
++ dependencies properly during yum update. Specifically,
++ remove_old_deps should remove precisely the packages which are not
++ required by any package currently installed or pending
++ installation. Two cases:
++
++ For packages A, B, we write A -> B if B requires A. Packages
++ with a dep prefix are dep-installed.
++
++ 1) Installed: dep1 -> dep2 -> pkg1 <- dep3 and dep3 -> dep2
++ Update: pkg1, which requires dep2 but no longer requires dep3.
++ Correct outcome: dep1, dep2, dep3, pkg1, since dep2 still
++ needs dep3.
++
++ 2) Installed: dep1 -> dep2 -> pkg1 <- dep3 and dep3 -> dep2
++ Update: pkg1, which now requires only dep1
++ Correct outcome: dep1, pkg1, since dep2 and dep3 are
++ no longer needed.
++
++ """
++
++
++ pkgs.installed_1 = FakePackage('dep1', '1', '0', '0', 'noarch')
++ pkgs.installed_1.yumdb_info.reason = 'dep'
++
++ pkgs.installed_2 = FakePackage('dep2', '1', '0', '0', 'noarch')
++ pkgs.installed_2.yumdb_info.reason = 'dep'
++
++ pkgs.installed_3 = FakePackage('pkg1', '1', '0', '0', 'noarch')
++ pkgs.installed_3.yumdb_info.reason = 'user'
++
++ pkgs.installed_4 = FakePackage('dep3', '1', '0', '0', 'noarch')
++ pkgs.installed_4.yumdb_info.reason = 'dep'
++
++ pkgs.installed_1.addRequiringPkg(pkgs.installed_2)
++ pkgs.installed_2.addRequiringPkg(pkgs.installed_3)
++ pkgs.installed_4.addRequiringPkg(pkgs.installed_2)
++
++ pkgs.installed_2.addRequiresPkg(pkgs.installed_1)
++ pkgs.installed_2.addRequiresPkg(pkgs.installed_4)
++ pkgs.installed_3.addRequiresPkg(pkgs.installed_4)
++ pkgs.installed_3.addRequiresPkg(pkgs.installed_2)
++
++ pkgs.update_2 = FakePackage('dep2', '2', '0', '0', 'noarch')
++ pkgs.update_2.addRequires('dep1', 'EQ', ('0', '1', '0'))
++
++ pkgs.update_3 = FakePackage('pkg1', '2', '0', '0', 'noarch')
++ pkgs.update_3.addRequires('dep2', 'EQ', ('0', '1', '0'))
++
++ pkgs.update_4 = FakePackage('pkg1', '2', '0', '0', 'noarch')
++ pkgs.update_4.addRequires('dep1', 'EQ', ('0', '1', '0'))
++
++ def testUpdate(self):
++ p = self.pkgs
++ res, msg = self.runOperation(['update'], [p.installed_1, p.installed_2, p.installed_3, p.installed_4], [p.update_3])
++ self.assert_(res=='ok', msg)
++ self.assertResult( (p.installed_1, p.installed_2, p.update_3, p.installed_4) )
++
++ def testUpdate2(self):
++ p = self.pkgs
++ res, msg = self.runOperation(['update'], [p.installed_1, p.installed_2, p.installed_3, p.installed_4], [p.update_4])
++ self.assert_(res=='ok', msg)
++ self.assertResult( (p.installed_1, p.update_4) )
++
diff --git a/test/simpleobsoletestests.py b/test/simpleobsoletestests.py
index 97a9923..70dde98 100644
--- a/test/simpleobsoletestests.py
@@ -149127,10 +149368,10 @@ index ced6ba0..08b09fb
return_code = self.doTransaction()
diff --git a/yum-cron/Makefile b/yum-cron/Makefile
new file mode 100644
-index 0000000..d68659a
+index 0000000..34cb397
--- /dev/null
+++ b/yum-cron/Makefile
-@@ -0,0 +1,19 @@
+@@ -0,0 +1,21 @@
+all:
+ echo "Nothing to do"
+
@@ -149143,7 +149384,9 @@ index 0000000..d68659a
+ mkdir -p $(DESTDIR)/usr/sbin
+ mkdir -p $(DESTDIR)/etc/sysconfig
+ mkdir -p $(DESTDIR)/usr/share/yum-cron
-+ install -D -m 755 yum-update.cron.sh $(DESTDIR)/etc/cron.daily/yum-update.cron
++# Install yum-update.cron as 0yum-update.cron so it runs before items like
++# manpage update, mlocate, and prelink
++ install -D -m 755 yum-update.cron.sh $(DESTDIR)/etc/cron.daily/0yum-update.cron
+ install -D -m 755 yum-cleanup.cron.sh $(DESTDIR)/etc/cron.daily/yum-cleanup.cron
+ install -D -m 755 yum-cron.sysvinit $(DESTDIR)/etc/rc.d/init.d/yum-cron
+ install -D -m 755 yum-cron.sh $(DESTDIR)/usr/sbin/yum-cron
@@ -149408,7 +149651,7 @@ index 0000000..e300fa7
+exit 0
diff --git a/yum-cron/yum-cron.sysconfig b/yum-cron/yum-cron.sysconfig
new file mode 100644
-index 0000000..4c8c40d
+index 0000000..53477d3
--- /dev/null
+++ b/yum-cron/yum-cron.sysconfig
@@ -0,0 +1,92 @@
@@ -149465,7 +149708,7 @@ index 0000000..4c8c40d
+#SYSTEMNAME=""
+
+# Scheduling Options (used by the default cron scripts,
-+# /etc/cron.daily/yum-cleanup.cron and /etc/cron.daily/yum-update.cron)
++# /etc/cron.daily/yum-cleanup.cron and /etc/cron.daily/0yum-update.cron)
+#
+# Note that if you use a different cron configuration (for example,
+# removing the default scripts and adding an entry in /etc/cron.d),
@@ -150214,7 +150457,7 @@ index 1ce4720..25e3022
gobject.threads_init()
dbus.glib.threads_init()
diff --git a/yum.spec b/yum.spec
-index abd203f..572112a 100644
+index abd203f..65c62a9 100644
--- a/yum.spec
+++ b/yum.spec
@@ -1,24 +1,51 @@
@@ -150451,7 +150694,7 @@ index abd203f..572112a 100644
-%{_sysconfdir}/cron.daily/0yum.cron
-%config(noreplace) %{_sysconfdir}/yum/yum-daily.yum
-%config(noreplace) %{_sysconfdir}/yum/yum-weekly.yum
-+%config(noreplace) %{_sysconfdir}/cron.daily/yum-update.cron
++%config(noreplace) %{_sysconfdir}/cron.daily/0yum-update.cron
+%config(noreplace) %{_sysconfdir}/cron.daily/yum-cleanup.cron
%{_sysconfdir}/rc.d/init.d/yum-cron
+%{_sbindir}/yum-cron
@@ -150481,7 +150724,7 @@ index abd203f..572112a 100644
- 3.4.1
- umask bug fix.
diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..3680356 100644
+index 99039e0..4650639 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -46,8 +46,13 @@ import operator
@@ -150657,7 +150900,20 @@ index 99039e0..3680356 100644
if debuglevel != None:
startupconf.debuglevel = debuglevel
-@@ -367,22 +404,36 @@ class YumBase(depsolve.Depsolve):
+@@ -336,6 +373,12 @@ class YumBase(depsolve.Depsolve):
+
+ self._conf = config.readMainConfig(startupconf)
+
++ # update urlgrabber defaults
++ mc = self._conf.max_connections
++ if mc > 0:
++ default_grabber.opts.max_connections = mc
++ default_grabber.opts.timedhosts = self._conf.cachedir + '/timedhosts'
++
+ # We don't want people accessing/altering preconf after it becomes
+ # worthless. So we delete it, and thus. it'll raise AttributeError
+ del self.preconf
+@@ -367,22 +410,36 @@ class YumBase(depsolve.Depsolve):
def doLoggingSetup(self, debuglevel, errorlevel,
syslog_ident=None, syslog_facility=None,
syslog_device='/dev/log'):
@@ -150701,7 +150957,17 @@ index 99039e0..3680356 100644
if repo_age is None:
repo_age = os.stat(repofn)[8]
-@@ -429,7 +480,15 @@ class YumBase(depsolve.Depsolve):
+@@ -391,8 +448,7 @@ class YumBase(depsolve.Depsolve):
+ try:
+ parser.readfp(confpp_obj)
+ except ParsingError, e:
+- msg = str(e)
+- raise Errors.ConfigError, msg
++ raise Errors.ConfigError(exception2msg(e))
+
+ # Check sections in the .repo file that was just slurped up
+ for section in parser.sections():
+@@ -429,7 +485,15 @@ class YumBase(depsolve.Depsolve):
thisrepo.base_persistdir = self.conf._repos_persistdir
@@ -150718,7 +150984,7 @@ index 99039e0..3680356 100644
if thisrepo.id in self.repo_setopts:
for opt in self.repo_setopts[thisrepo.id].items:
if not hasattr(thisrepo, opt):
-@@ -440,6 +499,20 @@ class YumBase(depsolve.Depsolve):
+@@ -440,6 +504,20 @@ class YumBase(depsolve.Depsolve):
if validate and not validate(thisrepo):
continue
@@ -150739,7 +151005,7 @@ index 99039e0..3680356 100644
# Got our list of repo objects, add them to the repos
# collection
try:
-@@ -448,8 +521,11 @@ class YumBase(depsolve.Depsolve):
+@@ -448,8 +526,11 @@ class YumBase(depsolve.Depsolve):
self.logger.warning(e)
def getReposFromConfig(self):
@@ -150753,7 +151019,16 @@ index 99039e0..3680356 100644
# Read .repo files from directories specified by the reposdir option
# (typically /etc/yum/repos.d)
repo_config_age = self.conf.config_file_age
-@@ -472,12 +548,13 @@ class YumBase(depsolve.Depsolve):
+@@ -466,18 +547,22 @@ class YumBase(depsolve.Depsolve):
+
+ if os.path.isdir(reposdir):
+ for repofn in sorted(glob.glob('%s/*.repo' % reposdir)):
++ if not os.access(repofn, os.R_OK):
++ self.logger.warning(_("Skipping unreadable repository %s"), repr(repofn))
++ continue
+ thisrepo_age = os.stat(repofn)[8]
+ if thisrepo_age < repo_config_age:
+ thisrepo_age = repo_config_age
self.getReposFromConfigFile(repofn, repo_age=thisrepo_age)
def readRepoConfig(self, parser, section):
@@ -150772,7 +151047,17 @@ index 99039e0..3680356 100644
repo = yumRepo.YumRepository(section)
try:
repo.populate(parser, section, self.conf)
-@@ -500,31 +577,31 @@ class YumBase(depsolve.Depsolve):
+@@ -493,38 +578,40 @@ class YumBase(depsolve.Depsolve):
+ repo.name = to_unicode(repo.name)
+
+ # Set attributes not from the config file
++ repo.old_base_cache_dir = getattr(self, '_old_cachedir', '')
+ repo.basecachedir = self.conf.cachedir
+ repo.yumvar.update(self.conf.yumvar)
+ repo.cfg = parser
+-
++ # Enable parallel downloading
++ repo._async = repo.async
return repo
def disablePlugins(self):
@@ -150825,7 +151110,7 @@ index 99039e0..3680356 100644
if isinstance(self.plugins, plugins.YumPlugins):
raise RuntimeError(_("plugins already initialised"))
-@@ -533,6 +610,8 @@ class YumBase(depsolve.Depsolve):
+@@ -533,6 +620,8 @@ class YumBase(depsolve.Depsolve):
def doRpmDBSetup(self):
@@ -150834,7 +151119,7 @@ index 99039e0..3680356 100644
warnings.warn(_('doRpmDBSetup() will go away in a future version of Yum.\n'),
Errors.YumFutureDeprecationWarning, stacklevel=2)
-@@ -552,7 +631,8 @@ class YumBase(depsolve.Depsolve):
+@@ -552,7 +641,8 @@ class YumBase(depsolve.Depsolve):
return self._rpmdb
def closeRpmDB(self):
@@ -150844,7 +151129,7 @@ index 99039e0..3680356 100644
if self._rpmdb is not None:
self._rpmdb.ts = None
self._rpmdb.dropCachedData()
-@@ -567,6 +647,12 @@ class YumBase(depsolve.Depsolve):
+@@ -567,6 +657,12 @@ class YumBase(depsolve.Depsolve):
self._ts = None
def doRepoSetup(self, thisrepo=None):
@@ -150857,7 +151142,7 @@ index 99039e0..3680356 100644
warnings.warn(_('doRepoSetup() will go away in a future version of Yum.\n'),
Errors.YumFutureDeprecationWarning, stacklevel=2)
-@@ -630,6 +716,14 @@ class YumBase(depsolve.Depsolve):
+@@ -630,6 +726,14 @@ class YumBase(depsolve.Depsolve):
self._repos = RepoStorage(self)
def doSackSetup(self, archlist=None, thisrepo=None):
@@ -150872,7 +151157,7 @@ index 99039e0..3680356 100644
warnings.warn(_('doSackSetup() will go away in a future version of Yum.\n'),
Errors.YumFutureDeprecationWarning, stacklevel=2)
-@@ -711,6 +805,9 @@ class YumBase(depsolve.Depsolve):
+@@ -711,6 +815,9 @@ class YumBase(depsolve.Depsolve):
def doUpdateSetup(self):
@@ -150882,7 +151167,7 @@ index 99039e0..3680356 100644
warnings.warn(_('doUpdateSetup() will go away in a future version of Yum.\n'),
Errors.YumFutureDeprecationWarning, stacklevel=2)
-@@ -765,6 +862,8 @@ class YumBase(depsolve.Depsolve):
+@@ -765,6 +872,8 @@ class YumBase(depsolve.Depsolve):
return self._up
def doGroupSetup(self):
@@ -150891,7 +151176,16 @@ index 99039e0..3680356 100644
warnings.warn(_('doGroupSetup() will go away in a future version of Yum.\n'),
Errors.YumFutureDeprecationWarning, stacklevel=2)
-@@ -837,7 +936,10 @@ class YumBase(depsolve.Depsolve):
+@@ -829,7 +938,7 @@ class YumBase(depsolve.Depsolve):
+ try:
+ self._comps.add(groupfile)
+ except (Errors.GroupsError,Errors.CompsException), e:
+- msg = _('Failed to add groups file for repository: %s - %s') % (repo, str(e))
++ msg = _('Failed to add groups file for repository: %s - %s') % (repo, exception2msg(e))
+ self.logger.critical(msg)
+ else:
+ repo.groups_added = True
+@@ -837,7 +946,10 @@ class YumBase(depsolve.Depsolve):
if self._comps.compscount == 0:
raise Errors.GroupsError, _('No Groups Available in any repository')
@@ -150903,7 +151197,16 @@ index 99039e0..3680356 100644
self.verbose_logger.debug('group time: %0.3f' % (time.time() - group_st))
return self._comps
-@@ -881,9 +983,18 @@ class YumBase(depsolve.Depsolve):
+@@ -868,7 +980,7 @@ class YumBase(depsolve.Depsolve):
+ # feed it into _tags.add()
+ self._tags.add(repo.id, tag_sqlite)
+ except (Errors.RepoError, Errors.PkgTagsError), e:
+- msg = _('Failed to add Pkg Tags for repository: %s - %s') % (repo, str(e))
++ msg = _('Failed to add Pkg Tags for repository: %s - %s') % (repo, exception2msg(e))
+ self.logger.critical(msg)
+
+
+@@ -881,9 +993,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,
@@ -150923,7 +151226,7 @@ index 99039e0..3680356 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 +1032,11 @@ class YumBase(depsolve.Depsolve):
+@@ -921,6 +1042,11 @@ class YumBase(depsolve.Depsolve):
fdel=lambda self: setattr(self, "_history", None),
doc="Yum History Object")
@@ -150935,7 +151238,7 @@ index 99039e0..3680356 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 +1044,10 @@ class YumBase(depsolve.Depsolve):
+@@ -928,9 +1054,10 @@ class YumBase(depsolve.Depsolve):
def doSackFilelistPopulate(self):
@@ -150949,7 +151252,7 @@ index 99039e0..3680356 100644
necessary = False
# I can't think of a nice way of doing this, we have to have the sack here
-@@ -951,8 +1068,12 @@ class YumBase(depsolve.Depsolve):
+@@ -951,8 +1078,12 @@ class YumBase(depsolve.Depsolve):
self.repos.populateSack(mdtype='filelists')
def yumUtilsMsg(self, func, prog):
@@ -150964,7 +151267,7 @@ index 99039e0..3680356 100644
if self.rpmdb.contains(name="yum-utils"):
return
-@@ -964,8 +1085,17 @@ class YumBase(depsolve.Depsolve):
+@@ -964,8 +1095,17 @@ class YumBase(depsolve.Depsolve):
(hibeg, prog, hiend))
def buildTransaction(self, unfinished_transactions_check=True):
@@ -150984,7 +151287,7 @@ index 99039e0..3680356 100644
if (unfinished_transactions_check and
misc.find_unfinished_transactions(yumlibpath=self.conf.persistdir)):
msg = _('There are unfinished transactions remaining. You might ' \
-@@ -1004,7 +1134,7 @@ class YumBase(depsolve.Depsolve):
+@@ -1004,7 +1144,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 )
@@ -150993,7 +151296,7 @@ index 99039e0..3680356 100644
self.tsInfo.pkgSack.dropCachedData()
# FIXME: This is horrible, see below and yummain. Maybe create a real
-@@ -1242,13 +1372,15 @@ class YumBase(depsolve.Depsolve):
+@@ -1242,13 +1382,15 @@ class YumBase(depsolve.Depsolve):
if None in pkgtup:
return None
return pkgtup
@@ -151013,7 +151316,7 @@ index 99039e0..3680356 100644
if pkgtup is None:
return
self._not_found_i[pkgtup] = YumNotFoundPackage(pkgtup)
-@@ -1454,8 +1586,14 @@ class YumBase(depsolve.Depsolve):
+@@ -1454,8 +1596,14 @@ class YumBase(depsolve.Depsolve):
return probs
def runTransaction(self, cb):
@@ -151029,7 +151332,7 @@ index 99039e0..3680356 100644
self.plugins.run('pretrans')
# We may want to put this other places, eventually, but for now it's
-@@ -1516,10 +1654,23 @@ class YumBase(depsolve.Depsolve):
+@@ -1516,10 +1664,23 @@ class YumBase(depsolve.Depsolve):
pass
self._ts_save_file = None
@@ -151053,7 +151356,7 @@ index 99039e0..3680356 100644
# make resultobject - just a plain yumgenericholder object
resultobject = misc.GenericHolder()
-@@ -1567,13 +1718,24 @@ class YumBase(depsolve.Depsolve):
+@@ -1567,13 +1728,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):
@@ -151083,7 +151386,7 @@ index 99039e0..3680356 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 +1746,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1584,9 +1756,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
@@ -151100,7 +151403,7 @@ index 99039e0..3680356 100644
for txmbr in self.tsInfo:
if txmbr.output_state in TS_INSTALL_STATES:
if not self.rpmdb.contains(po=txmbr.po):
-@@ -1596,7 +1765,9 @@ class YumBase(depsolve.Depsolve):
+@@ -1596,7 +1775,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
@@ -151110,7 +151413,7 @@ index 99039e0..3680356 100644
po = self.getInstalledPackageObject(txmbr.pkgtup)
rpo = txmbr.po
po.yumdb_info.from_repo = rpo.repoid
-@@ -1630,6 +1801,10 @@ class YumBase(depsolve.Depsolve):
+@@ -1630,6 +1811,10 @@ class YumBase(depsolve.Depsolve):
if md:
po.yumdb_info.from_repo_timestamp = str(md.timestamp)
@@ -151121,7 +151424,7 @@ index 99039e0..3680356 100644
loginuid = misc.getloginuid()
if txmbr.updates or txmbr.downgrades or txmbr.reinstall:
if txmbr.updates:
-@@ -1640,11 +1815,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1640,11 +1825,16 @@ class YumBase(depsolve.Depsolve):
opo = po
if 'installed_by' in opo.yumdb_info:
po.yumdb_info.installed_by = opo.yumdb_info.installed_by
@@ -151138,7 +151441,7 @@ index 99039e0..3680356 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 +1842,13 @@ class YumBase(depsolve.Depsolve):
+@@ -1662,10 +1852,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
@@ -151152,7 +151455,7 @@ index 99039e0..3680356 100644
self.verbose_logger.log(logginglevels.DEBUG_2, 'What is this? %s' % txmbr.po)
self.plugins.run('postverifytrans')
-@@ -1680,10 +1863,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1680,10 +1873,11 @@ class YumBase(depsolve.Depsolve):
self.verbose_logger.debug('VerifyTransaction time: %0.3f' % (time.time() - vt_st))
def costExcludePackages(self):
@@ -151168,7 +151471,7 @@ index 99039e0..3680356 100644
# if all the repo.costs are equal then don't bother running things
costs = {}
for r in self.repos.listEnabled():
-@@ -1705,10 +1889,12 @@ class YumBase(depsolve.Depsolve):
+@@ -1705,10 +1899,12 @@ class YumBase(depsolve.Depsolve):
done = True
def excludePackages(self, repo=None):
@@ -151184,7 +151487,7 @@ index 99039e0..3680356 100644
if "all" in self.conf.disable_excludes:
return
-@@ -1735,9 +1921,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1735,9 +1931,11 @@ class YumBase(depsolve.Depsolve):
self.pkgSack.addPackageExcluder(repoid, exid,'exclude.match', match)
def includePackages(self, repo):
@@ -151199,7 +151502,7 @@ index 99039e0..3680356 100644
includelist = repo.getIncludePkgList()
if len(includelist) == 0:
-@@ -1757,8 +1945,11 @@ class YumBase(depsolve.Depsolve):
+@@ -1757,8 +1955,11 @@ class YumBase(depsolve.Depsolve):
self.pkgSack.addPackageExcluder(repo.id, exid, 'exclude.marked')
def doLock(self, lockfile = YUM_PID_FILE):
@@ -151213,7 +151516,7 @@ index 99039e0..3680356 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 +1965,26 @@ class YumBase(depsolve.Depsolve):
+@@ -1774,38 +1975,26 @@ class YumBase(depsolve.Depsolve):
mypid=str(os.getpid())
while not self._lock(lockfile, mypid, 0644):
@@ -151267,7 +151570,7 @@ index 99039e0..3680356 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 +2009,69 @@ class YumBase(depsolve.Depsolve):
+@@ -1830,31 +2019,69 @@ class YumBase(depsolve.Depsolve):
self._unlock(lockfile)
self._lockfile = None
@@ -151347,7 +151650,7 @@ index 99039e0..3680356 100644
failed = False
if type(fo) is types.InstanceType:
-@@ -1894,9 +2111,16 @@ class YumBase(depsolve.Depsolve):
+@@ -1894,9 +2121,16 @@ class YumBase(depsolve.Depsolve):
def verifyChecksum(self, fo, checksumType, csum):
@@ -151367,7 +151670,7 @@ index 99039e0..3680356 100644
try:
filesum = misc.checksum(checksumType, fo)
except Errors.MiscError, e:
-@@ -1908,6 +2132,17 @@ class YumBase(depsolve.Depsolve):
+@@ -1908,6 +2142,17 @@ class YumBase(depsolve.Depsolve):
return 0
def downloadPkgs(self, pkglist, callback=None, callback_total=None):
@@ -151385,10 +151688,28 @@ index 99039e0..3680356 100644
def mediasort(apo, bpo):
# FIXME: we should probably also use the mediaid; else we
# could conceivably ping-pong between different disc1's
-@@ -1998,16 +2233,6 @@ class YumBase(depsolve.Depsolve):
+@@ -1979,8 +2224,9 @@ class YumBase(depsolve.Depsolve):
+ urlgrabber.progress.text_meter_total_size(remote_size)
+ beg_download = time.time()
+ i = 0
+- local_size = 0
++ local_size = [0]
+ done_repos = set()
++ async = hasattr(urlgrabber.grabber, 'parallel_wait')
+ for po in remote_pkgs:
+ # Recheck if the file is there, works around a couple of weird
+ # edge cases.
+@@ -1992,52 +2238,47 @@ class YumBase(depsolve.Depsolve):
+ remote_size -= po.size
+ if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+ urlgrabber.progress.text_meter_total_size(remote_size,
+- local_size)
++ local_size[0])
+ continue
+ if os.path.getsize(local) >= po.size:
os.unlink(local)
- checkfunc = (self.verifyPkg, (po, 1), {})
+- checkfunc = (self.verifyPkg, (po, 1), {})
- dirstat = os.statvfs(po.repo.pkgdir)
- if (dirstat.f_bavail * dirstat.f_bsize) <= long(po.size):
- adderror(po, _('Insufficient space in download directory %s\n'
@@ -151399,19 +151720,65 @@ index 99039e0..3680356 100644
- format_number(po.size)))
- continue
-
- try:
- if i == 1 and not local_size and remote_size == po.size:
- text = os.path.basename(po.relativepath)
-@@ -2032,7 +2257,7 @@ class YumBase(depsolve.Depsolve):
- done_repos.add(po.repoid)
-
- except Errors.RepoError, e:
+- try:
+- if i == 1 and not local_size and remote_size == po.size:
+- text = os.path.basename(po.relativepath)
+- else:
+- text = '(%s/%s): %s' % (i, len(remote_pkgs),
+- os.path.basename(po.relativepath))
+- mylocal = po.repo.getPackage(po,
+- checkfunc=checkfunc,
+- text=text,
+- cache=po.repo.http_caching != 'none',
+- )
+- local_size += po.size
++ def checkfunc(obj, po=po):
++ self.verifyPkg(obj, po, 1)
++ local_size[0] += po.size
+ if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+ urlgrabber.progress.text_meter_total_size(remote_size,
+- local_size)
++ local_size[0])
+ if po.repoid not in done_repos:
++ done_repos.add(po.repoid)
+ # Check a single package per. repo. ... to give a hint to
+ # the user on big downloads.
+ result, errmsg = self.sigCheckPkg(po)
+ if result != 0:
+ self.verbose_logger.warn("%s", errmsg)
+- done_repos.add(po.repoid)
+-
+- except Errors.RepoError, e:
- adderror(po, str(e))
-+ adderror(po, exception2msg(e))
- else:
- po.localpath = mylocal
+- else:
+- po.localpath = mylocal
++ po.localpath = obj.filename
if po in errors:
-@@ -2052,7 +2277,22 @@ class YumBase(depsolve.Depsolve):
+ del errors[po]
+
++ text = os.path.basename(po.relativepath)
++ kwargs = {}
++ if async and po.repo._async:
++ kwargs['failfunc'] = lambda obj, po=po: adderror(po, exception2msg(obj.exception))
++ kwargs['async'] = True
++ elif not (i == 1 and not local_size[0] and remote_size == po.size):
++ text = '(%s/%s): %s' % (i, len(remote_pkgs), text)
++ try:
++ po.repo.getPackage(po,
++ checkfunc=checkfunc,
++ text=text,
++ cache=po.repo.http_caching != 'none',
++ **kwargs
++ )
++ except Errors.RepoError, e:
++ adderror(po, exception2msg(e))
++ if async:
++ urlgrabber.grabber.parallel_wait()
++
+ if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+ urlgrabber.progress.text_meter_total_size(0)
+ if callback_total is not None and not errors:
+@@ -2052,7 +2293,22 @@ class YumBase(depsolve.Depsolve):
return errors
def verifyHeader(self, fo, po, raiseError):
@@ -151435,7 +151802,7 @@ index 99039e0..3680356 100644
if type(fo) is types.InstanceType:
fo = fo.filename
-@@ -2076,9 +2316,12 @@ class YumBase(depsolve.Depsolve):
+@@ -2076,9 +2332,12 @@ class YumBase(depsolve.Depsolve):
return 1
def downloadHeader(self, po):
@@ -151450,7 +151817,7 @@ index 99039e0..3680356 100644
if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
return
-@@ -2122,15 +2365,17 @@ class YumBase(depsolve.Depsolve):
+@@ -2122,15 +2381,17 @@ class YumBase(depsolve.Depsolve):
return
def sigCheckPkg(self, po):
@@ -151476,7 +151843,7 @@ index 99039e0..3680356 100644
if self._override_sigchecks:
check = False
hasgpgkey = 0
-@@ -2181,6 +2426,9 @@ class YumBase(depsolve.Depsolve):
+@@ -2181,6 +2442,9 @@ class YumBase(depsolve.Depsolve):
return result, msg
def cleanUsedHeadersPackages(self):
@@ -151486,7 +151853,7 @@ index 99039e0..3680356 100644
filelist = []
for txmbr in self.tsInfo:
if txmbr.po.state not in TS_INSTALL_STATES:
-@@ -2218,27 +2466,42 @@ class YumBase(depsolve.Depsolve):
+@@ -2218,27 +2482,42 @@ class YumBase(depsolve.Depsolve):
_('%s removed'), fn)
def cleanHeaders(self):
@@ -151531,7 +151898,7 @@ index 99039e0..3680356 100644
cachedir = self.conf.persistdir + "/rpmdb-indexes/"
if not os.path.exists(cachedir):
filelist = []
-@@ -2272,8 +2535,29 @@ class YumBase(depsolve.Depsolve):
+@@ -2272,8 +2551,29 @@ class YumBase(depsolve.Depsolve):
def doPackageLists(self, pkgnarrow='all', patterns=None, showdups=None,
ignore_case=False):
@@ -151563,7 +151930,7 @@ index 99039e0..3680356 100644
if showdups is None:
showdups = self.conf.showdupesfromrepos
ygh = misc.GenericHolder(iter=pkgnarrow)
-@@ -2323,10 +2607,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2323,10 +2623,22 @@ class YumBase(depsolve.Depsolve):
key = (pkg.name, pkg.arch)
if pkg.pkgtup in dinst:
reinstall_available.append(pkg)
@@ -151589,7 +151956,7 @@ index 99039e0..3680356 100644
# produce the updates list of tuples
elif pkgnarrow == 'updates':
-@@ -2461,14 +2757,13 @@ class YumBase(depsolve.Depsolve):
+@@ -2461,14 +2773,13 @@ class YumBase(depsolve.Depsolve):
def findDeps(self, pkgs):
@@ -151609,7 +151976,7 @@ index 99039e0..3680356 100644
results = {}
for pkg in pkgs:
-@@ -2495,10 +2790,22 @@ class YumBase(depsolve.Depsolve):
+@@ -2495,10 +2806,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):
@@ -151636,7 +152003,7 @@ index 99039e0..3680356 100644
sql_fields = []
for f in fields:
sql_fields.append(RPM_TO_SQLITE.get(f, f))
-@@ -2661,6 +2968,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2661,6 +2984,14 @@ class YumBase(depsolve.Depsolve):
yield (po, vs)
def searchPackageTags(self, criteria):
@@ -151651,7 +152018,7 @@ index 99039e0..3680356 100644
results = {} # name = [(criteria, taglist)]
for c in criteria:
c = c.lower()
-@@ -2677,11 +2992,16 @@ class YumBase(depsolve.Depsolve):
+@@ -2677,11 +3008,16 @@ class YumBase(depsolve.Depsolve):
return results
def searchPackages(self, fields, criteria, callback=None):
@@ -151673,7 +152040,7 @@ index 99039e0..3680356 100644
warnings.warn(_('searchPackages() will go away in a future version of Yum.\
Use searchGenerator() instead. \n'),
Errors.YumFutureDeprecationWarning, stacklevel=2)
-@@ -2700,6 +3020,19 @@ class YumBase(depsolve.Depsolve):
+@@ -2700,13 +3036,23 @@ class YumBase(depsolve.Depsolve):
def searchPackageProvides(self, args, callback=None,
callback_has_matchfor=False):
@@ -151693,7 +152060,15 @@ index 99039e0..3680356 100644
def _arg_data(arg):
if not misc.re_glob(arg):
isglob = False
-@@ -2723,7 +3056,7 @@ class YumBase(depsolve.Depsolve):
+- if arg[0] != '/':
+- canBeFile = False
+- else:
+- canBeFile = True
++ canBeFile = arg.startswith('/')
+ else:
+ isglob = True
+ canBeFile = misc.re_filename(arg)
+@@ -2723,7 +3069,7 @@ class YumBase(depsolve.Depsolve):
where = self.returnPackagesByDep(arg)
else:
usedDepString = False
@@ -151702,7 +152077,7 @@ index 99039e0..3680356 100644
self.verbose_logger.log(logginglevels.DEBUG_1,
P_('Searching %d package', 'Searching %d packages', len(where)), len(where))
-@@ -2817,25 +3150,93 @@ class YumBase(depsolve.Depsolve):
+@@ -2817,25 +3163,93 @@ class YumBase(depsolve.Depsolve):
return matches
@@ -151807,7 +152182,7 @@ index 99039e0..3680356 100644
if uservisible:
if grp.user_visible:
installed.append(grp)
-@@ -2848,12 +3249,29 @@ class YumBase(depsolve.Depsolve):
+@@ -2848,12 +3262,29 @@ class YumBase(depsolve.Depsolve):
else:
available.append(grp)
@@ -151840,7 +152215,7 @@ index 99039e0..3680356 100644
txmbrs_used = []
thesegroups = self.comps.return_groups(grpid)
-@@ -2861,20 +3279,28 @@ class YumBase(depsolve.Depsolve):
+@@ -2861,20 +3292,28 @@ class YumBase(depsolve.Depsolve):
raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
for thisgroup in thesegroups:
@@ -151871,7 +152246,7 @@ index 99039e0..3680356 100644
thesegroups = self.comps.return_groups(grpid)
if not thesegroups:
raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -2898,13 +3324,18 @@ class YumBase(depsolve.Depsolve):
+@@ -2898,13 +3337,18 @@ class YumBase(depsolve.Depsolve):
self.tsInfo.remove(txmbr.po.pkgtup)
@@ -151897,7 +152272,7 @@ index 99039e0..3680356 100644
"""
if not self.comps.has_group(grpid):
-@@ -2934,12 +3365,47 @@ class YumBase(depsolve.Depsolve):
+@@ -2934,12 +3378,47 @@ class YumBase(depsolve.Depsolve):
if 'optional' in package_types:
pkgs.extend(thisgroup.optional_packages)
@@ -151946,7 +152321,7 @@ index 99039e0..3680356 100644
except Errors.InstallError, e:
self.verbose_logger.debug(_('No package named %s available to be installed'),
pkg)
-@@ -2953,6 +3419,7 @@ class YumBase(depsolve.Depsolve):
+@@ -2953,6 +3432,7 @@ class YumBase(depsolve.Depsolve):
group_conditionals = enable_group_conditionals
count_cond_test = 0
@@ -151954,7 +152329,7 @@ index 99039e0..3680356 100644
if group_conditionals:
for condreq, cond in thisgroup.conditional_packages.iteritems():
if self.isPackageInstalled(cond):
-@@ -2997,10 +3464,14 @@ class YumBase(depsolve.Depsolve):
+@@ -2997,10 +3477,14 @@ class YumBase(depsolve.Depsolve):
return txmbrs_used
def deselectGroup(self, grpid, force=False):
@@ -151973,7 +152348,7 @@ index 99039e0..3680356 100644
if not self.comps.has_group(grpid):
raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-@@ -3035,12 +3506,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3035,12 +3519,21 @@ class YumBase(depsolve.Depsolve):
self.tsInfo.remove(pkg.pkgtup)
def getPackageObject(self, pkgtup, allow_missing=False):
@@ -152001,7 +152376,7 @@ index 99039e0..3680356 100644
# look it up in the self.localPackages first:
for po in self.localPackages:
if po.pkgtup == pkgtup:
-@@ -3049,7 +3529,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3049,7 +3542,7 @@ class YumBase(depsolve.Depsolve):
pkgs = self.pkgSack.searchPkgTuple(pkgtup)
if len(pkgs) == 0:
@@ -152010,7 +152385,7 @@ index 99039e0..3680356 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 +3545,21 @@ class YumBase(depsolve.Depsolve):
+@@ -3065,13 +3558,21 @@ class YumBase(depsolve.Depsolve):
return result
def getInstalledPackageObject(self, pkgtup):
@@ -152037,7 +152412,7 @@ index 99039e0..3680356 100644
raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
# Dito. FIXME from getPackageObject() for len() > 1 ... :)
-@@ -3079,9 +3567,11 @@ class YumBase(depsolve.Depsolve):
+@@ -3079,9 +3580,11 @@ class YumBase(depsolve.Depsolve):
return po
def gpgKeyCheck(self):
@@ -152051,7 +152426,7 @@ index 99039e0..3680356 100644
gpgkeyschecked = self.conf.cachedir + '/.gpgkeyschecked.yum'
if os.path.exists(gpgkeyschecked):
return 1
-@@ -3106,9 +3596,13 @@ class YumBase(depsolve.Depsolve):
+@@ -3106,9 +3609,13 @@ class YumBase(depsolve.Depsolve):
return 1
def returnPackagesByDep(self, depstring):
@@ -152067,7 +152442,7 @@ index 99039e0..3680356 100644
if not depstring:
return []
-@@ -3135,9 +3629,16 @@ class YumBase(depsolve.Depsolve):
+@@ -3135,9 +3642,16 @@ class YumBase(depsolve.Depsolve):
return self.pkgSack.getProvides(depname, depflags, depver).keys()
def returnPackageByDep(self, depstring):
@@ -152087,7 +152462,7 @@ index 99039e0..3680356 100644
# we get all sorts of randomness here
errstring = depstring
if type(depstring) not in types.StringTypes:
-@@ -3149,16 +3650,22 @@ class YumBase(depsolve.Depsolve):
+@@ -3149,16 +3663,22 @@ class YumBase(depsolve.Depsolve):
raise Errors.YumBaseError, _('No Package found for %s') % errstring
ps = ListPackageSack(pkglist)
@@ -152114,7 +152489,7 @@ index 99039e0..3680356 100644
if not depstring:
return []
-@@ -3184,12 +3691,47 @@ class YumBase(depsolve.Depsolve):
+@@ -3184,12 +3704,47 @@ class YumBase(depsolve.Depsolve):
return self.rpmdb.getProvides(depname, depflags, depver).keys()
@@ -152164,7 +152539,7 @@ index 99039e0..3680356 100644
if len(pkglist) == 0:
-@@ -3198,14 +3740,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3198,14 +3753,23 @@ class YumBase(depsolve.Depsolve):
if len(pkglist) == 1:
return pkglist[0]
@@ -152194,7 +152569,7 @@ index 99039e0..3680356 100644
returnlist = []
compatArchList = self.arch.get_arch_list(arch)
multiLib = []
-@@ -3222,9 +3773,9 @@ class YumBase(depsolve.Depsolve):
+@@ -3222,9 +3786,9 @@ class YumBase(depsolve.Depsolve):
singleLib.append(po)
# we now have three lists. find the best package(s) of each
@@ -152207,7 +152582,7 @@ index 99039e0..3680356 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 +3789,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3238,7 +3802,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:
@@ -152216,7 +152591,7 @@ index 99039e0..3680356 100644
if best.arch == "noarch":
returnlist.append(no)
else:
-@@ -3246,7 +3797,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3246,7 +3810,7 @@ class YumBase(depsolve.Depsolve):
if single: returnlist.append(single)
# similar for the non-multilib case
elif single:
@@ -152225,7 +152600,7 @@ index 99039e0..3680356 100644
if best.arch == "noarch":
returnlist.append(no)
else:
-@@ -3350,23 +3901,27 @@ class YumBase(depsolve.Depsolve):
+@@ -3350,23 +3914,27 @@ class YumBase(depsolve.Depsolve):
done = True
slow = next_func(slow)
@@ -152258,7 +152633,7 @@ index 99039e0..3680356 100644
def _at_groupremove(self, pattern):
" Do groupremove via. leading @ on the cmd line, for remove."
assert pattern[0] == '@'
-@@ -3398,7 +3953,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3398,7 +3966,7 @@ class YumBase(depsolve.Depsolve):
def _minus_deselect(self, pattern):
""" Remove things from the transaction, like kickstart. """
assert pattern[0] == '-'
@@ -152267,7 +152642,7 @@ index 99039e0..3680356 100644
if pat and pat[0] == '@':
pat = pat[1:]
-@@ -3437,14 +3992,61 @@ class YumBase(depsolve.Depsolve):
+@@ -3437,14 +4005,61 @@ class YumBase(depsolve.Depsolve):
if flag not in self.tsInfo.probFilterFlags:
self.tsInfo.probFilterFlags.append(flag)
@@ -152335,7 +152710,7 @@ index 99039e0..3680356 100644
pkgs = []
was_pattern = False
if po:
-@@ -3477,20 +4079,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3477,20 +4092,12 @@ class YumBase(depsolve.Depsolve):
self.verbose_logger.debug(_('Checking for virtual provide or file-provide for %s'),
arg)
@@ -152362,7 +152737,7 @@ index 99039e0..3680356 100644
else:
nevra_dict = self._nevra_kwarg_parse(kwargs)
-@@ -3577,8 +4171,8 @@ class YumBase(depsolve.Depsolve):
+@@ -3577,8 +4184,8 @@ class YumBase(depsolve.Depsolve):
continue
# make sure this shouldn't be passed to update:
@@ -152373,7 +152748,7 @@ index 99039e0..3680356 100644
txmbrs = self.update(po=po)
tx_return.extend(txmbrs)
continue
-@@ -3587,7 +4181,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3587,7 +4194,7 @@ class YumBase(depsolve.Depsolve):
# something else in the repo. Unless there is a obsoletion loop,
# at which point ignore everything.
obsoleting_pkg = None
@@ -152382,7 +152757,7 @@ index 99039e0..3680356 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 +4194,23 @@ class YumBase(depsolve.Depsolve):
+@@ -3600,23 +4207,23 @@ class YumBase(depsolve.Depsolve):
already_obs = pkgs[0]
if already_obs:
@@ -152413,7 +152788,7 @@ index 99039e0..3680356 100644
continue
# make sure we don't have a name.arch of this already installed
-@@ -3630,7 +4224,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3630,7 +4237,7 @@ class YumBase(depsolve.Depsolve):
found = True
break
if not found:
@@ -152422,7 +152797,7 @@ index 99039e0..3680356 100644
txmbrs = self.update(po=po)
tx_return.extend(txmbrs)
continue
-@@ -3719,14 +4313,33 @@ class YumBase(depsolve.Depsolve):
+@@ -3719,14 +4326,33 @@ class YumBase(depsolve.Depsolve):
return txmbr
def update(self, po=None, requiringPo=None, update_to=False, **kwargs):
@@ -152463,7 +152838,7 @@ index 99039e0..3680356 100644
# check for args - if no po nor kwargs, do them all
# if po, do it, ignore all else
# if no po do kwargs
-@@ -3765,7 +4378,12 @@ class YumBase(depsolve.Depsolve):
+@@ -3765,7 +4391,12 @@ class YumBase(depsolve.Depsolve):
if new is None:
continue
tx_return.extend(self.update(po=new))
@@ -152477,7 +152852,7 @@ index 99039e0..3680356 100644
return tx_return
# complications
-@@ -3787,7 +4405,7 @@ class YumBase(depsolve.Depsolve):
+@@ -3787,7 +4418,7 @@ class YumBase(depsolve.Depsolve):
return self._minus_deselect(kwargs['pattern'])
if kwargs['pattern'] and kwargs['pattern'][0] == '@':
@@ -152486,7 +152861,7 @@ index 99039e0..3680356 100644
arg = kwargs['pattern']
if not update_to:
-@@ -3920,6 +4538,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3920,6 +4551,18 @@ class YumBase(depsolve.Depsolve):
tx_return.append(txmbr)
for available_pkg in availpkgs:
@@ -152505,7 +152880,7 @@ index 99039e0..3680356 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 +4615,18 @@ class YumBase(depsolve.Depsolve):
+@@ -3985,11 +4628,18 @@ class YumBase(depsolve.Depsolve):
return tx_return
def remove(self, po=None, **kwargs):
@@ -152529,7 +152904,7 @@ index 99039e0..3680356 100644
if not po and not kwargs:
raise Errors.RemoveError, 'Nothing specified to remove'
-@@ -4055,17 +4692,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4055,17 +4705,19 @@ class YumBase(depsolve.Depsolve):
return tx_return
def installLocal(self, pkg, po=None, updateonly=False):
@@ -152559,7 +152934,7 @@ index 99039e0..3680356 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 +4822,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4183,16 +4835,15 @@ class YumBase(depsolve.Depsolve):
return tx_return
def reinstallLocal(self, pkg, po=None):
@@ -152584,7 +152959,7 @@ index 99039e0..3680356 100644
if not po:
try:
po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4215,9 +4853,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4215,9 +4866,19 @@ class YumBase(depsolve.Depsolve):
return self.reinstall(po=po)
def reinstall(self, po=None, **kwargs):
@@ -152607,7 +152982,7 @@ index 99039e0..3680356 100644
self._add_prob_flags(rpm.RPMPROB_FILTER_REPLACEPKG,
rpm.RPMPROB_FILTER_REPLACENEWFILES,
rpm.RPMPROB_FILTER_REPLACEOLDFILES)
-@@ -4259,16 +4907,15 @@ class YumBase(depsolve.Depsolve):
+@@ -4259,16 +4920,15 @@ class YumBase(depsolve.Depsolve):
return tx_mbrs
def downgradeLocal(self, pkg, po=None):
@@ -152632,7 +153007,7 @@ index 99039e0..3680356 100644
if not po:
try:
po = YumUrlPackage(self, ts=self.rpmdb.readOnlyTS(), url=pkg,
-@@ -4309,13 +4956,19 @@ class YumBase(depsolve.Depsolve):
+@@ -4309,13 +4969,19 @@ class YumBase(depsolve.Depsolve):
return False
def downgrade(self, po=None, **kwargs):
@@ -152659,7 +153034,17 @@ index 99039e0..3680356 100644
if not po and not kwargs:
raise Errors.DowngradeError, 'Nothing specified to downgrade'
-@@ -4457,7 +5110,7 @@ class YumBase(depsolve.Depsolve):
+@@ -4421,6 +5087,9 @@ class YumBase(depsolve.Depsolve):
+ warned_nas.add(na)
+ continue
+
++ if pkg.verEQ(lipkg):
++ continue
++
+ if pkg.verGE(lipkg):
+ if na not in warned_nas:
+ msg = _('Only Upgrade available on package: %s') % pkg
+@@ -4457,7 +5126,7 @@ class YumBase(depsolve.Depsolve):
if e and v and r:
evr = '%s:%s-%s' % (e, v, r)
elif v and r:
@@ -152668,7 +153053,7 @@ index 99039e0..3680356 100644
elif e and v:
evr = '%s:%s' % (e, v)
elif v: # e and r etc. is just too weird to print
-@@ -4500,12 +5153,24 @@ class YumBase(depsolve.Depsolve):
+@@ -4500,12 +5169,24 @@ class YumBase(depsolve.Depsolve):
return returndict
@@ -152696,7 +153081,7 @@ index 99039e0..3680356 100644
old_conf_obs = self.conf.obsoletes
self.conf.obsoletes = False
done = False
-@@ -4515,19 +5180,46 @@ class YumBase(depsolve.Depsolve):
+@@ -4515,19 +5196,46 @@ class YumBase(depsolve.Depsolve):
done = True
for pkg in transaction.trans_data:
if pkg.state == 'Downgrade':
@@ -152743,7 +153128,7 @@ index 99039e0..3680356 100644
if self.install(pkgtup=pkg.pkgtup):
done = True
for pkg in transaction.trans_data:
-@@ -4538,8 +5230,14 @@ class YumBase(depsolve.Depsolve):
+@@ -4538,8 +5246,14 @@ class YumBase(depsolve.Depsolve):
return done
def history_undo(self, transaction):
@@ -152760,7 +153145,25 @@ index 99039e0..3680356 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 :).
-@@ -4674,39 +5372,49 @@ class YumBase(depsolve.Depsolve):
+@@ -4616,7 +5330,7 @@ class YumBase(depsolve.Depsolve):
+
+ except urlgrabber.grabber.URLGrabError, e:
+ raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
+- to_unicode(str(e)))
++ exception2msg(e))
+
+ # check for a .asc file accompanying it - that's our gpg sig on the key
+ # suck it down and do the check
+@@ -4649,7 +5363,7 @@ class YumBase(depsolve.Depsolve):
+ keys_info = misc.getgpgkeyinfo(rawkey, multiple=True)
+ except ValueError, e:
+ raise Errors.YumBaseError(_('Invalid GPG Key from %s: %s') %
+- (url, to_unicode(str(e))))
++ (url, exception2msg(e)))
+ keys = []
+ for keyinfo in keys_info:
+ thiskey = {}
+@@ -4674,39 +5388,49 @@ class YumBase(depsolve.Depsolve):
if pkgs:
pkgs = sorted(pkgs)[-1]
msg = (_('Importing %s key 0x%s:\n'
@@ -152828,7 +153231,7 @@ index 99039e0..3680356 100644
user_cb_fail = False
for keyurl in keyurls:
keys = self._retrievePublicKey(keyurl, repo)
-@@ -4725,7 +5433,9 @@ class YumBase(depsolve.Depsolve):
+@@ -4725,7 +5449,9 @@ class YumBase(depsolve.Depsolve):
# Try installing/updating GPG key
self._getKeyImportMessage(info, keyurl)
rc = False
@@ -152839,7 +153242,7 @@ index 99039e0..3680356 100644
rc = True
# grab the .sig/.asc for the keyurl, if it exists
-@@ -4751,8 +5461,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4751,8 +5477,8 @@ class YumBase(depsolve.Depsolve):
ts = self.rpmdb.readOnlyTS()
result = ts.pgpImportPubkey(misc.procgpgkey(info['raw_key']))
if result != 0:
@@ -152850,7 +153253,7 @@ index 99039e0..3680356 100644
self.logger.info(_('Key imported successfully'))
key_installed = True
-@@ -4760,18 +5470,20 @@ class YumBase(depsolve.Depsolve):
+@@ -4760,18 +5486,20 @@ class YumBase(depsolve.Depsolve):
raise Errors.YumBaseError, _("Didn't install any keys")
if not key_installed:
@@ -152876,7 +153279,7 @@ index 99039e0..3680356 100644
def _getAnyKeyForRepo(self, repo, destdir, keyurl_list, is_cakey=False, callback=None):
"""
-@@ -4788,6 +5500,18 @@ class YumBase(depsolve.Depsolve):
+@@ -4788,6 +5516,18 @@ class YumBase(depsolve.Depsolve):
"""
key_installed = False
@@ -152895,7 +153298,7 @@ index 99039e0..3680356 100644
user_cb_fail = False
for keyurl in keyurl_list:
keys = self._retrievePublicKey(keyurl, repo, getSig=not is_cakey)
-@@ -4819,8 +5543,11 @@ class YumBase(depsolve.Depsolve):
+@@ -4819,8 +5559,11 @@ class YumBase(depsolve.Depsolve):
if not key_installed:
self._getKeyImportMessage(info, keyurl, keytype)
rc = False
@@ -152908,7 +153311,7 @@ index 99039e0..3680356 100644
elif callback:
rc = callback({"repo": repo, "userid": info['userid'],
"hexkeyid": info['hexkeyid'], "keyurl": keyurl,
-@@ -4835,7 +5562,8 @@ class YumBase(depsolve.Depsolve):
+@@ -4835,7 +5578,8 @@ class YumBase(depsolve.Depsolve):
# Import the key
result = misc.import_key_to_pubring(info['raw_key'], info['hexkeyid'], gpgdir=destdir)
if not result:
@@ -152918,7 +153321,7 @@ index 99039e0..3680356 100644
self.logger.info(_('Key imported successfully'))
key_installed = True
# write out the key id to imported_cakeys in the repos basedir
-@@ -4851,36 +5579,35 @@ class YumBase(depsolve.Depsolve):
+@@ -4851,36 +5595,35 @@ class YumBase(depsolve.Depsolve):
pass
if not key_installed and user_cb_fail:
@@ -152971,7 +153374,41 @@ index 99039e0..3680356 100644
self._getAnyKeyForRepo(repo, repo.gpgcadir, repo.gpgcakey, is_cakey=True, callback=callback)
def _limit_installonly_pkgs(self):
-@@ -4959,19 +5686,22 @@ class YumBase(depsolve.Depsolve):
+@@ -4927,6 +5670,7 @@ class YumBase(depsolve.Depsolve):
+ ts = self.rpmdb.readOnlyTS()
+ (cur_kernel_v, cur_kernel_r) = misc.get_running_kernel_version_release(ts)
+ 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 +5681,21 @@ class YumBase(depsolve.Depsolve):
+ if not po_names.intersection(install_only_names):
+ continue
+
+- installed = self.rpmdb.searchNevra(name=m.name)
++ if m.name not in found:
++ found[m.name] = 1
++ else:
++ found[m.name] += 1
++
++ for name in found:
++ installed = self.rpmdb.searchNevra(name=name)
+ installed = _sort_and_filter_installonly(installed)
+- if len(installed) < self.conf.installonly_limit - 1:
+- continue # we're adding one
+
+- numleft = len(installed) - self.conf.installonly_limit + 1
++ total = len(installed) + found[name]
++ if total <= self.conf.installonly_limit:
++ continue # Not adding enough to trigger.
++
++ # Number left to try and remove...
++ numleft = total - self.conf.installonly_limit
+ for po in installed:
+ if (po.version, po.release) == (cur_kernel_v, cur_kernel_r):
+ # don't remove running
+@@ -4959,19 +5712,22 @@ class YumBase(depsolve.Depsolve):
txmbr.depends_on.append(rel)
def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
@@ -153007,7 +153444,7 @@ index 99039e0..3680356 100644
if not callback:
callback = callbacks.ProcessTransNoOutputCallback()
-@@ -5114,13 +5844,19 @@ class YumBase(depsolve.Depsolve):
+@@ -5114,13 +5870,19 @@ class YumBase(depsolve.Depsolve):
return results
def add_enable_repo(self, repoid, baseurls=[], mirrorlist=None, **kwargs):
@@ -153034,7 +153471,7 @@ index 99039e0..3680356 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 +5903,15 @@ class YumBase(depsolve.Depsolve):
+@@ -5167,9 +5929,15 @@ class YumBase(depsolve.Depsolve):
def setCacheDir(self, force=False, tmpdir=None, reuse=True,
suffix='/$basearch/$releasever'):
@@ -153053,7 +153490,24 @@ index 99039e0..3680356 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:
-@@ -5220,13 +5962,24 @@ class YumBase(depsolve.Depsolve):
+@@ -5179,7 +5947,7 @@ class YumBase(depsolve.Depsolve):
+ try:
+ cachedir = misc.getCacheDir(tmpdir, reuse)
+ except (IOError, OSError), e:
+- self.logger.critical(_('Could not set cachedir: %s') % str(e))
++ self.logger.critical(_('Could not set cachedir: %s') % exception2msg(e))
+ cachedir = None
+
+ if cachedir is None:
+@@ -5190,6 +5958,7 @@ class YumBase(depsolve.Depsolve):
+ self.prerepoconf.cachedir = cachedir
+ else:
+ self.repos.setCacheDir(cachedir)
++ self._old_cachedir = self.conf.cachedir
+ self.conf.cachedir = cachedir
+ return True # We got a new cache dir
+
+@@ -5220,13 +5989,24 @@ class YumBase(depsolve.Depsolve):
self.history.write_addon_data('config-repos', myrepos)
def verify_plugins_cb(self, verify_package):
@@ -153081,7 +153535,7 @@ index 99039e0..3680356 100644
if self.tsInfo._unresolvedMembers:
if auto:
self.logger.critical(_("Dependencies not solved. Will not save unresolved transaction."))
-@@ -5234,7 +5987,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5234,7 +6014,7 @@ class YumBase(depsolve.Depsolve):
raise Errors.YumBaseError(_("Dependencies not solved. Will not save unresolved transaction."))
if not filename:
@@ -153090,27 +153544,52 @@ index 99039e0..3680356 100644
fd,filename = tempfile.mkstemp(suffix='.yumtx', prefix=prefix)
f = os.fdopen(fd, 'w')
else:
-@@ -5244,7 +5997,7 @@ class YumBase(depsolve.Depsolve):
+@@ -5244,13 +6024,17 @@ class YumBase(depsolve.Depsolve):
msg = "%s\n" % self.rpmdb.simpleVersion(main_only=True)[0]
msg += "%s\n" % self.ts.getTsFlags()
- if self.tsInfo.pkgSack is None: # rm Transactions don't have pkgSack
+- msg += "0\n"
++
+ if self.tsInfo._pkgSack is None: # Transactions have pkgSack?
- msg += "0\n"
++ msg += "1\n"
else:
- msg += "%s\n" % len(self.repos.listEnabled())
-@@ -5266,7 +6019,17 @@ class YumBase(depsolve.Depsolve):
+- msg += "%s\n" % len(self.repos.listEnabled())
++ msg += "%s\n" % (len(self.repos.listEnabled()) + 1)
+ for r in self.repos.listEnabled():
+ msg += "%s:%s:%s\n" % (r.id, len(r.sack), r.repoXML.revision)
-
- def load_ts(self, filename, ignorerpm=None, ignoremissing=None):
++ # Save what we think the future rpmdbv will be.
++ msg += "%s:%s\n" % ('installed', self.tsInfo.futureRpmDBVersion())
++
+ msg += "%s\n" % len(self.tsInfo.getMembers())
+ for txmbr in self.tsInfo.getMembers():
+ msg += txmbr._dump()
+@@ -5260,13 +6044,25 @@ class YumBase(depsolve.Depsolve):
+ except (IOError, OSError), e:
+ self._ts_save_file = None
+ if auto:
+- self.logger.critical(_("Could not save transaction file %s: %s") % (filename, str(e)))
++ self.logger.critical(_("Could not save transaction file %s: %s") % (filename, exception2msg(e)))
+ else:
+- raise Errors.YumBaseError(_("Could not save transaction file %s: %s") % (filename, str(e)))
+-
+-
+- def load_ts(self, filename, ignorerpm=None, ignoremissing=None):
- """loads a transaction from a .yumtx file"""
++ raise Errors.YumBaseError(_("Could not save transaction file %s: %s") % (filename, exception2msg(e)))
++
++
++ def load_ts(self, filename, ignorerpm=None, ignoremissing=None,
++ ignorenewrpm=None):
+ """Load a transaction from a .yumtx file.
+
+ :param filename: the name of the file to load the transaction
+ from
-+ :param ignorerpm: whether to ignore messages from rpm
++ :param ignorerpm: whether to ignore starting rpmdb version mismatch.
+ :param ignoremissing: whether to ignore that there may be
+ transaction members missing
++ :param ignorenewrpm: whether to ignore ending rpmdb version mismatch.
+ :return: the members of the loaded transaction
+ :raises: :class:`yum.Errors.YumBaseError` if there are problems
+ loading the transaction
@@ -153118,7 +153597,33 @@ index 99039e0..3680356 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
-@@ -5292,6 +6055,16 @@ class YumBase(depsolve.Depsolve):
+@@ -5276,26 +6072,45 @@ class YumBase(depsolve.Depsolve):
+ try:
+ data = open(filename, 'r').readlines()
+ except (IOError, OSError), e:
+- raise Errors.YumBaseError(_("Could not access/read saved transaction %s : %s") % (filename, str(e)))
++ raise Errors.YumBaseError(_("Could not access/read saved transaction %s : %s") % (filename, exception2msg(e)))
+
+
+ if ignorerpm is None:
+ ignorerpm = self.conf.loadts_ignorerpm
++ if ignorenewrpm is None:
++ ignorenewrpm = self.conf.loadts_ignorenewrpm
+ if ignoremissing is None:
+ ignoremissing = self.conf.loadts_ignoremissing
++
++ # Inherit this, because for the ending version to match the starting
++ # version must match.
++ if ignorerpm:
++ ignorenewrpm = True
+
+ # data format
+ # 0 == rpmdb version
+ # 1 == tsflags
+ # 2 == numrepos
+ # 3:numrepos = repos
++ # -- post 3.2.29 update: 'installed' repo. added with the values as the
++ # new rpmdb version.
# 3+numrepos = num pkgs
# 3+numrepos+1 -> EOF= txmembers
@@ -153135,7 +153640,31 @@ index 99039e0..3680356 100644
# rpm db ver
rpmv = data[0].strip()
if rpmv != str(self.rpmdb.simpleVersion(main_only=True)[0]):
-@@ -5329,6 +6102,7 @@ class YumBase(depsolve.Depsolve):
+- msg = _("rpmdb ver mismatched saved transaction version, ")
++ msg = _("rpmdb ver mismatched saved transaction version,")
+ if ignorerpm:
+ msg += _(" ignoring, as requested.")
+ self.logger.critical(_(msg))
+@@ -5318,8 +6133,17 @@ class YumBase(depsolve.Depsolve):
+ numrepos = int(data[2].strip())
+ repos = []
+ rindex=3+numrepos
++ future_rpmdbv = None
+ for r in data[3:rindex]:
+- repos.append(r.strip().split(':'))
++ repo = r.strip().split(':')
++
++ if repo and repo[0] == 'installed':
++ # This is an update hack to list the _future_ rpmdb version.
++ # Doing it this way allows older yum's to load newer ts files.
++ future_rpmdbv = "%s:%s" % (repo[1], repo[2])
++ continue
++
++ repos.append(repo)
+
+ # pkgs/txmbrs
+ numpkgs = int(data[rindex].strip())
+@@ -5329,6 +6153,7 @@ class YumBase(depsolve.Depsolve):
pkgcount = 0
pkgprob = False
curpkg = None
@@ -153143,6 +153672,67 @@ index 99039e0..3680356 100644
for l in data[pkgstart:]:
l = l.rstrip()
# our main txmbrs
+@@ -5438,6 +6263,11 @@ class YumBase(depsolve.Depsolve):
+ msg += _(" aborting.")
+ raise Errors.YumBaseError(msg)
+
++ if len(self.tsInfo) != pkgcount:
++ future_rpmdbv = None
++ if future_rpmdbv is not None:
++ self.tsInfo._check_future_rpmdbv = (pkgcount, future_rpmdbv,
++ ignorenewrpm)
+ return self.tsInfo.getMembers()
+
+ def _remove_old_deps(self):
+@@ -5470,18 +6300,6 @@ class YumBase(depsolve.Depsolve):
+ if requiring == required: # if they are self-requiring skip them
+ continue
+
+- # go through the stuff in the ts to be installed - make sure none of that needs the required pkg, either.
+- for (provn,provf,provevr) in required.provides:
+- if self.tsInfo.getNewRequires(provn, provf, provevr).keys():
+- still_needed = True
+- okay_to_remove[required] = False
+- break
+- for fn in required.filelist + required.dirlist:
+- if self.tsInfo.getNewRequires(fn, None,(None,None,None)).keys():
+- okay_to_remove[required] = False
+- still_needed = True
+- break
+-
+ #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 +6351,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
++ ok_to_remove[curpkg] = False
+ return True
++
++ # Go through the stuff in the ts to be installed - make sure
++ # none of that needs the required pkg, either.
++ for (provn,provf,provevr) in curpkg.provides:
++ if self.tsInfo.getNewRequires(provn, provf, provevr).keys():
++ ok_to_remove[pkg] = False
++ ok_to_remove[curpkg] = False
++ self.verbose_logger.log(logginglevels.DEBUG_2, _("%s is needed by a package to be installed."), curpkg)
++ return True
++ for fn in curpkg.filelist + curpkg.dirlist:
++ if self.tsInfo.getNewRequires(fn, None,(None,None,None)).keys():
++ ok_to_remove[pkg] = False
++ ok_to_remove[curpkg] = False
++ self.verbose_logger.log(logginglevels.DEBUG_2, _("%s is needed by a package to be installed."), curpkg)
++ return True
++
+ visited[curpkg] = True
+ all_leaves_visited = True
+ leaves = curpkg.requiring_packages()
+@@ -5547,4 +6382,3 @@ class YumBase(depsolve.Depsolve):
+ # Debugging output
+ self.verbose_logger.log(logginglevels.DEBUG_2, _("%s has no user-installed revdeps."), pkg)
+ return False
+-
diff --git a/yum/callbacks.py b/yum/callbacks.py
index 7ad25ce..a9a8e53 100644
--- a/yum/callbacks.py
@@ -153291,7 +153881,7 @@ index 7ad25ce..a9a8e53 100644
pass
diff --git a/yum/config.py b/yum/config.py
-index d09511f..fe7e1cb 100644
+index d09511f..2bf4f45 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -45,15 +45,18 @@ from misc import get_uuid, read_in_items_from_dot_dir
@@ -153991,8 +154581,9 @@ index d09511f..fe7e1cb 100644
commands = ListOption()
exclude = ListOption()
- failovermethod = Option('roundrobin')
+- proxy = UrlOption(schemes=('http', 'ftp', 'https'), allow_none=True)
+ failovermethod = Option(__main_failovermethod_default__)
- proxy = UrlOption(schemes=('http', 'ftp', 'https'), allow_none=True)
++ proxy = UrlOption(default=False, schemes=('http', 'ftp', 'https'), allow_none=True)
proxy_username = Option()
proxy_password = Option()
username = Option()
@@ -154020,7 +154611,7 @@ index d09511f..fe7e1cb 100644
alwaysprompt = BoolOption(True)
exactarch = BoolOption(True)
tolerant = BoolOption(True)
-@@ -681,11 +778,16 @@ class YumConf(StartupConf):
+@@ -681,11 +778,17 @@ class YumConf(StartupConf):
enable_group_conditionals = BoolOption(True)
groupremove_leaf_only = BoolOption(False)
group_package_types = ListOption(['mandatory', 'default'])
@@ -154034,10 +154625,11 @@ index d09511f..fe7e1cb 100644
+ ip_resolve = CaselessSelectionOption(
+ allowed = ('ipv4', 'ipv6', 'whatever'),
+ mapper = {'4': 'ipv4', '6': 'ipv6'})
++ max_connections = IntOption(0)
http_caching = SelectionOption('all', ('none', 'packages', 'all'))
metadata_expire = SecondsOption(60 * 60 * 6) # Time in seconds (6h).
-@@ -698,12 +800,14 @@ class YumConf(StartupConf):
+@@ -698,12 +801,14 @@ class YumConf(StartupConf):
# Note that "instant" is the old behaviour, but group:primary is very
# similar but better :).
mdpolicy = ListOption(['group:primary'])
@@ -154054,7 +154646,7 @@ index d09511f..fe7e1cb 100644
color = SelectionOption('auto', ('auto', 'never', 'always'),
mapper={'on' : 'always', 'yes' : 'always',
-@@ -715,11 +819,13 @@ class YumConf(StartupConf):
+@@ -715,11 +820,13 @@ class YumConf(StartupConf):
color_list_installed_newer = Option('bold,yellow')
color_list_installed_reinstall = Option('normal')
color_list_installed_extra = Option('bold,red')
@@ -154068,7 +154660,7 @@ index d09511f..fe7e1cb 100644
color_update_installed = Option('normal')
color_update_local = Option('bold')
-@@ -731,6 +837,7 @@ class YumConf(StartupConf):
+@@ -731,6 +838,7 @@ class YumConf(StartupConf):
sslverify = BoolOption(True)
sslclientcert = Option()
sslclientkey = Option()
@@ -154076,7 +154668,11 @@ index d09511f..fe7e1cb 100644
history_record = BoolOption(True)
history_record_packages = ListOption(['yum', 'rpm'])
-@@ -747,15 +854,25 @@ class YumConf(StartupConf):
+@@ -744,18 +852,29 @@ class YumConf(StartupConf):
+
+ loadts_ignoremissing = BoolOption(False)
+ loadts_ignorerpm = BoolOption(False)
++ loadts_ignorenewrpm = BoolOption(False)
clean_requirements_on_remove = BoolOption(False)
@@ -154102,7 +154698,7 @@ index d09511f..fe7e1cb 100644
output = '[main]\n'
# we exclude all vars which start with _ or are in this list:
excluded_vars = ('cfg', 'uid', 'yumvar', 'progress_obj', 'failure_obj',
-@@ -778,14 +895,12 @@ class YumConf(StartupConf):
+@@ -778,14 +897,12 @@ class YumConf(StartupConf):
return output
class RepoConf(BaseConfig):
@@ -154120,7 +154716,7 @@ index d09511f..fe7e1cb 100644
ck = self.__cached_keys
if not isinstance(self, RepoConf):
ck = set()
-@@ -823,39 +938,43 @@ class RepoConf(BaseConfig):
+@@ -823,39 +940,44 @@ class RepoConf(BaseConfig):
bandwidth = Inherit(YumConf.bandwidth)
throttle = Inherit(YumConf.throttle)
timeout = Inherit(YumConf.timeout)
@@ -154142,6 +154738,7 @@ index d09511f..fe7e1cb 100644
+ ssl_check_cert_permissions = Inherit(YumConf.ssl_check_cert_permissions)
skip_if_unavailable = BoolOption(False)
++ async = BoolOption(True)
class VersionGroupConf(BaseConfig):
+ """Option definitions for version groups."""
@@ -154175,7 +154772,7 @@ index d09511f..fe7e1cb 100644
# ' xemacs syntax hack
-@@ -876,20 +995,24 @@ def readStartupConfig(configfile, root):
+@@ -876,20 +998,24 @@ def readStartupConfig(configfile, root):
raise Errors.ConfigError("All plugin search paths must be absolute")
# Stuff this here to avoid later re-parsing
startupconf._parser = parser
@@ -154206,7 +154803,7 @@ index d09511f..fe7e1cb 100644
# ' xemacs syntax hack
-@@ -956,6 +1079,12 @@ def readMainConfig(startupconf):
+@@ -956,6 +1082,12 @@ def readMainConfig(startupconf):
return yumconf
def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
@@ -154219,7 +154816,7 @@ index d09511f..fe7e1cb 100644
parser = ConfigParser()
confpp_obj = ConfigPreProcessor(configfile)
try:
-@@ -970,17 +1099,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
+@@ -970,17 +1102,16 @@ def readVersionGroupsConfig(configfile="/etc/yum/version-groups.conf"):
def getOption(conf, section, name, option):
@@ -154247,7 +154844,7 @@ index d09511f..fe7e1cb 100644
try:
val = conf.get(section, name)
except (NoSectionError, NoOptionError):
-@@ -1028,7 +1156,10 @@ def _getsysver(installroot, distroverpkg):
+@@ -1028,7 +1159,10 @@ def _getsysver(installroot, distroverpkg):
if idx.count() == 0:
releasever = '$releasever'
else:
@@ -154259,7 +154856,7 @@ index d09511f..fe7e1cb 100644
releasever = hdr['version']
del hdr
del idx
-@@ -1036,13 +1167,12 @@ def _getsysver(installroot, distroverpkg):
+@@ -1036,13 +1170,12 @@ def _getsysver(installroot, distroverpkg):
return releasever
def writeRawRepoFile(repo,only=None):
@@ -154278,7 +154875,7 @@ index d09511f..fe7e1cb 100644
if not _use_iniparse:
return
-@@ -1069,7 +1199,7 @@ def writeRawRepoFile(repo,only=None):
+@@ -1069,7 +1202,7 @@ def writeRawRepoFile(repo,only=None):
# If the value is the same, but just interpreted ... when we don't want
# to keep the interpreted values.
if (name in ini[section_id] and
@@ -155525,8 +156122,41 @@ index 0000000..625ee66
+ break
+
+ return returns.values()
+diff --git a/yum/metalink.py b/yum/metalink.py
+index aaa4f25..51895fd 100755
+--- a/yum/metalink.py
++++ b/yum/metalink.py
+@@ -180,6 +180,7 @@ class MetaLinkRepoMD:
+ self.repomd = None
+ self.old_repomds = []
+ self.mirrors = []
++ self._host2mc = {}
+ if not os.path.exists(filename):
+ raise MetaLinkRepoErrorParseFail, "File %s does not exist" %filename
+ try:
+@@ -225,8 +226,6 @@ class MetaLinkRepoMD:
+ # Get the hostname from a url, stripping away any usernames/passwords
+ # Borrowd from fastestmirror
+ url2host = lambda url: url.split('/')[2].split('@')[-1]
+- hosts = set() # Don't want multiple urls for one host in plain mode
+- # The list of URLs is sorted, so http is before ftp
+
+ for mirror in self.mirrors:
+ url = mirror.url
+@@ -237,9 +236,9 @@ class MetaLinkRepoMD:
+ elif (url.startswith("http:") or url.startswith("ftp:") or
+ url.startswith("https:")):
+ host = url2host(url)
+- if host in hosts:
++ if host in self._host2mc:
+ continue
+- hosts.add(host)
++ self._host2mc[host] = mirror.max_connections
+ else:
+ continue
+
diff --git a/yum/misc.py b/yum/misc.py
-index 2f6ddfe..5321003 100644
+index 2f6ddfe..59aff5d 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -8,6 +8,7 @@ import os
@@ -155555,7 +156185,16 @@ index 2f6ddfe..5321003 100644
def getgpgkeyinfo(rawkey, multiple=False):
'''Return a dict of info for the given ASCII armoured key text
-@@ -940,14 +952,16 @@ def unlink_f(filename):
+@@ -746,6 +758,8 @@ def _decompress_chunked(source, dest, ztype):
+ data = s_fn.read(1024000)
+ except IOError:
+ break
++ except EOFError:
++ break
+
+ if not data: break
+
+@@ -940,14 +954,16 @@ def unlink_f(filename):
if e.errno != errno.ENOENT:
raise
@@ -155576,17 +156215,59 @@ index 2f6ddfe..5321003 100644
def _getloginuid():
""" Get the audit-uid/login-uid, if available. None is returned if there
-@@ -1112,10 +1126,12 @@ def decompress(filename, dest=None, fn_only=False, check_timestamps=False):
- if check_timestamps:
- fi = stat_f(filename)
- fo = stat_f(out)
+@@ -992,9 +1008,17 @@ def setup_locale(override_codecs=True, override_time=False):
+ locale.setlocale(locale.LC_ALL, 'C')
+
+ if override_codecs:
+- import codecs
+- sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
+- sys.stdout.errors = 'replace'
++ class UnicodeStream:
++ def __init__(self, stream, encoding):
++ self.stream = stream
++ self.encoding = encoding
++ def write(self, s):
++ if isinstance(s, unicode):
++ s = s.encode(self.encoding, 'replace')
++ self.stream.write(s)
++ def __getattr__(self, name):
++ return getattr(self.stream, name)
++ sys.stdout = UnicodeStream(sys.stdout, locale.getpreferredencoding())
+
+
+ def get_my_lang_code():
+@@ -1105,17 +1129,26 @@ def decompress(filename, dest=None, fn_only=False, check_timestamps=False):
+ out = filename.replace('.xz', '')
+
+ else:
+- out = filename # returning the same file since it is not compressed
+- ztype = None
++ return filename # returning the same file since it is not compressed
+
+- if ztype and not fn_only:
+- if check_timestamps:
+- fi = stat_f(filename)
+- fo = stat_f(out)
- if fi and fo and fo.st_mtime > fi.st_mtime:
-+ if fi and fo and fo.st_mtime == fi.st_mtime:
++ if check_timestamps:
++ fi = stat_f(filename)
++ fo = stat_f(out)
++ if fi and fo:
++ if fo.st_mtime == fi.st_mtime:
return out
++ if fn_only:
++ # out exists but not valid
++ return None
- _decompress_chunked(filename, out, ztype)
-+ if check_timestamps and fi:
-+ os.utime(out, (fi.st_mtime, fi.st_mtime))
+- _decompress_chunked(filename, out, ztype)
++ if not fn_only:
++ try:
++ _decompress_chunked(filename, out, ztype)
++ if check_timestamps and fi:
++ os.utime(out, (fi.st_mtime, fi.st_mtime))
++ except:
++ unlink_f(out)
++ raise
return out
@@ -155886,6 +156567,23 @@ index 5ef9951..da31971 100644
def _is_pre_req(self, flag):
"""check the flags for a requirement, return 1 or 0 whether or not requires
+diff --git a/yum/parser.py b/yum/parser.py
+index fccf528..f443ce7 100644
+--- a/yum/parser.py
++++ b/yum/parser.py
+@@ -73,7 +73,11 @@ class ConfigPreProcessor:
+ if scheme == '':
+ # check it to make sure it's not a relative file url
+ if configfile[0] != '/':
+- configfile = os.getcwd() + '/' + configfile
++ try:
++ rootdir = os.getcwd() + "/"
++ except:
++ rootdir = "/"
++ configfile = rootdir + configfile
+ url = 'file://' + configfile
+ else:
+ url = configfile
diff --git a/yum/pgpmsg.py b/yum/pgpmsg.py
index ee825c6..dae60c9 100644
--- a/yum/pgpmsg.py
@@ -156454,6 +157152,92 @@ index bfc49b7..9ddcae6 100644
a = parsever(a)
b = parsever(b)
+diff --git a/yum/repos.py b/yum/repos.py
+index 3793bad..4b1d52e 100644
+--- a/yum/repos.py
++++ b/yum/repos.py
+@@ -22,6 +22,7 @@ import misc
+
+ import Errors
+ from packageSack import MetaSack
++import urlgrabber.grabber
+
+ from weakref import proxy as weakref
+
+@@ -67,6 +68,38 @@ class RepoStorage:
+ self._cache_enabled_repos = []
+ self.quick_enable_disable = {}
+
++ def retrieveAllMD(self):
++ """ Download metadata for all enabled repositories,
++ based on mdpolicy.
++ """
++
++ if not hasattr(urlgrabber.grabber, 'parallel_wait'):
++ return
++
++ repos = []
++ for repo in self.listEnabled():
++ if repo._async and repo._commonLoadRepoXML(repo):
++ mdtypes = repo._mdpolicy2mdtypes()
++ downloading = repo._commonRetrieveDataMD_list(mdtypes)
++ repos.append((repo, downloading, [False]))
++
++ # with sizes first, then without sizes..
++ for no_size in (False, True):
++ for repo, downloading, error in repos:
++ def failfunc(obj, error=error):
++ error[0] = True
++ for (ndata, nmdtype) in downloading:
++ if (ndata.size is None) == no_size:
++ repo._retrieveMD(nmdtype, async=True, failfunc=failfunc)
++ urlgrabber.grabber.parallel_wait()
++
++ # done or revert
++ for repo, downloading, error in repos:
++ if error[0]: # some MD failed?
++ repo._revertOldRepoXML()
++ else:
++ repo._commonRetrieveDataMD_done(downloading)
++
+ def doSetup(self, thisrepo = None):
+
+ self.ayum.plugins.run('prereposetup')
+@@ -89,6 +122,7 @@ class RepoStorage:
+ self.disableRepo(repo.id)
+
+ self._setup = True
++ self.retrieveAllMD()
+ self.ayum.plugins.run('postreposetup')
+
+ def __str__(self):
+@@ -223,8 +257,9 @@ class RepoStorage:
+
+ self._cachedir = cachedir
+ for repo in self.repos.values():
+- repo.old_base_cache_dir = repo.basecachedir
+- repo.basecachedir = cachedir
++ if cachedir != repo.basecachedir:
++ repo.old_base_cache_dir = repo.basecachedir
++ repo.basecachedir = cachedir
+
+
+ def setProgressBar(self, obj):
+@@ -288,6 +323,14 @@ class RepoStorage:
+ else:
+ data = [ mdtype ]
+
++ if hasattr(urlgrabber.grabber, 'parallel_wait'):
++ # download all metadata in parallel
++ for repo in myrepos:
++ if repo._async:
++ sack = repo.getPackageSack()
++ sack._retrieve_async(repo, data)
++ urlgrabber.grabber.parallel_wait()
++
+ for repo in myrepos:
+ sack = repo.getPackageSack()
+ try:
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index e289a7a..ed8e3d1 100644
--- a/yum/rpmsack.py
@@ -156627,10 +157411,21 @@ index 9b265f9..24a1f9e 100644
+
+ self.display.verify_txmbr(self.base, txmbr, count)
diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
-index 8a6f6f3..f6df93e 100644
+index 8a6f6f3..ba929de 100644
--- a/yum/sqlitesack.py
+++ b/yum/sqlitesack.py
-@@ -406,7 +406,7 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
+@@ -382,6 +382,10 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
+
+ def returnPrco(self, prcotype, printable=False):
+ prcotype = _share_data(prcotype)
++ if prcotype == 'strong_requires':
++ # pkg not installed so we don't know require flags yet
++ # returning all requires should work in most cases
++ prcotype = 'requires'
+ if isinstance(self.prco[prcotype], tuple):
+ sql = "SELECT name, version, release, epoch, flags " \
+ "FROM %s WHERE pkgKey = ?" % prcotype
+@@ -406,7 +410,7 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
requires = []
for ob in cur:
pre = "0"
@@ -156639,7 +157434,7 @@ index 8a6f6f3..f6df93e 100644
pre = "1"
prco_set = (_share_data(ob['name']), _share_data(ob['flags']),
(_share_data(ob['epoch']),
-@@ -917,8 +917,7 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
+@@ -917,8 +921,7 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
# ultra simple optimization
if misc.re_primary_filename(name):
@@ -156650,7 +157445,7 @@ index 8a6f6f3..f6df93e 100644
if len(self.filelistsdb) == 0:
# grab repo object from primarydb and force filelists population in this sack using repo
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
-index 4d89d83..97de8f0 100644
+index 4d89d83..b584338 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -87,7 +87,8 @@ class TransactionData:
@@ -156663,7 +157458,17 @@ index 4d89d83..97de8f0 100644
self.pkgSackPackages = 0
self.localSack = PackageSack()
self._inSack = GetProvReqOnlyPackageSack()
-@@ -115,6 +116,18 @@ class TransactionData:
+@@ -105,6 +106,9 @@ class TransactionData:
+ self.reinstalled = []
+ self.downgraded = []
+ self.failed = []
++
++ self._future_rpmdbv = None
++ self._check_future_rpmdbv = None
+
+ def __len__(self):
+ return len(self.pkgdict)
+@@ -115,6 +119,18 @@ class TransactionData:
else:
return iter(self.getMembers())
@@ -156682,7 +157487,7 @@ index 4d89d83..97de8f0 100644
def debugprint(self, msg):
if self.debug:
print msg
-@@ -208,7 +221,9 @@ class TransactionData:
+@@ -208,7 +224,9 @@ class TransactionData:
txmbrs = self.matchNaevr(na[0], na[1])
if not txmbrs:
@@ -156693,7 +157498,7 @@ index 4d89d83..97de8f0 100644
pkgs = []
else:
pkgs = self.pkgSack.returnPackages(patterns=[pattern])
-@@ -547,9 +562,10 @@ class TransactionData:
+@@ -547,9 +565,10 @@ class TransactionData:
return txmbr
@@ -156706,6 +157511,27 @@ index 4d89d83..97de8f0 100644
def getNewProvides(self, name, flag=None, version=(None, None, None)):
"""return dict { packages -> list of matching provides }
+@@ -619,6 +638,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. """
++
++ if self._future_rpmdbv is not None:
++ sc, ret = self._future_rpmdbv
++ if sc == self.state_counter:
++ return ret
++
+ pkgs = self.rpmdb.returnPackages()
+ _reinstalled_pkgtups = {}
+ for txmbr in self.getMembersWithState(None, TS_INSTALL_STATES):
+@@ -658,6 +683,7 @@ class TransactionData:
+
+ self.rpmdb.transactionCachePackageChecksums(pkg_checksum_tups)
+
++ self._future_rpmdbv = (self.state_counter, main)
+ return main
+
+ def findObsoletedByThisMember(self, txmbr):
diff --git a/yum/update_md.py b/yum/update_md.py
index 2cb1acb..7da6a08 100644
--- a/yum/update_md.py
@@ -156726,7 +157552,7 @@ index 2cb1acb..7da6a08 100644
self._md[item] = val
diff --git a/yum/yumRepo.py b/yum/yumRepo.py
-index e5e9ece..62e53f8 100644
+index e5e9ece..57a1a29 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -20,10 +20,12 @@ import time
@@ -156750,8 +157576,131 @@ index e5e9ece..62e53f8 100644
from constants import *
import metalink
-@@ -434,22 +437,13 @@ class YumRepository(Repository, config.RepoConf):
- if self.proxy not in empty:
+@@ -121,6 +124,25 @@ class YumPackageSack(packageSack.PackageSack):
+ # umm, wtf?
+ pass
+
++ def _retrieve_async(self, repo, data):
++ """ Just schedule the metadata downloads """
++
++ for item in data:
++ if item in self.added.get(repo, []):
++ continue
++ if item == 'metadata':
++ mydbtype = 'primary_db'
++ elif item == 'filelists':
++ mydbtype = 'filelists_db'
++ elif item == 'otherdata':
++ mydbtype = 'other_db'
++ else:
++ continue
++
++ if self._check_db_version(repo, mydbtype):
++ if not self._check_uncompressed_db(repo, mydbtype):
++ repo._retrieveMD(mydbtype, async=True, failfunc=None)
++
+ def populate(self, repo, mdtype='metadata', callback=None, cacheonly=0):
+ if mdtype == 'all':
+ data = ['metadata', 'filelists', 'otherdata']
+@@ -162,6 +184,25 @@ class YumPackageSack(packageSack.PackageSack):
+ continue
+
+ if self._check_db_version(repo, mydbtype):
++ # Use gen decompression on DB files. Keeps exactly what we
++ # downloaded in the download dir.
++
++ # Backwards compat. ... try the old uncompressed version first.
++ db_un_fn = self._check_uncompressed_db(repo, mydbtype)
++ if not db_un_fn:
++ db_un_fn = self._check_uncompressed_db_gen(repo, mydbtype)
++
++ if not db_un_fn:
++ db_fn = repo._retrieveMD(mydbtype)
++ if db_fn:
++ db_un_fn = self._check_uncompressed_db_gen(repo,
++ mydbtype)
++ if not db_un_fn: # Shouldn't happen?
++ raise URLGrabError(-1, 'Check uncompressed DB failed')
++
++ dobj = repo.cacheHandler.open_database(db_un_fn)
++
++ elif self._check_db_version(repo, mydbtype):
+ # see if we have the uncompressed db and check it's checksum vs the openchecksum
+ # if not download the compressed file
+ # decompress it
+@@ -180,7 +221,17 @@ class YumPackageSack(packageSack.PackageSack):
+
+ else:
+ repo._xml2sqlite_local = True
++ # Download...
+ xml = repo_get_function()
++
++ # Use generated dir. and handle compression types metadata
++ # parser doesn't understand.
++ gen = mymdtype + '.xml'
++ ret = misc.repo_gen_decompress(xml, gen, cached=repo.cache)
++ if not ret:
++ raise URLGrabError(-1, 'Decompress DB failed')
++ xml = ret
++ # Convert XML => .sqlite
+ xmldata = repo.repoXML.getData(mymdtype)
+ (ctype, csum) = xmldata.checksum
+ dobj = repo_cache_function(xml, csum)
+@@ -193,6 +244,25 @@ class YumPackageSack(packageSack.PackageSack):
+ # get rid of all this stuff we don't need now
+ del repo.cacheHandler
+
++ def _check_uncompressed_db_gen(self, repo, mdtype, fast=True):
++ """return file name of db in gen/ dir if good, None if not"""
++
++ mydbdata = repo.repoXML.getData(mdtype)
++ (r_base, remote) = mydbdata.location
++ fname = os.path.basename(remote)
++ compressed_fn = repo.cachedir + '/' + fname
++ db_un_fn = mdtype + '.sqlite'
++
++ if not repo._checkMD(compressed_fn, mdtype, data=mydbdata,
++ check_can_fail=fast, fast=fast):
++ return None
++
++ ret = misc.repo_gen_decompress(compressed_fn, db_un_fn,
++ cached=repo.cache)
++ if ret:
++ return self._check_uncompressed_db_fn(repo, mdtype, ret)
++ return None
++
+ def _check_uncompressed_db(self, repo, mdtype):
+ """return file name of uncompressed db is good, None if not"""
+ mydbdata = repo.repoXML.getData(mdtype)
+@@ -201,9 +271,11 @@ class YumPackageSack(packageSack.PackageSack):
+ compressed_fn = repo.cachedir + '/' + fname
+ db_un_fn = misc.decompress(compressed_fn, fn_only=True)
+
++ return self._check_uncompressed_db_fn(repo, mdtype, db_un_fn)
++
++ def _check_uncompressed_db_fn(self, repo, mdtype, db_un_fn):
+ result = None
+
+- repo._preload_md_from_system_cache(os.path.basename(db_un_fn))
+ if os.path.exists(db_un_fn):
+ if skip_old_DBMD_check and repo._using_old_MD:
+ return db_un_fn
+@@ -285,6 +357,7 @@ class YumRepository(Repository, config.RepoConf):
+
+ self._grabfunc = None
+ self._grab = None
++ self._async = False
+
+ def __cmp__(self, other):
+ """ Sort yum repos. by cost, and then by alphanumeric on their id. """
+@@ -431,25 +504,18 @@ class YumRepository(Repository, config.RepoConf):
+ self._proxy_dict = {} # zap it
+ proxy_string = None
+ empty = (None, '_none_', '')
+- if self.proxy not in empty:
++ if self.proxy is None: # got 'proxy=_none_'
++ proxy_string = '' # this disables default proxies
++ elif self.proxy:
proxy_string = '%s' % self.proxy
if self.proxy_username not in empty:
- proxy_parsed = urlparse.urlsplit(self.proxy, allow_fragments=0)
@@ -156778,7 +157727,29 @@ index e5e9ece..62e53f8 100644
if proxy_string is not None:
self._proxy_dict['http'] = proxy_string
-@@ -499,6 +493,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -488,8 +554,20 @@ class YumRepository(Repository, config.RepoConf):
+ copy_local=self.copy_local,
+ reget='simple',
+ **ugopts)
++ def add_mc(url):
++ host = urlparse.urlsplit(url).netloc
++ mc = self.metalink_data._host2mc.get(host)
++ if mc > 0:
++ url = {
++ 'mirror': misc.to_utf8(url),
++ 'kwargs': { 'max_connections': mc },
++ }
++ return url
++ urls = self.urls
++ if self.metalink:
++ urls = map(add_mc, urls)
+
+- self._grab = mgclass(self._grabfunc, self.urls,
++ self._grab = mgclass(self._grabfunc, urls,
+ failure_callback=self.mirror_failure_obj)
+
+ def _default_grabopts(self, cache=True):
+@@ -499,6 +577,7 @@ class YumRepository(Repository, config.RepoConf):
'throttle': self.throttle,
'proxies': self.proxy_dict,
'timeout': self.timeout,
@@ -156786,7 +157757,16 @@ index e5e9ece..62e53f8 100644
'http_headers': tuple(self.__headersListFromDict(cache=cache)),
'ssl_verify_peer': self.sslverify,
'ssl_verify_host': self.sslverify,
-@@ -796,6 +791,16 @@ class YumRepository(Repository, config.RepoConf):
+@@ -751,7 +830,7 @@ class YumRepository(Repository, config.RepoConf):
+
+ def _getFile(self, url=None, relative=None, local=None, start=None, end=None,
+ copy_local=None, checkfunc=None, text=None, reget='simple',
+- cache=True, size=None):
++ cache=True, size=None, **kwargs):
+ """retrieve file from the mirrorgroup for the repo
+ relative to local, optionally get range from
+ start to end, also optionally retrieve from a specific baseurl"""
+@@ -796,6 +875,16 @@ class YumRepository(Repository, config.RepoConf):
except Errors.MediaError, e:
verbose_logger.log(logginglevels.DEBUG_2, "Error getting package from media; falling back to url %s" %(e,))
@@ -156803,7 +157783,34 @@ index e5e9ece..62e53f8 100644
if url and scheme != "media":
ugopts = self._default_grabopts(cache=cache)
ug = URLGrabber(progress_obj = self.callback,
-@@ -1020,7 +1025,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -835,7 +924,8 @@ class YumRepository(Repository, config.RepoConf):
+ reget = reget,
+ checkfunc=checkfunc,
+ http_headers=headers,
+- size=size
++ size=size,
++ **kwargs
+ )
+ except URLGrabError, e:
+ errstr = "failure: %s from %s: %s" % (relative, self.id, e)
+@@ -847,7 +937,7 @@ class YumRepository(Repository, config.RepoConf):
+ return result
+ __get = _getFile
+
+- def getPackage(self, package, checkfunc=None, text=None, cache=True):
++ def getPackage(self, package, checkfunc=None, text=None, cache=True, **kwargs):
+ remote = package.relativepath
+ local = package.localPkg()
+ basepath = package.basepath
+@@ -864,6 +954,7 @@ class YumRepository(Repository, config.RepoConf):
+ text=text,
+ cache=cache,
+ size=package.size,
++ **kwargs
+ )
+
+ def getHeader(self, package, checkfunc = None, reget = 'simple',
+@@ -1020,7 +1111,7 @@ class YumRepository(Repository, config.RepoConf):
if grab_can_fail:
return None
raise Errors.RepoError, 'Error downloading file %s: %s' % (local, e)
@@ -156812,7 +157819,7 @@ index e5e9ece..62e53f8 100644
misc.unlink_f(tfname)
if grab_can_fail:
return None
-@@ -1260,6 +1265,9 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1260,6 +1351,9 @@ class YumRepository(Repository, config.RepoConf):
return True
def _check_db_version(self, mdtype, repoXML=None):
@@ -156822,7 +157829,116 @@ index e5e9ece..62e53f8 100644
if repoXML is None:
repoXML = self.repoXML
if mdtype in repoXML.repoData:
-@@ -1451,12 +1459,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1277,11 +1371,11 @@ class YumRepository(Repository, config.RepoConf):
+ return None
+
+ if not file_check:
+- compressed = dbmdtype.endswith("_db")
+- local = self._get_mdtype_fname(data, compressed)
++ compressed = False
++ local = self._get_mdtype_fname(data)
+ else:
+ compressed = False
+- local = self._get_mdtype_fname(data, False)
++ local = self._get_mdtype_fname(data)
+ if not os.path.exists(local):
+ local = misc.decompress(local, fn_only=True)
+ compressed = True
+@@ -1302,6 +1396,17 @@ class YumRepository(Repository, config.RepoConf):
+ into the delete list, this means metadata can change filename
+ without us leaking it. """
+
++ downloading = self._commonRetrieveDataMD_list(mdtypes)
++ for (ndata, nmdtype) in downloading:
++ if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
++ self._revertOldRepoXML()
++ return False
++ self._commonRetrieveDataMD_done(downloading)
++ return True
++
++ def _commonRetrieveDataMD_list(self, mdtypes):
++ """ Return a list of metadata to be retrieved """
++
+ def _mdtype_eq(omdtype, odata, nmdtype, ndata):
+ """ Check if two returns from _get_mdtype_data() are equal. """
+ if ndata is None:
+@@ -1333,8 +1438,7 @@ class YumRepository(Repository, config.RepoConf):
+
+ # Inited twice atm. ... sue me
+ self._oldRepoMDData['new_MD_files'] = []
+- downloading_with_size = []
+- downloading_no_size = []
++ downloading = []
+ for mdtype in all_mdtypes:
+ (nmdtype, ndata) = self._get_mdtype_data(mdtype)
+
+@@ -1371,43 +1475,16 @@ class YumRepository(Repository, config.RepoConf):
+ # No old repomd data, but we might still have uncompressed MD
+ if self._groupCheckDataMDValid(ndata, nmdtype, mdtype):
+ continue
++ downloading.append((ndata, nmdtype))
++ return downloading
+
+- if ndata.size is None:
+- downloading_no_size.append((ndata, nmdtype))
+- else:
+- downloading_with_size.append((ndata, nmdtype))
+-
+- if len(downloading_with_size) == 1:
+- downloading_no_size.extend(downloading_with_size)
+- downloading_with_size = []
+-
+- remote_size = 0
+- local_size = 0
+- for (ndata, nmdtype) in downloading_with_size: # Get total size...
+- remote_size += int(ndata.size)
+-
+- for (ndata, nmdtype) in downloading_with_size:
+- urlgrabber.progress.text_meter_total_size(remote_size, local_size)
+- if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
+- self._revertOldRepoXML()
+- return False
+- local_size += int(ndata.size)
+- urlgrabber.progress.text_meter_total_size(0)
+- for (ndata, nmdtype) in downloading_no_size:
+- if not self._retrieveMD(nmdtype, retrieve_can_fail=True):
+- self._revertOldRepoXML()
+- return False
++ def _commonRetrieveDataMD_done(self, downloading):
++ """ Uncompress the downloaded metadata """
+
+- for (ndata, nmdtype) in downloading_with_size + downloading_no_size:
++ for (ndata, nmdtype) in downloading:
+ local = self._get_mdtype_fname(ndata, False)
+- if nmdtype.endswith("_db"): # Uncompress any compressed files
+- dl_local = local
+- local = misc.decompress(dl_local)
+- misc.unlink_f(dl_local)
+ self._oldRepoMDData['new_MD_files'].append(local)
+-
+ self._doneOldRepoXML()
+- return True
+
+ def _groupLoadRepoXML(self, text=None, mdtypes=None):
+ """ Retrieve the new repomd.xml from the repository, then check it
+@@ -1421,7 +1498,7 @@ class YumRepository(Repository, config.RepoConf):
+ self._commonRetrieveDataMD(mdtypes)
+
+ def _mdpolicy2mdtypes(self):
+- md_groups = {'instant' : [],
++ md_groups = {'instant' : ['__None__'],
+ 'group:primary' : ['primary'],
+ 'group:small' : ["primary", "updateinfo"],
+ 'group:main' : ["primary", "group", "filelists",
+@@ -1436,6 +1513,7 @@ class YumRepository(Repository, config.RepoConf):
+ if not mdtypes or 'group:all' in mdtypes:
+ mdtypes = None
+ else:
++ mdtypes.discard("__None__")
+ mdtypes = sorted(list(mdtypes))
+ return mdtypes
+
+@@ -1451,12 +1529,7 @@ class YumRepository(Repository, config.RepoConf):
def _getRepoXML(self):
if self._repoXML:
return self._repoXML
@@ -156836,19 +157952,95 @@ index e5e9ece..62e53f8 100644
return self._repoXML
-@@ -1614,7 +1617,7 @@ class YumRepository(Repository, config.RepoConf):
+@@ -1514,7 +1587,7 @@ class YumRepository(Repository, config.RepoConf):
+ return self._checkMD(fn, mdtype, openchecksum)
+
+ def _checkMD(self, fn, mdtype, openchecksum=False,
+- data=None, check_can_fail=False):
++ data=None, check_can_fail=False, fast=False):
+ """ Internal function, use .checkMD() from outside yum. """
+
+ thisdata = data # So the argument name is nicer
+@@ -1537,6 +1610,18 @@ class YumRepository(Repository, config.RepoConf):
+ if size is not None:
+ size = int(size)
+
++ if fast:
++ fsize = misc.stat_f(file)
++ if fsize is None: # File doesn't exist...
++ return None
++ if size is None:
++ return 1
++ if size == fsize.st_size:
++ return 1
++ if check_can_fail:
++ return None
++ raise URLGrabError(-1, 'Metadata file does not match size')
++
+ try: # get the local checksum
+ l_csum = self._checksum(r_ctype, file, datasize=size)
+ except Errors.RepoError, e:
+@@ -1551,15 +1636,13 @@ class YumRepository(Repository, config.RepoConf):
+ return None
+ raise URLGrabError(-1, 'Metadata file does not match checksum')
+
+-
+-
+ def retrieveMD(self, mdtype):
+ """base function to retrieve metadata files from the remote url
+ returns the path to the local metadata file of a 'mdtype'
+ mdtype can be 'primary', 'filelists', 'other' or 'group'."""
+ return self._retrieveMD(mdtype)
+
+- def _retrieveMD(self, mdtype, retrieve_can_fail=False):
++ def _retrieveMD(self, mdtype, retrieve_can_fail=False, **kwargs):
+ """ Internal function, use .retrieveMD() from outside yum. """
+ # Note that this can raise Errors.RepoMDError if mdtype doesn't exist
+ # for this repo.
+@@ -1597,7 +1680,9 @@ class YumRepository(Repository, config.RepoConf):
+ return local # it's the same return the local one
+
+ try:
+- checkfunc = (self.checkMD, (mdtype,), {})
++ def checkfunc(obj):
++ self.checkMD(obj, mdtype)
++ self.retrieved[mdtype] = 1
+ text = "%s/%s" % (self.id, mdtype)
+ if thisdata.size is None:
+ reget = None
+@@ -1613,8 +1698,9 @@ class YumRepository(Repository, config.RepoConf):
+ checkfunc=checkfunc,
text=text,
cache=self.http_caching == 'all',
- size=thisdata.size)
+- size=thisdata.size)
- except (Errors.NoMoreMirrorsRepoError, Errors.RepoError):
++ size=thisdata.size,
++ **kwargs)
+ except Errors.RepoError:
if retrieve_can_fail:
return None
raise
+@@ -1624,7 +1710,6 @@ class YumRepository(Repository, config.RepoConf):
+ raise Errors.RepoError, \
+ "Could not retrieve %s matching remote checksum from %s" % (local, self)
+ else:
+- self.retrieved[mdtype] = 1
+ return local
+
+
diff --git a/yumcommands.py b/yumcommands.py
-index 4dcbea7..9c181ec 100644
+index 4dcbea7..bc30bd4 100644
--- a/yumcommands.py
+++ b/yumcommands.py
+@@ -29,7 +29,7 @@ import operator
+ import locale
+ import fnmatch
+ import time
+-from yum.i18n import utf8_width, utf8_width_fill, to_unicode
++from yum.i18n import utf8_width, utf8_width_fill, to_unicode, exception2msg
+
+ import yum.config
+
@@ -43,16 +43,24 @@ def _err_mini_usage(base, basecmd):
base.logger.critical(txt)
@@ -156981,7 +158173,7 @@ index 4dcbea7..9c181ec 100644
"""
if base.repos.listEnabled():
return
-@@ -152,85 +199,207 @@ def checkEnabledRepo(base, possible_local_files=[]):
+@@ -152,113 +199,273 @@ def checkEnabledRepo(base, possible_local_files=[]):
raise cli.CliError
class YumCommand:
@@ -157141,9 +158333,10 @@ index 4dcbea7..9c181ec 100644
- return base.installPkgs(extcmds)
+ return base.installPkgs(extcmds, basecmd=basecmd)
except yum.Errors.YumBaseError, e:
- return 1, [str(e)]
-
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+
+
class UpdateCommand(YumCommand):
+ """A class containing methods needed by the cli to execute the
+ update command.
@@ -157202,8 +158395,9 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Setting up Update Process"))
try:
return base.updatePkgs(extcmds, update_to=(basecmd == 'update-to'))
-@@ -238,21 +407,59 @@ class UpdateCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
class DistroSyncCommand(YumCommand):
+ """A class containing methods needed by the cli to execute the
@@ -157262,7 +158456,14 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Setting up Distribution Synchronization Process"))
try:
base.conf.obsoletes = 1
-@@ -289,18 +496,53 @@ def _list_cmd_calc_columns(base, ypl):
+ return base.distroSyncPkgs(extcmds)
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+
+ def _add_pkg_simple_list_lens(data, pkg, indent=''):
+ """ Get the length of each pkg's column. Add that to data.
+@@ -289,21 +496,56 @@ def _list_cmd_calc_columns(base, ypl):
return (-columns[0], -columns[1], -columns[2])
class InfoCommand(YumCommand):
@@ -157315,7 +158516,11 @@ index 4dcbea7..9c181ec 100644
+ highlight = False
ypl = base.returnPkgLists(extcmds, installed_available=highlight)
except yum.Errors.YumBaseError, e:
- return 1, [str(e)]
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+ else:
+ update_pkgs = {}
+ inst_pkgs = {}
@@ -341,6 +583,7 @@ class InfoCommand(YumCommand):
local_pkgs[(po.name, po.arch)] = po
@@ -157342,7 +158547,7 @@ index 4dcbea7..9c181ec 100644
'=' : clar, 'not in' : clai})
rep = base.listPkgs(ypl.extras, _('Extra Packages'), basecmd,
columns=columns)
-@@ -389,35 +635,95 @@ class InfoCommand(YumCommand):
+@@ -389,45 +635,121 @@ class InfoCommand(YumCommand):
return 0, []
def needTs(self, base, basecmd, extcmds):
@@ -157438,8 +158643,9 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Setting up Remove Process"))
try:
return base.erasePkgs(extcmds)
-@@ -425,9 +731,25 @@ class EraseCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
def needTs(self, base, basecmd, extcmds):
+ """Return whether a transaction set must be set up before this
@@ -157490,6 +158696,15 @@ index 4dcbea7..9c181ec 100644
return _("Display, or use, the groups information")
def _grp_setup_doCommand(self, base):
+@@ -459,7 +794,7 @@ class GroupsCommand(YumCommand):
+ except yum.Errors.GroupsError:
+ return 1, [_('No Groups on which to run command')]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+
+ def _grp_cmd(self, basecmd, extcmds):
+ if basecmd in self.direct_commands:
@@ -470,6 +805,10 @@ class GroupsCommand(YumCommand):
else:
cmd = 'summary'
@@ -157689,7 +158904,8 @@ index 4dcbea7..9c181ec 100644
+
+
except yum.Errors.YumBaseError, e:
- return 1, [str(e)]
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
def needTs(self, base, basecmd, extcmds):
@@ -157779,7 +158995,14 @@ index 4dcbea7..9c181ec 100644
base.logger.debug(_("Making cache files for all metadata files."))
base.logger.debug(_("This may take a while depending on the speed of this computer"))
try:
-@@ -572,9 +1105,7 @@ class MakeCacheCommand(YumCommand):
+@@ -565,81 +1098,204 @@ class MakeCacheCommand(YumCommand):
+ repo.mdpolicy = "group:all"
+ base.doRepoSetup(dosack=0)
+ base.repos.doSetup()
+- for repo in base.repos.listEnabled():
+- repo.repoXML
+
+ # These convert the downloaded data into usable data,
# we can't remove them until *LoadRepo() can do:
# 1. Download a .sqlite.bz2 and convert to .sqlite
# 2. Download a .xml.gz and convert to .xml.gz.sqlite
@@ -157790,7 +159013,8 @@ index 4dcbea7..9c181ec 100644
except yum.Errors.YumBaseError, e:
-@@ -582,44 +1113,134 @@ class MakeCacheCommand(YumCommand):
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
return 0, [_('Metadata Cache Created')]
def needTs(self, base, basecmd, extcmds):
@@ -157925,8 +159149,9 @@ index 4dcbea7..9c181ec 100644
base.logger.debug("Searching Packages: ")
try:
return base.provides(extcmds)
-@@ -627,19 +1248,56 @@ class ProvidesCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
class CheckUpdateCommand(YumCommand):
+ """A class containing methods needed by the cli to execute the
@@ -157982,7 +159207,13 @@ index 4dcbea7..9c181ec 100644
obscmds = ['obsoletes'] + extcmds
base.extcmds.insert(0, 'updates')
result = 0
-@@ -681,19 +1339,56 @@ class CheckUpdateCommand(YumCommand):
+@@ -676,161 +1332,437 @@ class CheckUpdateCommand(YumCommand):
+ columns=columns)
+ result = 100
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+ else:
return result, []
class SearchCommand(YumCommand):
@@ -158039,8 +159270,9 @@ index 4dcbea7..9c181ec 100644
base.logger.debug(_("Searching Packages: "))
try:
return base.search(extcmds)
-@@ -701,24 +1396,70 @@ class SearchCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
def needTs(self, base, basecmd, extcmds):
+ """Return whether a transaction set must be set up before this
@@ -158110,8 +159342,10 @@ index 4dcbea7..9c181ec 100644
base.conf.obsoletes = 1
self.doneCommand(base, _("Setting up Upgrade Process"))
try:
-@@ -727,25 +1468,64 @@ class UpgradeCommand(YumCommand):
- return 1, [str(e)]
+ return base.updatePkgs(extcmds, update_to=(basecmd == 'upgrade-to'))
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
class LocalInstallCommand(YumCommand):
+ """A class containing methods needed by the cli to execute the
@@ -158175,8 +159409,11 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Setting up Local Package Process"))
updateonly = basecmd == 'localupdate'
-@@ -755,19 +1535,61 @@ class LocalInstallCommand(YumCommand):
- return 1, [str(e)]
+ try:
+ return base.localInstall(filelist=extcmds, updateonly=updateonly)
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
def needTs(self, base, basecmd, extcmds):
+ """Return whether a transaction set must be set up before this
@@ -158238,8 +159475,9 @@ index 4dcbea7..9c181ec 100644
base.logger.debug(_("Searching Packages for Dependency:"))
try:
return base.resolveDepCli(extcmds)
-@@ -775,19 +1597,56 @@ class ResolveDepCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
class ShellCommand(YumCommand):
+ """A class containing methods needed by the cli to execute the
@@ -158295,8 +159533,9 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _('Setting up Yum Shell'))
try:
return base.doShell()
-@@ -795,23 +1654,69 @@ class ShellCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
def needTs(self, base, basecmd, extcmds):
+ """Return whether a transaction set must be set up before this
@@ -158365,7 +159604,9 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Finding dependencies: "))
try:
return base.deplist(extcmds)
-@@ -820,17 +1725,46 @@ class DepListCommand(YumCommand):
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
class RepoListCommand(YumCommand):
@@ -158412,7 +159653,7 @@ index 4dcbea7..9c181ec 100644
def _repo_size(repo):
ret = 0
for pkg in repo.sack.returnPackages():
-@@ -866,6 +1800,13 @@ class RepoListCommand(YumCommand):
+@@ -866,6 +1798,13 @@ class RepoListCommand(YumCommand):
except yum.Errors.RepoError:
if verbose:
raise
@@ -158426,7 +159667,7 @@ index 4dcbea7..9c181ec 100644
repos = base.repos.repos.values()
repos.sort()
-@@ -924,111 +1865,108 @@ class RepoListCommand(YumCommand):
+@@ -924,111 +1863,108 @@ class RepoListCommand(YumCommand):
ui_enabled = dhibeg + _('disabled') + hiend
ui_endis_wid = utf8_width(_('disabled'))
@@ -158631,7 +159872,7 @@ index 4dcbea7..9c181ec 100644
if not verbose and cols:
# Work out the first (id) and last (enabled/disalbed/count),
-@@ -1088,21 +2026,54 @@ class RepoListCommand(YumCommand):
+@@ -1088,21 +2024,54 @@ class RepoListCommand(YumCommand):
return 0, ['repolist: ' +to_unicode(locale.format("%d", tot_num, True))]
def needTs(self, base, basecmd, extcmds):
@@ -158686,7 +159927,7 @@ index 4dcbea7..9c181ec 100644
if len(extcmds) == 0:
base.usage()
raise cli.CliError
-@@ -1147,28 +2118,85 @@ class HelpCommand(YumCommand):
+@@ -1147,28 +2116,85 @@ class HelpCommand(YumCommand):
return help_output
def doCommand(self, base, basecmd, extcmds):
@@ -158772,7 +160013,7 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Setting up Reinstall Process"))
try:
return base.reinstallPkgs(extcmds)
-@@ -1177,25 +2205,73 @@ class ReInstallCommand(YumCommand):
+@@ -1177,49 +2203,139 @@ class ReInstallCommand(YumCommand):
return 1, [to_unicode(e)]
def getSummary(self):
@@ -158846,8 +160087,9 @@ index 4dcbea7..9c181ec 100644
self.doneCommand(base, _("Setting up Downgrade Process"))
try:
return base.downgradePkgs(extcmds)
-@@ -1203,23 +2279,65 @@ class DowngradeCommand(YumCommand):
- return 1, [str(e)]
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
def getSummary(self):
+ """Return a one line summary of this command.
@@ -158912,7 +160154,25 @@ index 4dcbea7..9c181ec 100644
vcmd = 'installed'
if extcmds:
vcmd = extcmds[0]
-@@ -1344,6 +2462,14 @@ class VersionCommand(YumCommand):
+@@ -1308,7 +2424,7 @@ class VersionCommand(YumCommand):
+ str(data[2][grp])))
+ _append_repos(cols, data[3][grp])
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+ if vcmd in ('available', 'all', 'group-available', 'group-all'):
+ try:
+ data = base.pkgSack.simpleVersion(not verbose, groups=groups)
+@@ -1327,7 +2443,7 @@ class VersionCommand(YumCommand):
+ if verbose:
+ _append_repos(cols, data[3][grp])
+ except yum.Errors.YumBaseError, e:
+- return 1, [str(e)]
++ return 1, [exception2msg(e)]
+
+ data = {'rid' : {}, 'ver' : {}}
+ for (rid, ver) in cols:
+@@ -1344,6 +2460,14 @@ class VersionCommand(YumCommand):
return 0, ['version']
def needTs(self, base, basecmd, extcmds):
@@ -158927,7 +160187,7 @@ index 4dcbea7..9c181ec 100644
vcmd = 'installed'
if extcmds:
vcmd = extcmds[0]
-@@ -1354,23 +2480,62 @@ class VersionCommand(YumCommand):
+@@ -1354,23 +2478,62 @@ class VersionCommand(YumCommand):
class HistoryCommand(YumCommand):
@@ -158991,7 +160251,7 @@ index 4dcbea7..9c181ec 100644
return 2, ["Repeating transaction %u" % (old.tid,)]
def _hcmd_undo(self, base, extcmds):
-@@ -1426,12 +2591,54 @@ class HistoryCommand(YumCommand):
+@@ -1426,12 +2589,57 @@ class HistoryCommand(YumCommand):
def _hcmd_new(self, base, extcmds):
base.history._create_db_file()
@@ -158999,9 +160259,12 @@ index 4dcbea7..9c181ec 100644
+ print "File :", base.history._db_file
+ num = os.stat(base.history._db_file).st_size
+ print "Size :", locale.format("%d", num, True)
++ trans_N = base.history.last()
++ if trans_N is None:
++ print _("Transactions:"), 0
++ return
+ counts = base.history._pkg_stats()
+ trans_1 = base.history.old("1")[0]
-+ trans_N = base.history.last()
+ print _("Transactions:"), trans_N.tid
+ print _("Begin time :"), time.ctime(trans_1.beg_timestamp)
+ print _("End time :"), time.ctime(trans_N.end_timestamp)
@@ -159047,7 +160310,7 @@ index 4dcbea7..9c181ec 100644
if extcmds and extcmds[0] not in cmds:
base.logger.critical(_('Invalid history sub-command, use: %s.'),
", ".join(cmds))
-@@ -1444,6 +2651,19 @@ class HistoryCommand(YumCommand):
+@@ -1444,6 +2652,19 @@ class HistoryCommand(YumCommand):
raise cli.CliError
def doCommand(self, base, basecmd, extcmds):
@@ -159067,7 +160330,7 @@ index 4dcbea7..9c181ec 100644
vcmd = 'list'
if extcmds:
vcmd = extcmds[0]
-@@ -1468,12 +2688,26 @@ class HistoryCommand(YumCommand):
+@@ -1468,12 +2689,26 @@ class HistoryCommand(YumCommand):
ret = self._hcmd_rollback(base, extcmds)
elif vcmd == 'new':
ret = self._hcmd_new(base, extcmds)
@@ -159094,7 +160357,7 @@ index 4dcbea7..9c181ec 100644
vcmd = 'list'
if extcmds:
vcmd = extcmds[0]
-@@ -1481,16 +2715,46 @@ class HistoryCommand(YumCommand):
+@@ -1481,16 +2716,46 @@ class HistoryCommand(YumCommand):
class CheckRpmdbCommand(YumCommand):
@@ -159141,7 +160404,7 @@ index 4dcbea7..9c181ec 100644
chkcmd = 'all'
if extcmds:
chkcmd = extcmds
-@@ -1505,19 +2769,57 @@ class CheckRpmdbCommand(YumCommand):
+@@ -1505,19 +2770,57 @@ class CheckRpmdbCommand(YumCommand):
return rc, ['%s %s' % (basecmd, chkcmd)]
def needTs(self, base, basecmd, extcmds):
@@ -159199,7 +160462,7 @@ index 4dcbea7..9c181ec 100644
if not extcmds:
base.logger.critical(_("No saved transaction file specified."))
raise cli.CliError
-@@ -1533,5 +2835,13 @@ class LoadTransactionCommand(YumCommand):
+@@ -1533,5 +2836,13 @@ class LoadTransactionCommand(YumCommand):
def needTs(self, base, basecmd, extcmds):
@@ -159214,7 +160477,7 @@ index 4dcbea7..9c181ec 100644
return True
diff --git a/yummain.py b/yummain.py
-index 9f79f4f..c473df6 100755
+index 9f79f4f..e3a232b 100755
--- a/yummain.py
+++ b/yummain.py
@@ -29,13 +29,13 @@ from yum import Errors
@@ -159234,21 +160497,19 @@ index 9f79f4f..c473df6 100755
yum.misc.setup_locale(override_time=True)
-@@ -102,15 +102,21 @@ def main(args):
- return exFatal(e)
+@@ -89,6 +89,23 @@ def main(args):
+ logger = logging.getLogger("yum.main")
+ verbose_logger = logging.getLogger("yum.verbose.main")
- # Try to open the current directory to see if we have
-- # read and write access. If not, chdir to /
++ # Try to open the current directory to see if we have
+ # read and execute access. If not, chdir to /
- try:
- f = open(".")
- except IOError, e:
- if e.errno == errno.EACCES:
-- logger.critical(_('No read/write access in current directory, moving to /'))
++ try:
++ f = open(".")
++ except IOError, e:
++ if e.errno == errno.EACCES:
+ logger.critical(_('No read/execute access in current directory, moving to /'))
- os.chdir("/")
- else:
-- close(f)
++ os.chdir("/")
++ else:
+ f.close()
+ try:
+ os.getcwd()
@@ -159256,9 +160517,28 @@ index 9f79f4f..c473df6 100755
+ if e.errno == errno.ENOENT:
+ logger.critical(_('No getcwd() access in current directory, moving to /'))
+ os.chdir("/")
++
+ # our core object for the cli
+ base = cli.YumBaseCli()
+
+@@ -101,17 +118,6 @@ def main(args):
+ except Errors.YumBaseError, e:
+ return exFatal(e)
+- # Try to open the current directory to see if we have
+- # read and write access. If not, chdir to /
+- try:
+- f = open(".")
+- except IOError, e:
+- if e.errno == errno.EACCES:
+- logger.critical(_('No read/write access in current directory, moving to /'))
+- os.chdir("/")
+- else:
+- close(f)
+-
lockerr = ""
while True:
+ try:
@@ -120,16 +126,16 @@ def main(args):
if exception2msg(e) != lockerr:
lockerr = exception2msg(e)
diff --git a/yum-ppc64-preferred.patch b/yum-ppc64-preferred.patch
index 6c84924..3eaae57 100644
--- a/yum-ppc64-preferred.patch
+++ b/yum-ppc64-preferred.patch
@@ -2,8 +2,8 @@ diff -ru yum-3.4.3-orig/rpmUtils/arch.py yum-3.4.3/rpmUtils/arch.py
--- yum-3.4.3-orig/rpmUtils/arch.py 2011-06-28 17:01:10.009680846 -0400
+++ yum-3.4.3/rpmUtils/arch.py 2011-06-28 17:01:31.849916539 -0400
@@ -3,7 +3,7 @@
- import os
- import rpm
+ import ctypes
+ import struct
-_ppc64_native_is_best = False
+_ppc64_native_is_best = True
diff --git a/yum.spec b/yum.spec
index d4cc3f5..5ad02fe 100644
--- a/yum.spec
+++ b/yum.spec
@@ -18,7 +18,7 @@
Summary: RPM package installer/updater/manager
Name: yum
Version: 3.4.3
-Release: 25%{?dist}
+Release: 26%{?dist}
License: GPLv2+
Group: System Environment/Base
Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -30,9 +30,7 @@ Patch5: geode-arch.patch
Patch6: yum-HEAD.patch
Patch7: yum-ppc64-preferred.patch
Patch8: BZ-803346-no-only-update.patch
-Patch9: arm-arch-detection.patch
Patch20: yum-manpage-files.patch
-Patch21: BZ-809469-completion-helper.patch
URL: http://yum.baseurl.org/
BuildArchitectures: noarch
@@ -140,9 +138,7 @@ Install this package if you want auto yum updates nightly via cron.
%patch6 -p1
%patch7 -p1
%patch8 -p1
-%patch9 -p1
%patch20 -p1
-%patch21 -p1
%patch1 -p1
%build
@@ -296,7 +292,7 @@ exit 0
%files cron
%defattr(-,root,root)
%doc COPYING
-%config(noreplace) %{_sysconfdir}/cron.daily/yum-update.cron
+%config(noreplace) %{_sysconfdir}/cron.daily/0yum-update.cron
%config(noreplace) %{_sysconfdir}/cron.daily/yum-cleanup.cron
%{_sysconfdir}/rc.d/init.d/yum-cron
%{_sbindir}/yum-cron
@@ -317,6 +313,12 @@ exit 0
%endif
%changelog
+* Thu Jun 7 2012 Zdenek Pavlas <zpavlas at redhat.com> - 3.4.3-26
+- update to latest HEAD
+- more completion helper patches
+- parallel downloading of packages and metadata
+- revert a hack that probably caused BZ 829505
+
* Thu May 31 2012 Zdenek Pavlas <zpavlas at redhat.com> - 3.4.3-25
- backported completion-helper.py patches from HEAD, BZ 809469.
More information about the scm-commits
mailing list