Browse Source

yum package update

Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>
master
basebuilder_pel7ppc64bebuilder0 6 years ago
parent
commit
7975df2712
  1. 42
      SOURCES/BZ-1002977-use-the-provide-version.patch
  2. 58
      SOURCES/BZ-1004853-yum-cron-handle-empty-transaction.patch
  3. 43
      SOURCES/BZ-1033416-yum-error-on-non-us-locale.patch
  4. 231
      SOURCES/BZ-1040619-yum-cron-reporting.patch
  5. 63
      SOURCES/BZ-1041395-depsolve-loop-limit.patch
  6. 297
      SOURCES/BZ-1047793-lvm-snapshot.patch
  7. 28
      SOURCES/BZ-1050902-manpage-formatting-errrors.patch
  8. 86
      SOURCES/BZ-1052436-group-bundle-docs.patch
  9. 741
      SOURCES/BZ-1052436-group-bundle-pre-f20-fixes.patch
  10. 22
      SOURCES/BZ-1052994-yum-cron-install-unsigned-packages.patch
  11. 1469
      SOURCES/BZ-1053289-misc-perf+UI+simple-bug+docs-fixes.patch
  12. 37
      SOURCES/BZ-1058297-remove-del-for-weird-anaconda-C-NULL-exception.patch
  13. 1406
      SOURCES/BZ-1062959-add-fs-command.patch
  14. 24
      SOURCES/BZ-1063177-xml-traceback.patch
  15. 42
      SOURCES/BZ-1063181-upgrades-for-install-only.patch
  16. 135
      SOURCES/BZ-1065380-updateinfo-strip-respin.patch
  17. 16
      SOURCES/BZ-1087911-update-minimal-manpage.patch
  18. 18
      SOURCES/BZ-1095146-file-uris-normpath.patch
  19. 80
      SOURCES/BZ-1095157-traceback-when-empty-history.patch
  20. 19
      SOURCES/BZ-1095161-setopt-spaces-handling.patch
  21. 36
      SOURCES/BZ-1096147-history-search-crash.patch
  22. 77
      SOURCES/BZ-1097383-usr-readonly.patch
  23. 69
      SOURCES/BZ-1102585-variable-substitution.patch
  24. 28
      SOURCES/BZ-1113395-verify-permissions-mask.patch
  25. 51
      SOURCES/BZ-1130939-dont-create-lockdir-directories.patch
  26. 75
      SOURCES/BZ-1138205-needs-restarting.patch
  27. 18
      SOURCES/BZ-1147992-debuginfo-install-dolock-exception.patch
  28. 37
      SOURCES/BZ-1168120-manpage.patch
  29. 38
      SOURCES/BZ-1168121-fssnapshot-manpage-fix.patch
  30. 58
      SOURCES/BZ-1168385-group-conditionals-deselect.patch
  31. 22
      SOURCES/BZ-1175309-enable-repos-instruction.patch
  32. 22
      SOURCES/BZ-1175315-dont-require-enabled-repos-for-url.patch
  33. 88
      SOURCES/BZ-1182075-yum-security-manpage.patch
  34. 40
      SOURCES/BZ-1182096-yum-cron-conf-upgrade-minimal.patch
  35. 21
      SOURCES/BZ-1183669-corrupt-cache.patch
  36. 66
      SOURCES/BZ-1186690-compare_providers_priorities.patch
  37. 161
      SOURCES/BZ-1188960-API-missing-requires.patch
  38. 32
      SOURCES/BZ-1192239-update-minimal.patch
  39. 56
      SOURCES/BZ-1193871-updateinfo-notice-when-arch-changed.patch
  40. 84
      SOURCES/BZ-1194915-add-logging-for-bad-notice-dupes.patch
  41. 33
      SOURCES/BZ-1195745-failed-repo-message.patch
  42. 67
      SOURCES/BZ-1199976-kbase-articles.patch
  43. 42
      SOURCES/BZ-1202680-handle-non-ascii-email.patch
  44. 60
      SOURCES/BZ-1208803-autosavets.patch
  45. 74
      SOURCES/BZ-1211384-yum-grouplist-headers.patch
  46. 19
      SOURCES/BZ-1212506-running-kernel-epoch.patch
  47. 57
      SOURCES/BZ-1212514-not-enough-space.patch
  48. 113
      SOURCES/BZ-1212519-exclude-installed.patch
  49. 35
      SOURCES/BZ-1233152-pvm-api-lv_attr.patch
  50. 155
      SOURCES/BZ-1234967-handle-invalid-yumdb.patch
  51. 19
      SOURCES/BZ-1235623-new-provides-realpath-file-search.patch
  52. 25
      SOURCES/BZ-1244119-fssnapshot-automatic-percentage-manpage.patch
  53. 48
      SOURCES/BZ-1259837-igroups-empty-lines.patch
  54. 146
      SOURCES/BZ-1267234-groupinstall-fail-on-non-existent.patch
  55. 22
      SOURCES/BZ-1267897-exclude-dups-from-security-updates.patch
  56. 70
      SOURCES/BZ-1272058-arches.patch
  57. 173
      SOURCES/BZ-1274211-skip-missing-names.patch
  58. 243
      SOURCES/BZ-1278333-yum-shell-support-exit-status.patch
  59. 19
      SOURCES/BZ-1279483-hidden-groups-manpage.patch
  60. 143
      SOURCES/BZ-1281593-yum-fs-vars.patch
  61. 83
      SOURCES/BZ-1287610-fips-dont-pollute-stderr.patch
  62. 32
      SOURCES/BZ-1291745-query-install-excludes.patch
  63. 23
      SOURCES/BZ-1292087-history-hash-crash.patch
  64. 82
      SOURCES/BZ-1292150-updateinfo-list-available.patch
  65. 38
      SOURCES/BZ-1292160-security-lists-wrong-arch-updates.patch
  66. 66
      SOURCES/BZ-1293378-ftp-disable-epsv.patch
  67. 11
      SOURCES/BZ-1293513-compdir.patch
  68. 24
      SOURCES/BZ-1293670-proxy.patch
  69. 49
      SOURCES/BZ-1294789-yum-cron-fix-update_cmd.patch
  70. 86
      SOURCES/BZ-1306142-allow-older-installonly-deps.patch
  71. 19
      SOURCES/BZ-1309676-fs-command-help-fix.patch
  72. 47
      SOURCES/BZ-1321651-repoinfo-add-metadata-expire-filter.patch
  73. 19
      SOURCES/BZ-1327962-conduit-typo.patch
  74. 75
      SOURCES/BZ-1328023-updateinfo-traceback.patch
  75. 59
      SOURCES/BZ-1330423-skipbroken-installonly-limit-fix.patch
  76. 46
      SOURCES/BZ-1330670-system-name-email-from-cron.patch
  77. 408
      SOURCES/BZ-1335250-fssnapshot-handle-lvm-errors.patch
  78. 128
      SOURCES/BZ-1337105-add-lazy-packages-caching-opt.patch
  79. 58
      SOURCES/BZ-1339168-yum-cron-conf-typo.patch
  80. 129
      SOURCES/BZ-1343690-add-payload-gpgcheck-opt.patch
  81. 33
      SOURCES/BZ-1347813-security-updates-count.patch
  82. 220
      SOURCES/BZ-1348995-ship-comps-rng-schema.patch
  83. 48
      SOURCES/BZ-1352585-detect-installed-provide.patch
  84. 78
      SOURCES/BZ-1356797-silent-exception.patch
  85. 34
      SOURCES/BZ-1357083-clean-all-add-hint-rm-rf.patch
  86. 11
      SOURCES/BZ-1358492-installonly-kernel.patch
  87. 63
      SOURCES/BZ-1361609-improve-exactarchlist-opt.patch
  88. 98
      SOURCES/BZ-1369389-dont-recommend-makecache-if-running.patch
  89. 26
      SOURCES/BZ-1370134-yum-check-ignore-self-conflicts.patch
  90. 20
      SOURCES/BZ-1377328-_metadata_cache_req.patch
  91. 19
      SOURCES/BZ-1386597-obsoletes-man-page.patch
  92. 24
      SOURCES/BZ-1389816-include-repoid-in-timestamp-error.patch
  93. 69
      SOURCES/BZ-1391507-fix-filelist-queries-for-dup-pkgs.patch
  94. 64
      SOURCES/BZ-1397829-fix-reget-simple-md-fnames.patch
  95. 76
      SOURCES/BZ-1399628-updateinfo-fix-wrong-pkg-count.patch
  96. 28
      SOURCES/BZ-1411575-manpage-typo.patch
  97. 23
      SOURCES/BZ-1411692-docs-conf-var-naming-rules.patch
  98. 84
      SOURCES/BZ-1432319-add-usercache-opt.patch
  99. 73
      SOURCES/BZ-1451817-docs-improve-payload-gpgcheck-opt.patch
  100. 50
      SOURCES/BZ-1458841-preload-shared-libs.patch
  101. Some files were not shown because too many files have changed in this diff Show More

42
SOURCES/BZ-1002977-use-the-provide-version.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
commit 3a0bad67e16c391b57cf26bc68c8c61f96b5b077
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Wed Nov 20 13:32:13 2013 +0100

_getsysver(): use the version of the provide.
Use it as-is (no stripping or rewriting)

diff --git a/yum/config.py b/yum/config.py
index ecb8490..8f8e654 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1210,11 +1210,8 @@ def _getsysver(installroot, distroverpkg):
flag = rpmUtils.miscutils.flagToString(flag)
ver = hdr[getattr(rpm, 'RPMTAG_PROVIDEVERSION')][off]
if flag == 'EQ' and ver:
- releasever = rpmUtils.miscutils.stringToVersion(releasever)
- if releasever[2]:
- releasever = "%s-%s" % (releasever[1], releasever[2]) # No epoch
- else:
- releasever = releasever[1] # No epoch or release, just version
+ # override the package version
+ releasever = ver
del hdr
del idx
diff --git a/yum/config.py b/yum/config.py
index cdad4bc..cb5243f 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1213,8 +1213,9 @@ def _getsysver(installroot, distroverpkg):
flag = rpmUtils.miscutils.flagToString(flag)
ver = hdr[getattr(rpm, 'RPMTAG_PROVIDEVERSION')][off]
if flag == 'EQ' and ver:
- # override the package version
- releasever = ver
+ if hdr['name'] != distroverpkg_prov:
+ # override the package version
+ releasever = ver
del hdr
del idx

58
SOURCES/BZ-1004853-yum-cron-handle-empty-transaction.patch

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
commit ae22bcdbacc01b12175304e14df59bdda45aa108
Author: Andreas Fleig <andreasfleig@googlemail.com>
Date: Wed Mar 16 12:35:38 2016 +0100

yum-cron: don't fail on empty transaction. BZ 1004853
Even if refreshUpdates() returns True, the transaction may still be
empty if some updateinfo filters were applied there and thus a later
call to buildTransaction() would return 0 (success). This wasn't
handled by findDeps() properly, making it emit an error message in such
a case.
Note that, in the first place, we shouldn't return True from
refreshUpdates() if the transaction becomes empty after applying the
filters. However, we should handle this particular buildTransaction()
outcome in findDeps() regardless and that's sufficient to fix this bug.
See also:
http://lists.baseurl.org/pipermail/yum/2014-December/024141.html

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index ccba690..5c3c1f9 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -513,7 +513,13 @@ class YumCronBase(yum.YumBase, YumOutput):
except yum.Errors.RepoError, e:
self.emitCheckFailed("%s" %(e,))
sys.exit()
- if res != 2:
+ if res == 0:
+ # success, empty transaction
+ sys.exit(0)
+ elif res == 2:
+ # success, dependencies resolved
+ pass
+ else:
self.emitCheckFailed("Failed to build transaction: %s" %(str.join("\n", resmsg),))
sys.exit(1)
commit 485121311f4ff40b939965587db735b05aec6fe0
Author: Felix Kaiser <felix.kaiser@fxkr.net>
Date: Wed Mar 16 13:16:13 2016 +0100

yum-cron: fix exit code in findDeps()

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 5c3c1f9..12c7720 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -512,7 +512,7 @@ class YumCronBase(yum.YumBase, YumOutput):
(res, resmsg) = self.buildTransaction()
except yum.Errors.RepoError, e:
self.emitCheckFailed("%s" %(e,))
- sys.exit()
+ sys.exit(1)
if res == 0:
# success, empty transaction
sys.exit(0)

43
SOURCES/BZ-1033416-yum-error-on-non-us-locale.patch

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
diff --git a/test/misc-tests.py b/test/misc-tests.py
index 7d7d06f..11fd041 100644
--- a/test/misc-tests.py
+++ b/test/misc-tests.py
@@ -150,6 +150,19 @@ class MiscTests(DepsolveTests):
self.assertEqual(type(actual), type(expected))
self.assertEqual(actual, expected)
+ def testOptparse(self):
+ # make 'Usage: %s\n' translated
+ import gettext
+ def dgettext(domain, msg, orig=gettext.dgettext):
+ if domain=='messages' and msg == 'Usage: %s\n':
+ return 'Pou\xc5\xbeit\xc3\xad: %s\n'
+ return orig(domain, msg)
+ gettext.dgettext = dgettext
+ # run "yum --help"
+ from optparse import OptionParser
+ parser = OptionParser(usage=u'\u011b\u0161\u010d')
+ self.assertRaises(SystemExit, parser.parse_args, args=['--help'])
+
def setup_logging():
logging.basicConfig()
plainformatter = logging.Formatter("%(message)s")
diff --git a/yum/i18n.py b/yum/i18n.py
index 76a258d..2c0cbce 100755
--- a/yum/i18n.py
+++ b/yum/i18n.py
@@ -500,6 +500,14 @@ try:
t = gettext.translation('yum', fallback=True)
_ = t.ugettext
P_ = t.ungettext
+
+ # we describe yum commands and options with unicode but optparse
+ # mixes this with non-unicode translations so "yum --help" may fail.
+ # It's much easier to fix this in optparse than in yum. BZ 1033416
+ import optparse
+ if optparse._ is gettext.gettext:
+ #optparse._ = lambda msg: to_unicode(gettext.gettext(msg))
+ optparse._ = gettext.translation('messages', fallback=True).ugettext
except:
'''
Something went wrong so we make a dummy _() wrapper there is just

231
SOURCES/BZ-1040619-yum-cron-reporting.patch

@ -0,0 +1,231 @@ @@ -0,0 +1,231 @@
commit 1fb713cdabf46694e76df4092615607fa09016fe
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Thu Dec 19 10:43:07 2013 +0100

yum-cron: initialize both debuglevel and errorlevel
When warnings or errors are disabled in verbose
logger, disable them in error logger too.

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index a1fd10b..19436e5 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -380,16 +380,16 @@ class YumCronBase(yum.YumBase, YumOutput):
self.preconf.fn = self.opts.yum_config_file
# This needs to be set early, errors are handled later.
- try: self.preconf.debuglevel = int(self._confparser.get('base', 'debuglevel'))
- except: pass
+ try: level = int(self._confparser.get('base', 'debuglevel'))
+ except: level = -2
+ self.preconf.debuglevel = level
+ if -4 <= level <= -2:
+ self.preconf.errorlevel = level + 4
# if we are not root do the special subdir thing
if os.geteuid() != 0:
self.setCacheDir()
- # Create the configuration
- self.conf
-
# override base yum options
self.conf.populate(self._confparser, 'base')
del self._confparser
commit d0441397dc5a5e4f4d3ccc3a99c4cda57b228009
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Jan 6 14:12:46 2014 +0100

Remove emitCheckFailed(), change it to logger.warn(). BZ 1048391
Make acquireLock() respect debuglevel.

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index b96dd13..386a7a0 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -86,17 +86,6 @@ class UpdateEmitter(object):
% errmsg)
self.sendMessages()
- def lockFailed(self, errmsg):
- """Append a message to the output list stating that the
- program failed to acquire the yum lock, then call sendMessages
- to emit the output.
-
- :param errmsg: a string that contains the error message
- """
- self.output.append("Failed to acquire the yum lock with the following error message: \n%s"
- % errmsg)
- self.sendMessages()
-
def checkFailed(self, errmsg):
"""Append a message to the output stating that checking for
updates failed, then call sendMessages to emit the output.
@@ -196,16 +185,6 @@ class EmailEmitter(UpdateEmitter):
self.subject = "Yum: Failed to perform setup on %s" % self.opts.system_name
super(EmailEmitter, self).setupFailed(errmsg)
- def lockFailed(self, errmsg):
- """Append a message to the output list stating that the
- program failed to acquire the yum lock, then call sendMessages
- to emit the output, and set an appropriate subject line.
-
- :param errmsg: a string that contains the error message
- """
- self.subject = "Yum: Failed to acquire the yum lock on %s" % self.opts.system_name
- super(EmailEmitter, self).lockFailed(errmsg)
-
def checkFailed(self, errmsg):
"""Append a message to the output stating that checking for
updates failed, then call sendMessages to emit the output, and
@@ -406,7 +385,7 @@ class YumCronBase(yum.YumBase, YumOutput):
try:
self.doLock()
except yum.Errors.LockError, e:
- self.emitLockFailed("%s" % e)
+ self.logger.warn("Failed to acquire the yum lock: %s", e)
sys.exit(1)
def populateUpdateMetadata(self):
@@ -675,10 +654,6 @@ class YumCronBase(yum.YumBase, YumOutput):
"""Emit a notice stating that checking for updates failed."""
map(lambda x: x.setupFailed(error), self.emitters)
- def emitLockFailed(self, errmsg):
- """Emit a notice that we failed to acquire the yum lock."""
- map(lambda x: x.lockFailed(errmsg), self.emitters)
-
def emitCheckFailed(self, error):
"""Emit a notice stating that checking for updates failed."""
map(lambda x: x.checkFailed(error), self.emitters)
commit 13f69f68876fade7611bcbab6f612937e1c02bff
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Wed Jan 15 09:11:30 2014 +0100

yum-cron: emitUpdateFailed() expects str, not an array.
Avoid Python noise in the report. Also, use implicit conversion
instead of str() for unicode interoperability.

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 87b3e69..6cbed94 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -545,7 +545,7 @@ class YumCronBase(yum.YumBase, YumOutput):
try:
self.getKeyForPackage(po)
except yum.Errors.YumBaseError, errmsg:
- self.emitUpdateFailed([str(errmsg)])
+ self.emitUpdateFailed(errmsg)
return False
else:
self.emitUpdateFailed(err)
@@ -563,8 +563,7 @@ class YumCronBase(yum.YumBase, YumOutput):
try:
self.runTransaction(cb=cb)
except yum.Errors.YumBaseError, err:
-
- self.emitUpdateFailed([str(err)])
+ self.emitUpdateFailed(err)
sys.exit(1)
if emit :
@@ -675,9 +674,9 @@ class YumCronBase(yum.YumBase, YumOutput):
"""Emit a notice stating that downloading the updates failed."""
map(lambda x: x.downloadFailed(error), self.emitters)
- def emitUpdateFailed(self, errmsgs):
+ def emitUpdateFailed(self, errmsg):
"""Emit a notice stating that automatic updates failed."""
- map(lambda x: x.updatesFailed(errmsgs), self.emitters)
+ map(lambda x: x.updatesFailed(errmsg), self.emitters)
def emitMessages(self):
"""Emit the messages from the emitters."""
commit 048af21d6704d40e93e09c65f5c1b547a68e431e
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Mon Jan 20 10:59:58 2014 +0100

yum-cron: EmailEmitter failure should not be fatal. BZ 1055042

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 6cbed94..bfa580e 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -146,8 +146,9 @@ class UpdateEmitter(object):
class EmailEmitter(UpdateEmitter):
"""Emitter class to send messages via email."""
- def __init__(self, opts):
+ def __init__(self, opts, logger):
super(EmailEmitter, self).__init__(opts)
+ self.logger = logger
self.subject = ""
def updatesAvailable(self, summary):
@@ -229,10 +230,13 @@ class EmailEmitter(UpdateEmitter):
msg['To'] = ",".join(self.opts.email_to)
# Send the email
- s = smtplib.SMTP()
- s.connect(self.opts.email_host)
- s.sendmail(self.opts.email_from, self.opts.email_to, msg.as_string())
- s.close()
+ try:
+ s = smtplib.SMTP()
+ s.connect(self.opts.email_host)
+ s.sendmail(self.opts.email_from, self.opts.email_to, msg.as_string())
+ s.close()
+ except Exception, e:
+ self.logger.error("Failed to send an email to %s: %s" % (self.opts.email_host, e))
class StdIOEmitter(UpdateEmitter):
@@ -293,7 +297,7 @@ class YumCronBase(yum.YumBase, YumOutput):
# Create the emitters, and add them to the list
self.emitters = []
if 'email' in self.opts.emit_via:
- self.emitters.append(EmailEmitter(self.opts))
+ self.emitters.append(EmailEmitter(self.opts, self.logger))
if 'stdio' in self.opts.emit_via:
self.emitters.append(StdIOEmitter(self.opts))
commit 8d21de54f5b267af8710c1358fd3a0475aed6bbb
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Mon Jan 20 11:41:15 2014 +0100

yum-cron: Add a retry loop around doLock().

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index bfa580e..e1028be 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -262,6 +262,8 @@ class YumCronConfig(BaseConfig):
system_name = Option(gethostname())
output_width = IntOption(80)
random_sleep = IntOption(0)
+ lock_retries = IntOption(5)
+ lock_sleep = IntOption(60)
emit_via = ListOption(['email','stdio'])
email_to = ListOption(["root"])
email_from = Option("root")
@@ -386,9 +388,14 @@ class YumCronBase(yum.YumBase, YumOutput):
def acquireLock(self):
""" Wrapper method around doLock to emit errors correctly."""
- try:
- self.doLock()
- except yum.Errors.LockError, e:
+ i = 0
+ while True:
+ try: self.doLock(); break
+ except yum.Errors.LockError, e:
+ i += 1
+ if i < self.opts.lock_retries:
+ sleep(self.opts.lock_sleep)
+ continue
self.logger.warn("Failed to acquire the yum lock: %s", e)
sys.exit(1)

63
SOURCES/BZ-1041395-depsolve-loop-limit.patch

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
commit cfd0f0f8ad4bb285755ecc66e528a807f864b4ca
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Wed Dec 11 15:09:28 2013 +0100

depsolve_loop_limit=<forever> should try forever

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index da13dc8..48ced00 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -882,7 +882,7 @@ Default is: !*/swap !*/lv_swap glob:/etc/yum/fssnap.d/*.conf
Set the number of times any attempt to depsolve before we just give up. This
shouldn't be needed as yum should always solve or fail, however it has been
observed that it can loop forever with very large system upgrades. Setting
-this to `0' (or "forever") makes yum try forever. Default is `100'.
+this to `0' (or "<forever>") makes yum try forever. Default is `100'.
.SH "[repository] OPTIONS"
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 8b438bb..81bfdf8 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -870,7 +870,7 @@ class Depsolve(object):
if self.dsCallback: self.dsCallback.start()
depsolve_loop_count = 0
- while depsolve_loop_count < self.conf.depsolve_loop_limit:
+ while depsolve_loop_count != (self.conf.depsolve_loop_limit or -1):
depsolve_loop_count += 1
CheckDeps = True
commit 57f063c11cc8712ce8055d9e9429d897d7d0072c
Author: Zdenek Pavlas <zpavlas@redhat.com>
Date: Thu Dec 12 10:32:49 2013 +0100

Test depsolve_loop_count vs depsolve_loop_limit only once

diff --git a/yum/depsolve.py b/yum/depsolve.py
index 81bfdf8..95c21bc 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -870,7 +870,9 @@ class Depsolve(object):
if self.dsCallback: self.dsCallback.start()
depsolve_loop_count = 0
- while depsolve_loop_count != (self.conf.depsolve_loop_limit or -1):
+ while True:
+ if depsolve_loop_count == (self.conf.depsolve_loop_limit or -1):
+ return (1, [_("Depsolving loop limit reached.")] + unique(errors))
depsolve_loop_count += 1
CheckDeps = True
@@ -922,9 +924,6 @@ class Depsolve(object):
break
- if depsolve_loop_count >= self.conf.depsolve_loop_limit:
- return (1, [_("Depsolving loop limit reached.")] + unique(errors))
-
# FIXME: this doesn't belong here at all...
for txmbr in self.tsInfo.getMembers():
if self.allowedMultipleInstalls(txmbr.po) and \

297
SOURCES/BZ-1047793-lvm-snapshot.patch

@ -0,0 +1,297 @@ @@ -0,0 +1,297 @@
commit 13bbacb4dd25b83cd29389e0608fde1614537257
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Jan 12 15:21:46 2015 +0100

Multiple lvm fixes. BZ 1047793, BZ 1145485
- add fssnap_abort_on_errors config option
- fix default for fssnap_automatic_keep in the man page
- add logging for automatic fssnap events
- add lvm binary path test to _FSSnap.available
- check for lvm2 and lvm2-python-libs packages instead of python-lvm

diff --git a/docs/yum.8 b/docs/yum.8
index 998a5ad..a0038f6 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -741,7 +741,7 @@ then you can create and delete snapshots using:
.br
.br
-Configuration Options: \fBfssnap_automatic_pre\fP, \fBfssnap_automatic_post\fP, \fBfssnap_automatic_keep\fP, \fBfssnap_percentage\fP, \fBfssnap_devices\fP
+Configuration Options: \fBfssnap_automatic_pre\fP, \fBfssnap_automatic_post\fP, \fBfssnap_automatic_keep\fP, \fBfssnap_percentage\fP, \fBfssnap_devices\fP, \fBfssnap_abort_on_errors\fP
.IP
.IP "\fBfs\fP"
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 0362e85..272e07b 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -873,7 +873,7 @@ Boolean (1, 0, True, False, yes, no) Defaults to False
.IP
\fBfssnap_automatic_keep\fR
How many old snapshots should yum keep when trying to automatically create a
-new snapshot. Setting to 0 disables this feature. Default is '0'.
+new snapshot. Setting to 0 disables this feature. Default is '1'.
.IP
\fBfssnap_automatic_percentage\fR
@@ -887,6 +887,21 @@ first match (positive or negative) wins.
Default is: !*/swap !*/lv_swap glob:/etc/yum/fssnap.d/*.conf
.IP
+\fBfssnap_abort_on_errors\fR
+When fssnap_automatic_pre or fssnap_automatic_post is enabled, it's possible to specify which
+fssnap errors should make the transaction fail. The default is `any'.
+
+`broken-setup' - Abort current transaction if snapshot support is unavailable because
+lvm is missing or broken.
+
+`snapshot-failure' - Abort current transaction if creating a snapshot fails (e.g. there is not enough
+free space to make a snapshot).
+
+`any' - Abort current transaction if any of the above occurs.
+
+`none' - Never abort a transaction in case of errors.
+
+.IP
\fBdepsolve_loop_limit\fR
Set the number of times any attempt to depsolve before we just give up. This
shouldn't be needed as yum should always solve or fail, however it has been
diff --git a/yum/__init__.py b/yum/__init__.py
index 6d2c078..347aa7c 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1727,6 +1727,13 @@ much more problems).
:raises: :class:`yum.Errors.YumRPMTransError` if there is a
transaction cannot be completed
"""
+ if (self.conf.fssnap_automatic_pre or self.conf.fssnap_automatic_post) and not self.fssnap.available:
+ msg = _("Snapshot support not available.")
+ if self.conf.fssnap_abort_on_errors in ('broken-setup', 'any'):
+ raise Errors.YumRPMTransError(msg="Aborting transaction.", errors=msg)
+ else:
+ self.verbose_logger.critical(msg)
+
if self.fssnap.available and ((self.conf.fssnap_automatic_pre or
self.conf.fssnap_automatic_post) and
self.conf.fssnap_automatic_keep):
@@ -1748,17 +1755,30 @@ much more problems).
if num > self.conf.fssnap_automatic_keep:
todel.append(snap['dev'])
# Display something to the user?
- self.fssnap.del_snapshots(devices=todel)
+ snaps = self.fssnap.del_snapshots(devices=todel)
+ if len(snaps):
+ self.verbose_logger.info(_("Deleted %u snapshots.") % len(snaps))
if (self.fssnap.available and
(not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
self.conf.fssnap_automatic_pre)):
if not self.fssnap.has_space(self.conf.fssnap_percentage):
- msg = _("Not enough space to create pre. FS snapshot, aborting transaction.")
- raise Errors.YumRPMTransError(msg=msg, errors=[])
+ msg = _("Not enough space to create pre. FS snapshot.")
+ if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
+ raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
+ else:
+ self.verbose_logger.critical(msg)
else:
tags = {'*': ['reason=automatic']} # FIXME: pre. tags
- self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
+ snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
+ if not snaps:
+ msg = _("Failed to create snapshot")
+ if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
+ raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
+ else:
+ self.verbose_logger.critical(msg)
+ for (odev, ndev) in snaps:
+ self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
self.plugins.run('pretrans')
@@ -1895,11 +1915,14 @@ much more problems).
self.conf.fssnap_automatic_post)):
if not self.fssnap.has_space(self.conf.fssnap_percentage):
msg = _("Not enough space to create post trans FS snapshot.")
- self.logger.critical(msg)
+ self.verbose_logger.critical(msg)
else:
tags = {'*': ['reason=automatic']} # FIXME: post tags
- self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
-
+ snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
+ if not snaps:
+ self.verbose_logger.critical(_("Failed to create snapshot"))
+ for (odev, ndev) in snaps:
+ self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
return resultobject
def verifyTransaction(self, resultobject=None, txmbr_cb=None):
diff --git a/yum/config.py b/yum/config.py
index 8eab5bc..02061ba 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -899,6 +899,7 @@ class YumConf(StartupConf):
fssnap_devices = ListOption("!*/swap !*/lv_swap "
"glob:/etc/yum/fssnap.d/*.conf",
parse_default=True)
+ fssnap_abort_on_errors = SelectionOption('any', ('broken-setup', 'snapshot-failure', 'any', 'none'))
depsolve_loop_limit = PositiveIntOption(100, names_of_0=["<forever>"])
diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
index e912ea1..9af252d 100755
--- a/yum/fssnapshots.py
+++ b/yum/fssnapshots.py
@@ -146,7 +143,8 @@ class _FSSnap(object):
devices = []
self.version = _ver
- self.available = bool(lvm)
+ # Parts of the API seem to work even when lvm is not actually installed, hence the path test
+ self.available = bool(lvm and os.path.exists("/sbin/lvm"))
self.postfix_static = "_yum_"
self._postfix = None
self._root = root
diff --git a/yumcommands.py b/yumcommands.py
index a18bc5c..e77d209 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -4264,11 +4264,13 @@ class FSSnapshotCommand(YumCommand):
subcommand = 'summary'
if not base.fssnap.available:
- if not base.rpmdb.searchNames(['python-lvm']):
- print _("Snapshot support not available, no python-lvm package installed.")
- else:
- print _("Snapshot support not available, python-lvm is old/broken.")
- return 0, [basecmd + ' ' + subcommand + ' done']
+ msg = _("Snapshot support not available, please check your lvm installation.")
+ if not base.rpmdb.searchNames(['lvm2']):
+ msg += " " + _("No lvm2 package installed.")
+ if not base.rpmdb.searchNames(['lvm2-python-libs']):
+ msg += " " + _("No lvm2-python-libs package installed.")
+ print msg
+ return 1, [basecmd + ' ' + subcommand + ' done']
if subcommand == 'list':
snaps = base.fssnap.old_snapshots()
@@ -4301,10 +4303,11 @@ class FSSnapshotCommand(YumCommand):
if subcommand == 'create':
tags = {'*': ['reason=manual']}
pc = base.conf.fssnap_percentage
- for (odev, ndev) in base.fssnap.snapshot(pc, tags=tags):
- print _("Created snapshot from %s, results is: %s") %(odev,ndev)
- else:
+ snaps = base.fssnap.snapshot(pc, tags=tags)
+ if not snaps:
print _("Failed to create snapshots")
+ for (odev, ndev) in snaps:
+ print _("Created snapshot from %s, results is: %s") %(odev,ndev)
if subcommand == 'summary':
snaps = base.fssnap.old_snapshots()
commit 29440b1175411c3ccaca6010df8dec2d96088fbd
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Jul 9 15:26:29 2015 +0200

Stop caching fssnapshot postfixes and add microseconds

diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
index a07271d..10ec012 100755
--- a/yum/fssnapshots.py
+++ b/yum/fssnapshots.py
@@ -3,6 +3,7 @@
import os
import fnmatch
import time
+from datetime import datetime
import subprocess
@@ -228,23 +229,13 @@ class _FSSnap(object):
return ret
- def _get_postfix(self):
- if self._postfix is None:
- self._postfix = self.postfix_static
- self._postfix += time.strftime("%Y%m%d%H%M%S")
- return self._postfix
-
- postfix = property(fget=lambda self: self._get_postfix(),
- fset=lambda self, value: setattr(self, "_postfix",value),
- fdel=lambda self: setattr(self, "_postfix", None),
- doc="postfix for snapshots")
def snapshot(self, percentage=100, prefix='', postfix=None, tags={}):
""" Attempt to take a snapshot, note that errors can happen after
this function succeeds. """
if postfix is None:
- postfix = self.postfix
+ postfix = '%s%s' % (self.postfix_static, datetime.now().strftime("%Y%m%d%H%M%S.%f"))
ret = []
for vgname in self._vgnames:
commit 2678b0a2eb042e011bcafb507eae5ea3565c9110
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Jul 13 16:28:32 2015 +0200

Test for lvm binary before using.

diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
index 10ec012..70f80a0 100755
--- a/yum/fssnapshots.py
+++ b/yum/fssnapshots.py
@@ -155,7 +155,7 @@ class _FSSnap(object):
if not self._devs:
return
- self._vgnames = _list_vg_names()
+ self._vgnames = _list_vg_names() if self.available else []
def _use_dev(self, vgname, lv=None):
commit e756473a1b01f40f087488f72d002d9993843a84
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Aug 12 12:54:55 2015 +0200

Update not enough space messages for fssnapshot

diff --git a/yum/__init__.py b/yum/__init__.py
index 48956e9..84bea3e 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1773,7 +1773,7 @@ much more problems).
(not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
self.conf.fssnap_automatic_pre)):
if not self.fssnap.has_space(self.conf.fssnap_percentage):
- msg = _("Not enough space to create pre. FS snapshot.")
+ msg = _("Not enough space on logical volumes to create pre. FS snapshot.")
if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
else:
@@ -1926,7 +1926,7 @@ much more problems).
(not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
self.conf.fssnap_automatic_post)):
if not self.fssnap.has_space(self.conf.fssnap_percentage):
- msg = _("Not enough space to create post trans FS snapshot.")
+ msg = _("Not enough space on logical volumes to create post trans FS snapshot.")
self.verbose_logger.critical(msg)
else:
tags = {'*': ['reason=automatic']} # FIXME: post tags
diff --git a/yumcommands.py b/yumcommands.py
index 4a39ddb..5234260 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -4311,7 +4311,7 @@ class FSSnapshotCommand(YumCommand):
if base.fssnap.has_space(pc):
print _("Space available to take a snapshot.")
else:
- print _("Not enough space available to take a snapshot.")
+ print _("Not enough space available on logical volumes to take a snapshot.")
if subcommand == 'create':
tags = {'*': ['reason=manual']}

28
SOURCES/BZ-1050902-manpage-formatting-errrors.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
diff -up yum-3.4.3/docs/yum.8.old yum-3.4.3/docs/yum.8
--- yum-3.4.3/docs/yum.8.old 2014-01-10 16:20:19.181475331 +0100
+++ yum-3.4.3/docs/yum.8 2014-01-10 16:20:34.704480487 +0100
@@ -383,19 +383,19 @@ version of each package that matches (th
using --showduplicates) and it only shows the newest providers (which can be
changed by using --verbose).
.IP
-.IP "\fBrepolist\fP" "\fBrepoinfo\fP"
+.IP "\fBrepolist\fP"
Produces a list of configured repositories. The default is to list all
enabled repositories. If you pass \-v, for verbose mode, or use repoinfo then
-more information is listed. If the first argument is 'enabled', 'disabled' or
-'all' then the command will list those types of repos.
+more information is listed. If the first argument is \'enabled\', \'disabled\' or
+\'all\' then the command will list those types of repos.
You can pass repo id or name arguments, or wildcards which to match against
both of those. However if the id or name matches exactly then the repo will
be listed even if you are listing enabled repos. and it is disabled.
-In non-verbose mode the first column will start with a '*' if the repo. has
+In non-verbose mode the first column will start with a \'*\' if the repo. has
metalink data and the latest metadata is not local and will start with a
-'!' if the repo. has metadata that is expired. For non-verbose mode the
+\'!\' if the repo. has metadata that is expired. For non-verbose mode the
last column will also display the number of packages in the repo. and (if there
are any user specified excludes) the number of packages excluded.

86
SOURCES/BZ-1052436-group-bundle-docs.patch

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
commit 3fda2738b0c78df0454e72691a43b459c2e57c21
Author: James Antill <james@and.org>
Date: Tue Mar 11 15:09:18 2014 -0400

Change man page text for RHEL-7 group_command=object feedback.

diff --git a/docs/yum.8 b/docs/yum.8
index 6794581..1ab8534 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -250,20 +250,34 @@ Is used to download and make usable all the metadata for the currently enabled
sure the repos. are current (much like "yum clean expire-cache").
.IP
.IP "\fBgroups\fP"
-A command, new in 3.4.2, that collects all the subcommands that act on groups together.
-
-"\fBgroup install\fP" is used to install all of the individual packages in a group, of the specified
-types (this works as if you'd taken each of those package names and put them on
-the command line for a "yum install" command).
+A command, new in 3.4.2, that collects all the subcommands that act on groups
+together. Note that recent yum using distributions (Fedora-19+, RHEL-7+) have
+configured group_command=objects which changes how group commands act in some
+important ways.
+
+"\fBgroup install\fP" is used to install all of the individual packages in a
+group, of the specified types (this works as if you'd taken each of those
+package names and put them on the command line for a "yum install" command).
The group_package_types configuration option specifies which types will
be installed.
-
-"\fBgroup update\fP" is just an alias for groupinstall, which will do the right thing because
-"yum install X" and "yum update X" do the same thing, when X is already
-installed.
-
-"\fBgroup list\fP" is used to list the available groups from all \fByum\fP repos. Groups are marked
-as "installed" if all mandatory packages are installed, or if a group doesn't
+ If you wish to "reinstall" a group so that you get a package that is currently
+blacklisted the easiest way to do that currently is to install the package
+manually and then run "groups mark packages-sync mygroup mypackagename" (or
+use yumdb to set the group_member of the package(s)).
+
+"\fBgroup update\fP" is just an alias for group install, when using
+group_command=compat. This will install packages in the group not already
+installed and upgrade existing packages. With group_command=simple it will just
+upgrade already installed packages. With group_command=objects it will try to
+upgrade the group object, installing any available packages not blacklisted
+(marked '-' in group info) and will upgrade the installed packages.
+
+"\fBgroup list\fP" is used to list the available groups from all \fByum\fP
+repos. When group_command=objects the group is installed if the user
+explicitly installed it (or used the group mark* commands to mark it installed).
+It does not need to have any packages installed.
+When not using group_command=objects groups are shown as "installed" if all
+mandatory packages are installed, or if a group doesn't
have any mandatory packages then it is installed if any of the optional or
default package are installed (when not in group_command=objects mode).
You can pass optional arguments to the list/summary commands: installed,
@@ -300,6 +314,9 @@ meaning of these markers is:
.br
"=" = Package is installed, and was installed via the group.
+you can move an installed package into an installed group using either
+"group mark package-sync/package-sync-forced" or "yumdb set group_member".
+
"\fBgroup summary\fP" is used to give a quick summary of how many groups
are installed and available.
commit e15943868e2a05e4304247f1e19d2520701e9cca
Author: James Antill <james@and.org>
Date: Tue Mar 25 00:12:26 2014 -0400

Documentation tweak for group info and blacklisted packages.

diff --git a/docs/yum.8 b/docs/yum.8
index 1ab8534..3f028f8 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -306,7 +306,7 @@ to each package saying how that package relates to the group object. The
meaning of these markers is:
.br
-"-" = Package isn't installed, and won't be installed as part of the group (Eg. group install foo -pkgA … this will have pkgA marked as '-')
+"-" = Package isn't installed, and won't be installed as part of the group (Eg. "yum group install foo -pkgA" or "yum group install foo; yum remove pkgA" … this will have pkgA marked as '-')
.br
"+" = Package isn't installed, but will be the next time you run "yum upgrade" or "yum group upgrade foo"
.br

741
SOURCES/BZ-1052436-group-bundle-pre-f20-fixes.patch

@ -0,0 +1,741 @@ @@ -0,0 +1,741 @@
commit 8b977a860595a02dc13b5eefd5f8783ba23e4acf
Author: James Antill <james@and.org>
Date: Mon Nov 18 17:14:48 2013 -0500

Add _ugroup_member to txmbr, list installed for groups pkgs. BZ 1031374.

diff --git a/output.py b/output.py
index cf9e985..e42702e 100755
--- a/output.py
+++ b/output.py
@@ -1506,7 +1506,30 @@ class YumOutput:
a_wid = max(a_wid, len(a))
return a_wid
- for (action, pkglist) in [(_('Installing'), self.tsInfo.installed),
+ ninstalled = self.tsInfo.installed
+ ginstalled = {}
+ if self.conf.group_command == 'objects' and ninstalled:
+ # Show new pkgs. that are installed via. a group.
+ ninstalled = []
+ for txmbr in self.tsInfo.installed:
+ if not hasattr(txmbr, '_ugroup_member'):
+ ninstalled.append(txmbr)
+ continue
+ if txmbr._ugroup_member not in ginstalled:
+ ginstalled[txmbr._ugroup_member] = []
+ ginstalled[txmbr._ugroup_member].append(txmbr)
+
+ for grp in sorted(ginstalled, key=lambda x: x.ui_name):
+ action = _('Installing for group upgrade "%s"') % grp.ui_name
+ pkglist = ginstalled[grp]
+
+ lines = []
+ for txmbr in pkglist:
+ a_wid = _add_line(lines, data, a_wid, txmbr.po, txmbr.obsoletes)
+
+ pkglist_lines.append((action, lines))
+
+ for (action, pkglist) in [(_('Installing'), ninstalled),
(_('Updating'), self.tsInfo.updated),
(_('Removing'), self.tsInfo.removed),
(_('Reinstalling'), self.tsInfo.reinstalled),
diff --git a/yum/__init__.py b/yum/__init__.py
index 6bd5962..f212884 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3845,6 +3845,8 @@ much more problems).
pkg_warning_level='debug2')
for txmbr in txmbrs:
txmbr.group_member = thisgroup.groupid
+ if lupgrade: # For list transaction.
+ txmbr._ugroup_member = thisgroup
except Errors.InstallError, e:
self.verbose_logger.debug(_('No package named %s available to be installed'),
pkg)
commit 4a84e0f3d3954fdf0a94ecf61775ae9af43f2a4d
Author: James Antill <james@and.org>
Date: Mon Dec 16 16:03:57 2013 -0500

Remove old FIXME for env. groups, fixes "group lists" without patterns.

diff --git a/yum/__init__.py b/yum/__init__.py
index caafae4..69e8043 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3520,8 +3520,7 @@ much more problems).
if self.conf.group_command == 'objects':
igrps = self.igroups.groups.values()
evgrps = self.comps.environments
- if False and self.conf.group_command == 'objects':
- # FIXME: Environment groups.
+ if self.conf.group_command == 'objects':
ievgrps = self.igroups.environments.values()
return igrps, grps, ievgrps, evgrps
commit 42c82dd60dc498e7a2419b291a2392e77ffa5ded
Author: James Antill <james@and.org>
Date: Mon Dec 16 16:31:33 2013 -0500

Confirm/assert new mocked igrps/ievgrps behaviour.

diff --git a/yum/__init__.py b/yum/__init__.py
index 69e8043..230a2e3 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3629,6 +3629,12 @@ much more problems).
if ievgrps is None:
ievgrps = {}
+ # Note that we used to get here with igrps/ievgrps that didn't exist
+ # in comps. but we mock them in comps now because it was hard to deal
+ # with that everywhere ... so just to confirm.
+ assert not igrps
+ assert not ievgrps
+
for igrp in igrps.values():
# These are installed groups that aren't in comps anymore. so we
# create fake comps groups for them.
commit e2c3d3f909088ba5e1cc237d2b57eab669e7befd
Author: James Antill <james@and.org>
Date: Mon Dec 16 15:29:06 2013 -0500

Warn iff return_{groups, environments} returned an empty list. BZ 1043207.

diff --git a/yum/__init__.py b/yum/__init__.py
index 230a2e3..d051a1c 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4458,24 +4458,31 @@ much more problems).
if group_string and group_string[0] == '^':
group_string = group_string[1:]
# Actually dealing with "environment groups".
+ found = False
for env_grp in comps.return_environments(group_string):
+ found = True
try:
txmbrs = self.selectEnvironment(env_grp.environmentid,
upgrade=upgrade)
tx_return.extend(txmbrs)
except yum.Errors.GroupsError:
- self.logger.critical(_('Warning: Environment Group %s does not exist.'), group_string)
+ assert False, "Checked in for loop."
continue
+ if not found:
+ self.logger.error(_('Warning: Environment group %s does not exist.'),
+ group_string)
return tx_return
+ found = False
for group in comps.return_groups(group_string):
+ found = True
try:
txmbrs = self.selectGroup(group.groupid, upgrade=upgrade)
tx_return.extend(txmbrs)
except yum.Errors.GroupsError:
- self.logger.critical(_('Warning: Group %s does not exist.'), group_string)
+ assert False, "Checked in for loop."
continue
- else:
+ if not found:
self.logger.error(_('Warning: group %s does not exist.'),
group_string)
commit 406dae058a021cf1171666c4e779721ef7ac680e
Author: James Antill <james@and.org>
Date: Mon Dec 16 17:34:40 2013 -0500

Remove old test to allow comma separated grpid for selectGroup().

diff --git a/yum/__init__.py b/yum/__init__.py
index d051a1c..2709225 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3771,9 +3771,6 @@ much more problems).
transaction set by this function
"""
- if not self.comps.has_group(grpid):
- raise Errors.GroupsError, _("No Group named %s exists") % to_unicode(grpid)
-
txmbrs_used = []
thesegroups = self.comps.return_groups(grpid)
commit 1cedb184fe356252b0f22988ef8cd88d2de365ce
Author: James Antill <james@and.org>
Date: Mon Dec 16 17:37:16 2013 -0500

Contain selectGroup() exceptions when selecting environments. BZ 1014202.

diff --git a/yum/__init__.py b/yum/__init__.py
index 2709225..72052ab 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4007,10 +4007,13 @@ much more problems).
evgrp.allgroups)
grps = ",".join(sorted(grps))
- txs = self.selectGroup(grps,
- group_package_types,
- enable_group_conditionals, upgrade,
- ievgrp=ievgrp)
+ try:
+ txs = self.selectGroup(grps,
+ group_package_types,
+ enable_group_conditionals, upgrade,
+ ievgrp=ievgrp)
+ except Errors.GroupsError:
+ continue
ret.extend(txs)
return ret
commit 23b51f3242f066ebfa3d79df1a1122293f8ab432
Author: James Antill <james@and.org>
Date: Mon Dec 16 17:38:22 2013 -0500

Add groups from installed environments, and unique, so we don't miss any.

diff --git a/yum/__init__.py b/yum/__init__.py
index 72052ab..633bd76 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3991,7 +3991,7 @@ much more problems).
elif self.conf.group_command == 'objects':
igroup_data = self._groupInstalledEnvData(evgrp)
- grps = []
+ grps = set()
for grpid in evgrp.groups:
if (grpid not in igroup_data or
igroup_data[grpid].startswith('blacklisted')):
@@ -3999,9 +3999,10 @@ much more problems).
self.verbose_logger.log(logginglevels.DEBUG_2,
msg, grpid, evgrp.environmentid)
continue
- grps.append(grpid)
+ grps.add(grpid)
if evgrp.environmentid in self.igroups.environments:
ievgrp = self.igroups.environments[evgrp.environmentid]
+ grps.update(ievgrp.grp_names)
else:
self.igroups.add_environment(evgrp.environmentid,
evgrp.allgroups)
commit 4926655b7acd588de34322b07a5cf54de24f33dc
Author: James Antill <james@and.org>
Date: Mon Dec 16 17:48:16 2013 -0500

Change groupupdate command to call "group update" back compat. too confusing.

diff --git a/yumcommands.py b/yumcommands.py
index b346128..e01c96d 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -890,7 +890,7 @@ class GroupsCommand(YumCommand):
direct_commands = {'grouplist' : 'list',
'groupinstall' : 'install',
- 'groupupdate' : 'install',
+ 'groupupdate' : 'update',
'groupremove' : 'remove',
'grouperase' : 'remove',
'groupinfo' : 'info'}
commit 0a07500f2c4c76a1cb1ef428a7585238802e0a86
Author: James Antill <james@and.org>
Date: Mon Dec 16 17:49:15 2013 -0500

Have "yum group upgrade" do all, as "yum upgrade" does in objs. mode.

diff --git a/cli.py b/cli.py
index 180ba99..be8c46f 100755
--- a/cli.py
+++ b/cli.py
@@ -1913,6 +1913,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
2 = we've got work yet to do, onto the next stage
"""
pkgs_used = []
+
+ if not grouplist and self.conf.group_command == 'objects':
+ # Do what "yum upgrade" does when upgrade_group_objects_upgrade is
+ # set.
+ for ievgrp in self.igroups.environments:
+ pkgs_used.extend(self._at_groupupgrade('@^' + ievgrp))
+ for igrp in self.igroups.groups:
+ pkgs_used.extend(self._at_groupupgrade('@' + igrp))
for group_string in grouplist:
commit c8f16477b2deaeaf78ba88b9ea38b565061412a9
Author: James Antill <james@and.org>
Date: Tue Dec 17 10:48:44 2013 -0500

Don't add all grps in the installed evgrp, just those that belong.

diff --git a/yum/__init__.py b/yum/__init__.py
index 633bd76..b7eedf4 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4002,7 +4002,15 @@ much more problems).
grps.add(grpid)
if evgrp.environmentid in self.igroups.environments:
ievgrp = self.igroups.environments[evgrp.environmentid]
- grps.update(ievgrp.grp_names)
+ # Add groups from the installed evgrp, for Eg. installed
+ # only evgrps.
+ for grp_name in ievgrp.grp_names:
+ if grp_name not in self.igroups.groups:
+ continue
+ grp_evgrpid = self.igroups.groups[grp_name].environment
+ if grp_evgrpid != evgrp.environmentid:
+ continue
+ grps.add(grp_name)
else:
self.igroups.add_environment(evgrp.environmentid,
evgrp.allgroups)
commit a6f1124787cff91c435f9c8da2d658fe241ad026
Author: James Antill <james@and.org>
Date: Tue Dec 17 16:36:31 2013 -0500

Don't confuse <group info> output by giving data for optional when it's off.

diff --git a/output.py b/output.py
index 041910c..eb38d7d 100755
--- a/output.py
+++ b/output.py
@@ -1131,10 +1131,14 @@ class YumOutput:
if group.langonly:
print _(' Language: %s') % group.langonly
- sections = ((_(' Mandatory Packages:'), group.mandatory_packages),
- (_(' Default Packages:'), group.default_packages),
- (_(' Optional Packages:'), group.optional_packages),
- (_(' Conditional Packages:'), group.conditional_packages))
+ sections = (('mandatory', _(' Mandatory Packages:'),
+ group.mandatory_packages),
+ ('default', _(' Default Packages:'),
+ group.default_packages),
+ ('optional', _(' Optional Packages:'),
+ group.optional_packages),
+ (None, _(' Conditional Packages:'),
+ group.conditional_packages))
columns = None
if verb:
data = {'envra' : {}, 'rid' : {}}
@@ -1145,12 +1149,21 @@ class YumOutput:
columns = self.calcColumns(data)
columns = (-columns[0], -columns[1])
- for (section_name, pkg_names) in sections:
+ for (section_type, section_name, pkg_names) in sections:
+ # Only display igroup data for things that we'll actually try to
+ # install.
+ if section_type is None:
+ tigroup_data = igroup_data
+ elif section_type in self.conf.group_package_types:
+ tigroup_data = igroup_data
+ else:
+ tigroup_data = None
+
if len(pkg_names) > 0:
print section_name
self._displayPkgsFromNames(pkg_names, verb, pkg_names2pkgs,
columns=columns,
- igroup_data=igroup_data)
+ igroup_data=tigroup_data)
if igrp_only:
print _(' Installed Packages:')
self._displayPkgsFromNames(igrp_only, verb, pkg_names2pkgs,
commit 14bf13706a708764065e729998a30a991541906e
Author: James Antill <james@and.org>
Date: Tue Dec 17 16:40:00 2013 -0500

Pass the ievgrp to groups for new installed envs., so they belong. BZ 1043231

diff --git a/yum/__init__.py b/yum/__init__.py
index b7eedf4..1c17768 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4012,8 +4012,8 @@ much more problems).
continue
grps.add(grp_name)
else:
- self.igroups.add_environment(evgrp.environmentid,
- evgrp.allgroups)
+ ievgrp = self.igroups.add_environment(evgrp.environmentid,
+ evgrp.allgroups)
grps = ",".join(sorted(grps))
try:
commit d6ddfc90cda8c4e735a55628960ff623f40b27f6
Author: James Antill <james@and.org>
Date: Tue Dec 17 17:01:13 2013 -0500

Fix typo with simple groups compile of environment with only options.

diff --git a/yum/comps.py b/yum/comps.py
index 706e2a4..92e87ba 100755
--- a/yum/comps.py
+++ b/yum/comps.py
@@ -879,7 +879,7 @@ class Comps(object):
break
else:
evgroup.installed = False
- for grpname in evgroup.optional:
+ for grpname in evgroup.options:
if grpname in inst_grp_names:
evgroup.installed = True
break
commit 926f893eaa933b086d442957ee271348bfb1d2a3
Author: James Antill <james@and.org>
Date: Tue Dec 17 16:56:19 2013 -0500

Fix mark-convert-whitelist, and add mark-convert-blacklist (default).

diff --git a/docs/yum.8 b/docs/yum.8
index dff88af..e0bd5da 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -320,9 +320,19 @@ the packages as a member of the group.
"\fBgroup mark packages-force\fP" works like mark packages, but doesn't care if
the packages are already members of another group.
-"\fBgroup mark convert\fP" converts the automatic data you get without using
-groups as objects into groups as objects data. This makes it much easier to
-convert to groups as objects without having to reinstall.
+"\fBgroup mark convert-blacklist\fP"
+
+"\fBgroup mark convert-whitelist\fP"
+
+"\fBgroup mark convert\fP" converts the automatic data you get
+without using groups as objects into groups as objects data, in other words
+this will make "yum --setopt=group_command=objects groups list" look as similar
+as possible to the current output of
+"yum --setopt=group_command=simple groups list". This makes it much
+easier to convert to groups as objects without having to reinstall. For groups
+that are installed the whitelist variant will mark all uninstalled packages for
+the group as to be installed on the next "yum group upgrade", the blacklist
+variant (current default) will mark them all as blacklisted.
"\fBgroup unmark packages\fP" remove a package as a member from any groups.
.IP
diff --git a/yumcommands.py b/yumcommands.py
index e01c96d..f07d270 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -973,6 +973,7 @@ class GroupsCommand(YumCommand):
'mark-groups-sync', 'mark-groups-sync-force')
ocmds_all = ('mark-install', 'mark-remove', 'mark-convert',
+ 'mark-convert-whitelist', 'mark-convert-blacklist',
'mark-packages', 'mark-packages-force',
'unmark-packages',
'mark-packages-sync', 'mark-packages-sync-force',
@@ -1002,13 +1003,13 @@ class GroupsCommand(YumCommand):
pass
elif not os.path.exists(os.path.dirname(base.igroups.filename)):
base.logger.critical(_("There is no installed groups file."))
- base.logger.critical(_("Maybe run: yum groups mark convert"))
+ base.logger.critical(_("Maybe run: yum groups mark convert (see man yum)"))
elif not os.access(os.path.dirname(base.igroups.filename), os.R_OK):
base.logger.critical(_("You don't have access to the groups DBs."))
raise cli.CliError
elif not os.path.exists(base.igroups.filename):
base.logger.critical(_("There is no installed groups file."))
- base.logger.critical(_("Maybe run: yum groups mark convert"))
+ base.logger.critical(_("Maybe run: yum groups mark convert (see man yum)"))
elif not os.access(base.igroups.filename, os.R_OK):
base.logger.critical(_("You don't have access to the groups DB."))
raise cli.CliError
@@ -1157,14 +1158,15 @@ class GroupsCommand(YumCommand):
return 0, ['Marked groups-sync: ' + ','.join(extcmds)]
# FIXME: This doesn't do environment groups atm.
- if cmd == 'mark-convert':
+ if cmd in ('mark-convert',
+ 'mark-convert-whitelist', 'mark-convert-blacklist'):
# Convert old style info. into groups as objects.
def _convert_grp(grp):
if not grp.installed:
return
pkg_names = []
- for pkg in base.rpmdb.searchNames(pkg_names):
+ for pkg in base.rpmdb.searchNames(grp.packages):
if 'group_member' in pkg.yumdb_info:
continue
pkg.yumdb_info.group_member = grp.groupid
@@ -1173,7 +1175,10 @@ class GroupsCommand(YumCommand):
# We only mark the packages installed as a known part of
# the group. This way "group update" will work and install
# any remaining packages, as it would before the conversion.
- base.igroups.add_group(grp.groupid, pkg_names)
+ if cmd == 'mark-convert-whitelist':
+ base.igroups.add_group(grp.groupid, pkg_names)
+ else:
+ base.igroups.add_group(grp.groupid, grp.packages)
# Blank everything.
for gid in base.igroups.groups.keys():
commit 22f07ea55219b325b17e93406ee272a1ba492378
Author: James Antill <james@and.org>
Date: Tue Dec 17 17:19:12 2013 -0500

Add _igroup_member, so we can find installing groups for output.

diff --git a/yum/__init__.py b/yum/__init__.py
index 1c17768..b86c451 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3849,6 +3849,8 @@ much more problems).
txmbr.group_member = thisgroup.groupid
if lupgrade: # For list transaction.
txmbr._ugroup_member = thisgroup
+ else:
+ txmbr._igroup_member = thisgroup
except Errors.InstallError, e:
self.verbose_logger.debug(_('No package named %s available to be installed'),
pkg)
commit d8794ef4df1704b65f2dbb97ad5a94c7c02b134e
Author: James Antill <james@and.org>
Date: Tue Dec 17 17:19:28 2013 -0500

Show install groups as well as upgrading groups in transaction output.

diff --git a/output.py b/output.py
index eb38d7d..38045e9 100755
--- a/output.py
+++ b/output.py
@@ -1525,16 +1525,26 @@ class YumOutput:
# Show new pkgs. that are installed via. a group.
ninstalled = []
for txmbr in self.tsInfo.installed:
- if not hasattr(txmbr, '_ugroup_member'):
+ if hasattr(txmbr, '_igroup_member'):
+ key = ('i', txmbr._igroup_member)
+ if key not in ginstalled:
+ ginstalled[key] = []
+ ginstalled[key].append(txmbr)
+ elif hasattr(txmbr, '_ugroup_member'):
+ key = ('u', txmbr._ugroup_member)
+ if key not in ginstalled:
+ ginstalled[key] = []
+ ginstalled[key].append(txmbr)
+ else:
ninstalled.append(txmbr)
- continue
- if txmbr._ugroup_member not in ginstalled:
- ginstalled[txmbr._ugroup_member] = []
- ginstalled[txmbr._ugroup_member].append(txmbr)
- for grp in sorted(ginstalled, key=lambda x: x.ui_name):
- action = _('Installing for group upgrade "%s"') % grp.ui_name
- pkglist = ginstalled[grp]
+ for (T, grp) in sorted(ginstalled, key=lambda x: x[1].ui_name):
+ if T == 'u':
+ msg = _('Installing for group upgrade "%s"')
+ else:
+ msg = _('Installing for group install "%s"')
+ action = msg % grp.ui_name
+ pkglist = ginstalled[(T, grp)]
lines = []
for txmbr in pkglist:
commit 5bd3c6aa6926a427a7ef660868ac7aa1adbd83f9
Author: James Antill <james@and.org>
Date: Tue Dec 17 17:24:17 2013 -0500

Canonicalize the "no group" warnings to env. group and pkg group.

diff --git a/cli.py b/cli.py
index be8c46f..2873656 100755
--- a/cli.py
+++ b/cli.py
@@ -1944,7 +1944,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
txmbrs = self.selectEnvironment(group.environmentid,
upgrade=upgrade)
except yum.Errors.GroupsError:
- self.logger.critical(_('Warning: environment %s does not exist.'), group_string)
+ self.logger.critical(_('Warning: Environment group %s does not exist.'), group_string)
continue
else:
pkgs_used.extend(txmbrs)
@@ -1958,7 +1958,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
try:
txmbrs = self.selectGroup(group.groupid, upgrade=upgrade)
except yum.Errors.GroupsError:
- self.logger.critical(_('Warning: group %s does not exist.'), group_string)
+ self.logger.critical(_('Warning: Package group %s does not exist.'), group_string)
continue
else:
pkgs_used.extend(txmbrs)
diff --git a/yum/__init__.py b/yum/__init__.py
index b86c451..41c932c 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4494,7 +4494,7 @@ much more problems).
assert False, "Checked in for loop."
continue
if not found:
- self.logger.error(_('Warning: group %s does not exist.'),
+ self.logger.error(_('Warning: Package group %s does not exist.'),
group_string)
return tx_return
commit 31ef7b51e3d079e0f0203af1366e38577cdc8947
Author: James Antill <james@and.org>
Date: Tue Dec 17 17:38:22 2013 -0500

Tell users how to mark install/remove groups without packages.

diff --git a/cli.py b/cli.py
index 2873656..c05a4cf 100755
--- a/cli.py
+++ b/cli.py
@@ -1968,6 +1968,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
continue
if not pkgs_used:
+ if base.conf.group_command == 'objects':
+ self.logger.critical(_("Maybe run: yum groups mark install (see man yum)"))
return 0, [_('No packages in any requested group available to install or update')]
else:
return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)]
@@ -2024,6 +2026,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
pkgs_used.extend(txmbrs)
if not pkgs_used:
+ if base.conf.group_command == 'objects':
+ self.logger.critical(_("Maybe run: yum groups mark remove (see man yum)"))
return 0, [_('No packages to remove from groups')]
else:
return 2, [P_('%d package to remove', '%d packages to remove', len(pkgs_used)) % len(pkgs_used)]
commit 3722c9a8f3d1435462dd1abcf62a571a1b4b4d29
Author: James Antill <james@and.org>
Date: Tue Dec 17 17:38:26 2013 -0500

Add "groups mark blacklist" command to get out of the upgrade problem.

diff --git a/docs/yum.8 b/docs/yum.8
index e0bd5da..0e211eb 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -320,6 +320,10 @@ the packages as a member of the group.
"\fBgroup mark packages-force\fP" works like mark packages, but doesn't care if
the packages are already members of another group.
+"\fBgroup mark blacklist\fP" will blacklist all packages marked to be installed
+for a group. After this command a "yum group upgrade" will not install any new
+packages as part of the group.
+
"\fBgroup mark convert-blacklist\fP"
"\fBgroup mark convert-whitelist\fP"
diff --git a/yumcommands.py b/yumcommands.py
index f07d270..291eae5 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -965,6 +965,7 @@ class GroupsCommand(YumCommand):
ocmds_arg = []
if base.conf.group_command == 'objects':
ocmds_arg = ('mark-install', 'mark-remove',
+ 'mark-blacklist',
'mark-packages', 'mark-packages-force',
'unmark-packages',
'mark-packages-sync', 'mark-packages-sync-force',
@@ -974,6 +975,7 @@ class GroupsCommand(YumCommand):
ocmds_all = ('mark-install', 'mark-remove', 'mark-convert',
'mark-convert-whitelist', 'mark-convert-blacklist',
+ 'mark-blacklist',
'mark-packages', 'mark-packages-force',
'unmark-packages',
'mark-packages-sync', 'mark-packages-sync-force',
@@ -1063,6 +1065,24 @@ class GroupsCommand(YumCommand):
base.igroups.save()
return 0, ['Marked install: ' + ','.join(extcmds)]
+ if cmd == 'mark-blacklist':
+ gRG = base._groupReturnGroups(extcmds,ignore_case=False)
+ igrps, grps, ievgrps, evgrps = gRG
+ for ievgrp in ievgrps:
+ evgrp = base.comps.return_environment(igrp.evgid)
+ if not evgrp:
+ continue
+ base.igroups.changed = True
+ ievgrp.grp_names.update(grp.groups)
+ for igrp in igrps:
+ grp = base.comps.return_group(igrp.gid)
+ if not grp:
+ continue
+ base.igroups.changed = True
+ igrp.pkg_names.update(grp.packages)
+ base.igroups.save()
+ return 0, ['Marked upgrade blacklist: ' + ','.join(extcmds)]
+
if cmd in ('mark-packages', 'mark-packages-force'):
if len(extcmds) < 2:
return 1, ['No group or package given']
commit 1ec588666b376e5a61446c6ca1cd5ae764e0a590
Author: James Antill <james@and.org>
Date: Wed Dec 18 16:19:10 2013 -0500

Fix typo in new mark install/remove messages.

diff --git a/cli.py b/cli.py
index c05a4cf..5b44b2c 100755
--- a/cli.py
+++ b/cli.py
@@ -1968,7 +1968,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
continue
if not pkgs_used:
- if base.conf.group_command == 'objects':
+ if self.conf.group_command == 'objects':
self.logger.critical(_("Maybe run: yum groups mark install (see man yum)"))
return 0, [_('No packages in any requested group available to install or update')]
else:
@@ -2026,7 +2026,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
pkgs_used.extend(txmbrs)
if not pkgs_used:
- if base.conf.group_command == 'objects':
+ if self.conf.group_command == 'objects':
self.logger.critical(_("Maybe run: yum groups mark remove (see man yum)"))
return 0, [_('No packages to remove from groups')]
else:
commit 48f1ff768211fc5c6b7e0254b0e655b4a4ba451e
Author: James Antill <james@and.org>
Date: Thu Dec 19 00:00:26 2013 -0500

Delete extra break from for to if change, which now breaks outer loop.

diff --git a/yum/__init__.py b/yum/__init__.py
index 41c932c..9fb88d4 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3506,7 +3506,6 @@ much more problems).
if igrp.environment == evgroup.environmentid:
ret[grp_name] = 'installed'
- break
else:
ret[grp_name] = 'blacklisted-installed'
commit 9d4dae82c83df81197502b4a4bebc73c1cb3bd3e
Author: James Antill <james@and.org>
Date: Fri Dec 20 14:46:33 2013 -0500

Fix traceback in group info -v.

diff --git a/output.py b/output.py
index 38045e9..2787d86 100755
--- a/output.py
+++ b/output.py
@@ -1142,7 +1142,7 @@ class YumOutput:
columns = None
if verb:
data = {'envra' : {}, 'rid' : {}}
- for (section_name, pkg_names) in sections:
+ for (section_type, section_name, pkg_names) in sections:
self._calcDataPkgColumns(data, pkg_names, pkg_names2pkgs,
igroup_data=igroup_data)
data = [data['envra'], data['rid']]

22
SOURCES/BZ-1052994-yum-cron-install-unsigned-packages.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
From: Zdenek Pavlas <zpavlas@redhat.com>
Date: Tue, 14 Jan 2014 14:41:45 +0000 (+0100)
Subject: yum-cron: fail when sigCheckPkg() returns 2. BZ 1052440
X-Git-Url: http://yum.baseurl.org/gitweb?p=yum.git;a=commitdiff_plain;h=9df69e579496ccb6df5c3f5b5b7bab8d648b06b4

yum-cron: fail when sigCheckPkg() returns 2. BZ 1052440
---

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 386a7a0..87b3e69 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -547,6 +547,9 @@ class YumCronBase(yum.YumBase, YumOutput):
except yum.Errors.YumBaseError, errmsg:
self.emitUpdateFailed([str(errmsg)])
return False
+ else:
+ self.emitUpdateFailed(err)
+ return False
del self.ts
self.initActionTs() # make a new, blank ts to populate

1469
SOURCES/BZ-1053289-misc-perf+UI+simple-bug+docs-fixes.patch

File diff suppressed because it is too large Load Diff

37
SOURCES/BZ-1058297-remove-del-for-weird-anaconda-C-NULL-exception.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
commit 4ec4888593f739328600d42c1ad5a33d6b72674a
Author: Vratislav Podzimek <vpodzime@redhat.com>
Date: Tue Apr 8 09:37:01 2014 -0400

Remove extra del(fo) for weird C NULL execption (it is valid). BZ 1058297.

diff --git a/yum/misc.py b/yum/misc.py
index 347a07a..cdc08a0 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -360,7 +360,6 @@ def checksum(sumtype, file, CHUNK=2**16, datasize=None):
if type(file) is types.StringType:
fo.close()
- del fo
# This screws up the length, but that shouldn't matter. We only care
# if this checksum == what we expect.
commit 7cd5919c13e4e5efbd9c0b291124893e550e3633
Author: Vratislav Podzimek <vpodzime@redhat.com>
Date: Tue Apr 15 09:46:23 2014 -0400

Remove CHUNK argument from open, in checksum. BZ 1058297.

diff --git a/yum/misc.py b/yum/misc.py
index cdc08a0..6850ae2 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -351,7 +351,7 @@ def checksum(sumtype, file, CHUNK=2**16, datasize=None):
if type(file) not in types.StringTypes:
fo = file # assume it's a file-like-object
else:
- fo = open(file, 'r', CHUNK)
+ fo = open(file, 'r')
data = Checksums([sumtype])
while data.read(fo, CHUNK):

1406
SOURCES/BZ-1062959-add-fs-command.patch

File diff suppressed because it is too large Load Diff

24
SOURCES/BZ-1063177-xml-traceback.patch

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
commit 6132fa0c489f85c93ce77587ae3db4930d5bb1a4
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue May 26 11:16:00 2015 +0200

Don't traceback on xml parsing. BZ#1063177

diff --git a/yum/repos.py b/yum/repos.py
index d5e50ac..a0ef28c 100644
--- a/yum/repos.py
+++ b/yum/repos.py
@@ -381,6 +381,13 @@ class RepoStorage:
sack = repo.getPackageSack()
try:
sack.populate(repo, mdtype, callback, cacheonly)
+ except TypeError, e:
+ if not e.args[0].startswith('Parsing'):
+ raise
+ if mdtype in ['all', 'metadata'] and repo.skip_if_unavailable:
+ self.disableRepo(repo.id)
+ else:
+ raise Errors.RepoError(e.args[0])
except Errors.RepoError, e:
if mdtype in ['all', 'metadata'] and repo.skip_if_unavailable:
self.disableRepo(repo.id)

42
SOURCES/BZ-1063181-upgrades-for-install-only.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
commit fada4b8dbd30d0335a9c07067a74dccec0abbedb
Author: James Antill <james@and.org>
Date: Mon Sep 29 11:40:54 2014 -0400

Don't look for upgrades for install only packages. BZ 1063181.

diff --git a/yum/__init__.py b/yum/__init__.py
index a8a4e80..83a546a 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4654,6 +4654,9 @@ much more problems).
# don't have to.
return po.pkgtup in self.up.updating_dict
+ if self.allowedMultipleInstalls(po):
+ return False
+
for ipkg in ipkgs:
if po.verLE(ipkg):
continue
diff -up yum-3.4.3/test/simpleupdatetests.py.old yum-3.4.3/test/simpleupdatetests.py
--- yum-3.4.3/test/simpleupdatetests.py.old 2014-09-30 11:01:39.000000000 +0200
+++ yum-3.4.3/test/simpleupdatetests.py 2014-09-30 11:02:19.513283044 +0200
@@ -1230,3 +1230,18 @@ class SimpleUpdateTests(OperationsTests)
self.assert_(self._pkg2txmbr(foo11).reason == 'user')
self.assert_(self._pkg2txmbr(bar11).reason == 'blahg')
+
+ def testInstall_kernel_intermediate(self):
+ # Make sure we don't break this again...
+ k11 = FakePackage('kernel', '1', '1', '0', 'i386')
+ k12 = FakePackage('kernel', '1', '2', '0', 'i386')
+ k13 = FakePackage('kernel', '1', '3', '0', 'i386')
+ k14 = FakePackage('kernel', '1', '4', '0', 'i386')
+ k15 = FakePackage('kernel', '1', '5', '0', 'i386')
+
+ res, msg = self.runOperation(['install', 'kernel-1-2'],
+ [k11, k13, k14],
+ [k11, k12, k13, k14, k15])
+
+ self.assert_(res=='ok', msg)
+ self.assertResult((k11, k12, k13, k14))

135
SOURCES/BZ-1065380-updateinfo-strip-respin.patch

@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
commit 7b92efd65fea5187d295ffc4fcb49dcfbe822623
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Tue May 17 13:04:52 2016 +0200

updateinfo: strip respin suffix if present. BZ 1065380

diff --git a/docs/yum.8 b/docs/yum.8
index 9c09c48..efaa061 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -1091,6 +1091,17 @@ To get the information on advisory FEDORA-2707-4567 use:
.IP
yum updateinfo info FEDORA-2707-4567
.PP
+For Red Hat advisories, respin suffixes are also accepted in the ID, although
+they won't have any effect on the actual respin selected by yum, as it will
+always select the latest one available. For example, if you use:
+.IP
+yum updateinfo info RHSA-2016:1234-2
+.PP
+while RHSA-2016:1234-3 has been shipped already, yum will select the latter
+(provided your updateinfo.xml is current). The same would happen if you just
+specified RHSA-2016:1234. That said, there's no need for you to specify or
+care about the suffix at all.
+.PP
To update packages to the latest version which contain fixes for Bugzillas 123, 456 and 789; and all security updates use:
.IP
yum --bz 123 --bz 456 --bz 789 --security update
diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index 2b39330..7abe332 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -1,5 +1,6 @@
import os.path
+import re
from yum.i18n import _, P_
@@ -172,6 +173,40 @@ def _args2filters(args):
filters[T] = filters.get(T, []) + arg1.split(',')
return filters
+def _ysp_gen_opts(filters, sec_cmds=None):
+ def strip_respin(id_):
+ # Example: RHSA-2016:1234-2 -> RHSA-2016:1234
+ pattern = r'^(RH[BES]A\-\d+\:\d+)(\-\d+)?$'
+ match = re.match(pattern, id_)
+ if match:
+ return match.group(1)
+ return id_
+
+ opts = _updateinfofilter2opts(filters)
+ if sec_cmds is not None:
+ opts.sec_cmds = sec_cmds
+
+ # If a RH advisory was specified with a respin suffix, strip it out, as we
+ # don't include these suffixes in the notice update_id attribute either (we
+ # use the version attribute for that). Note that there's no ambiguity in
+ # which notice version we should match then, as updateinfo.xml should only
+ # contain one per advisory ID (we give a warning when duplicate IDs are
+ # detected in it). The reason we are handling this is that we sometimes
+ # refer to advisories in this form (e.g. on rhn.redhat.com/errata/...) and
+ # the user may then use it with yum too, in which case we would yield no
+ # matches.
+ #
+ # However, we used to put these suffixes in update_id in the past, so let's
+ # also keep the original (unstripped) form around in opts, just in case we
+ # are dealing with such an old updateinfo.xml.
+ for attr in ['sec_cmds', 'advisory']:
+ oldlist = getattr(opts, attr)
+ stripped = map(strip_respin, oldlist)
+ newlist = list(set(oldlist) | set(stripped))
+ setattr(opts, attr, newlist)
+
+ return opts
+
def _ysp_gen_used_map(opts):
used_map = {'bugzilla' : {}, 'cve' : {}, 'id' : {}, 'cmd' : {}, 'sev' : {}}
if True:
@@ -308,7 +343,7 @@ def remove_txmbrs(base, filters=None):
if filters is None:
filters = base.updateinfo_filters
- opts = _updateinfofilter2opts(filters)
+ opts = _ysp_gen_opts(filters)
if _no_options(opts):
return 0, 0, 0
@@ -392,7 +427,7 @@ def exclude_updates(base, filters=None):
if filters is None:
filters = base.updateinfo_filters
- opts = _updateinfofilter2opts(filters)
+ opts = _ysp_gen_opts(filters)
if _no_options(opts):
return 0, 0
@@ -446,7 +481,7 @@ def exclude_all(base, filters=None):
if filters is None:
filters = base.updateinfo_filters
- opts = _updateinfofilter2opts(filters)
+ opts = _ysp_gen_opts(filters)
if _no_options(opts):
return 0, 0
@@ -487,7 +522,7 @@ def update_minimal(base, extcmds=[]):
txmbrs = []
used_map = _ysp_gen_used_map(base.updateinfo_filters)
- opts = _updateinfofilter2opts(base.updateinfo_filters)
+ opts = _ysp_gen_opts(base.updateinfo_filters)
ndata = _no_options(opts)
# NOTE: Not doing obsoletes processing atm. ... maybe we should? --
--- yum-3.4.3/yumcommands.py.orig 2016-05-19 12:58:38.354630030 +0200
+++ yum-3.4.3/yumcommands.py 2016-05-19 12:59:37.385260152 +0200
@@ -4071,7 +4071,6 @@
# or -q deletes everything.
print x
- opts = _upi._updateinfofilter2opts(base.updateinfo_filters)
extcmds, show_type, filt_type = self._parse_extcmds(extcmds)
list_type = "available"
@@ -4081,7 +4080,7 @@
if filt_type is None:
extcmds, show_type, filt_type = self._parse_extcmds(extcmds)
- opts.sec_cmds = extcmds
+ opts = _upi._ysp_gen_opts(base.updateinfo_filters, extcmds)
used_map = _upi._ysp_gen_used_map(base.updateinfo_filters)
iname2tup = {}
if False: pass

16
SOURCES/BZ-1087911-update-minimal-manpage.patch

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
@@ -, +, @@
---
docs/yum.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/docs/yum.8
+++ a/docs/yum.8
@@ -25,7 +25,7 @@ gnome\-packagekit application\&.
.br
.I \fR * update-to [package1] [package2] [\&.\&.\&.]
.br
-.I \fR * minimal-update [package1] [package2] [\&.\&.\&.]
+.I \fR * update-minimal [package1] [package2] [\&.\&.\&.]
.br
.I \fR * check\-update
.br
--

18
SOURCES/BZ-1095146-file-uris-normpath.patch

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
commit bec81af1bffdd3c3511ad8861fb66b376bee89e9
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Mar 27 16:56:19 2014 +0100

normpath() file URIs. BZ 1009499

diff --git a/yum/__init__.py b/yum/__init__.py
index 84ca658..ac01435 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -562,6 +562,7 @@ class YumBase(depsolve.Depsolve):
# if we don't do this then anaconda likes to not work.
if os.path.exists(self.conf.installroot+'/'+reposdir):
reposdir = self.conf.installroot + '/' + reposdir
+ reposdir = os.path.normpath(reposdir)
if os.path.isdir(reposdir):
for repofn in sorted(glob.glob('%s/*.repo' % reposdir)):

80
SOURCES/BZ-1095157-traceback-when-empty-history.patch

@ -0,0 +1,80 @@ @@ -0,0 +1,80 @@
commit 1c557629752d26dca86948c5e933d8f31448818d
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Apr 17 16:15:22 2014 +0200

Fix traceback when the history dir is empty. BZ 875610

diff --git a/yum/history.py b/yum/history.py
index 3f20128..2f423d9 100644
--- a/yum/history.py
+++ b/yum/history.py
@@ -697,7 +697,9 @@ class YumHistory:
break
if self._db_file is None:
- self._create_db_file()
+ if not self._create_db_file():
+ # Couldn't create a db file
+ return
# make an addon path for where we're going to stick
# random additional history info - probably from plugins and what-not
@@ -1603,8 +1605,10 @@ class YumHistory:
if os.path.exists(_db_file + '-journal'):
os.rename(_db_file + '-journal', _db_file + '-journal.old')
self._db_file = _db_file
+ if not self.conf.writable:
+ return False
- if self.conf.writable and not os.path.exists(self._db_file):
+ if not os.path.exists(self._db_file):
# make them default to 0600 - sysadmin can change it later
# if they want
fo = os.open(self._db_file, os.O_CREAT, 0600)
@@ -1659,6 +1663,7 @@ class YumHistory:
for op in self._update_ops_3:
cur.execute(op)
self._commit()
+ return True
# Pasted from sqlitesack
_FULL_PARSE_QUERY_BEG = """
commit 8c6cd83a4825155d1ee9ddcd29b023682944e3e6
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 12 15:41:30 2014 +0100

Fix traceback when history files don't exist and user is not root.

diff --git a/yum/history.py b/yum/history.py
index 6f60f54..3f20128 100644
--- a/yum/history.py
+++ b/yum/history.py
@@ -668,6 +668,7 @@ class YumHistory:
self.releasever = releasever
+ self._db_file = None
if not os.path.exists(self.conf.db_path):
try:
os.makedirs(self.conf.db_path)
@@ -680,7 +681,6 @@ class YumHistory:
self.conf.writable = True
DBs = glob.glob('%s/history-*-*-*.sqlite' % self.conf.db_path)
- self._db_file = None
for d in reversed(sorted(DBs)):
fname = os.path.basename(d)
fname = fname[len("history-"):-len(".sqlite")]
diff --git a/yumcommands.py b/yumcommands.py
index 4e72a71..75b3ce2 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -3051,7 +3051,7 @@ class HistoryCommand(YumCommand):
if extcmds and extcmds[0] in ('repeat', 'redo', 'undo', 'rollback', 'new'):
checkRootUID(base)
checkGPGKey(base)
- elif not os.access(base.history._db_file, os.R_OK):
+ elif not (base.history._db_file and os.access(base.history._db_file, os.R_OK)):
base.logger.critical(_("You don't have access to the history DB."))
raise cli.CliError

19
SOURCES/BZ-1095161-setopt-spaces-handling.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
commit 0954b42554b7f78809d9050886b419a99e28d289
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue May 13 15:50:52 2014 +0200

Make --setopt handle spaces properly. BZ 1094373

diff --git a/cli.py b/cli.py
index c1ef023..aa73278 100755
--- a/cli.py
+++ b/cli.py
@@ -193,7 +193,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
if len(vals) < 2:
bad_setopt_ne.append(item)
continue
- k,v = vals
+ k, v = [i.strip() for i in vals]
period = k.rfind('.')
if period != -1:
repo = k[:period]

36
SOURCES/BZ-1096147-history-search-crash.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
commit 5efc1e1b88398da7f89dcb9055d62481bb288a8a
Author: James Antill <james@and.org>
Date: Tue Sep 16 16:33:33 2014 -0400

Workaround history searching for [abc] character lists failures. BZ 1096147.

diff --git a/yum/history.py b/yum/history.py
index 2f423d9..fd80191 100644
--- a/yum/history.py
+++ b/yum/history.py
@@ -20,6 +20,7 @@
import time
import os, os.path
import glob
+import re
from weakref import proxy as weakref
from sqlutils import sqlite, executeSQL, sql_esc_glob
@@ -1422,6 +1423,17 @@ class YumHistory:
if cur is None:
return set()
+ # This is kind of a hack, we can't do 'y[u]m' in SQL. In real yum
+ # we manually load everything and then do it inside yum (which is slow
+ # and a lot of code, but nobody uses it anyway and we already had the
+ # code). Here we don't have the code though, and still nobody will use
+ # it. So we cheat:
+ # 1. Convert 'y[u]m' into 'y?m' ... it returns more answers than it
+ # should, but the correct answers are there.
+ # 2. Convert 'y[m' info 'y!m' ... neither will match anything, so w/e.
+ patterns = [re.sub('\[[^]]+\]', '?', x).replace('[', '!')
+ for x in patterns]
+
data = _setupHistorySearchSQL(patterns, ignore_case)
(need_full, npatterns, fields, names) = data

77
SOURCES/BZ-1097383-usr-readonly.patch

@ -0,0 +1,77 @@ @@ -0,0 +1,77 @@
commit 507182919894e9bf75b08a75cb22c49d852c8278
Author: James Antill <james@and.org>
Date: Wed May 21 15:14:55 2014 -0400

Check /usr for writability before running a transaction.

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 4ec7689..c39544d 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -892,6 +892,11 @@ shouldn't be needed as yum should always solve or fail, however it has been
observed that it can loop forever with very large system upgrades. Setting
this to `0' (or "<forever>") makes yum try forever. Default is `100'.
+.IP
+\fBusr_w_check\fR
+Either `0' or `1'. Set this to `0' to disable the checking for writability on
+/usr in the installroot (when going into the depsolving stage). Default is `1'
+(perform the check).
.SH "[repository] OPTIONS"
.LP
diff --git a/yum/config.py b/yum/config.py
index 7bb56d0..f0f4e96 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -906,6 +906,8 @@ class YumConf(StartupConf):
check_config_file_age = BoolOption(True)
+ usr_w_check = BoolOption(True)
+
_reposlist = []
def dump(self):
diff --git a/yummain.py b/yummain.py
index fa76af8..ee8d632 100755
--- a/yummain.py
+++ b/yummain.py
@@ -209,6 +209,17 @@ def main(args):
logger.critical(msg)
if unlock(): return 200
return 3
+
+ # Mainly for ostree, but might be useful for others.
+ if base.conf.usr_w_check:
+ usrinstpath = base.conf.installroot + "/usr"
+ usrinstpath = usrinstpath.replace('//', '/')
+ if not os.access(usrinstpath, os.W_OK):
+ logger.critical(_('No write access to %s directory') % usrinstpath)
+ logger.critical(_(' Maybe this is an ostree image?'))
+ logger.critical(_(' To disable you can use --setopt=usr_w_check=false'))
+ if unlock(): return 200
+ return 1
# Depsolve stage
verbose_logger.log(logginglevels.INFO_2, _('Resolving Dependencies'))
commit 6e64b142014dc3c5489aed7966f0948948054fb7
Author: James Antill <james@and.org>
Date: Wed May 21 18:29:28 2014 -0400

Check for existance, so mock etc. is happy.

diff --git a/yummain.py b/yummain.py
index ee8d632..24bbe6c 100755
--- a/yummain.py
+++ b/yummain.py
@@ -214,7 +214,8 @@ def main(args):
if base.conf.usr_w_check:
usrinstpath = base.conf.installroot + "/usr"
usrinstpath = usrinstpath.replace('//', '/')
- if not os.access(usrinstpath, os.W_OK):
+ if (os.path.exists(usrinstpath) and
+ not os.access(usrinstpath, os.W_OK)):
logger.critical(_('No write access to %s directory') % usrinstpath)
logger.critical(_(' Maybe this is an ostree image?'))
logger.critical(_(' To disable you can use --setopt=usr_w_check=false'))

69
SOURCES/BZ-1102585-variable-substitution.patch

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
commit 28cc43d16664a408f7e4315767230544d7f52618
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon May 19 16:21:46 2014 +0200

Replace vars in include lines in .repo files. BZ 977380

diff --git a/yum/parser.py b/yum/parser.py
index b165ef2..5110cb5 100644
--- a/yum/parser.py
+++ b/yum/parser.py
@@ -18,6 +18,8 @@ def varReplace(raw, vars):
@return: Input raw string with substituted values.
'''
+ if not vars:
+ return raw
done = [] # Completed chunks to return
while raw:
@@ -136,6 +138,7 @@ class ConfigPreProcessor:
'Error parsing config %s: include must specify file to include.' % (self.name)
else:
# whooohoo a valid include line.. push it on the stack
+ url = varReplace(url, self._vars)
fo = self._pushfile( url )
else:
# check if the current line starts a new section
@@ -156,9 +159,7 @@ class ConfigPreProcessor:
line = line.lstrip()
# at this point we have a line from the topmost file on the stack
# or EOF if the stack is empty
- if self._vars:
- return varReplace(line, self._vars)
- return line
+ return varReplace(line, self._vars)
def _absurl( self, url ):
commit 04c46c81f556e3e5ee72630f9501e243d00528a7
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Jun 11 11:13:00 2014 +0200

Read env vars in readStartupConfig() to make them work in yum.conf. BZ 1102575

diff --git a/yum/config.py b/yum/config.py
index f0f4e96..6e0ecdc 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1042,6 +1042,11 @@ def readStartupConfig(configfile, root, releasever=None):
startupconf.config_file_path = configfile
parser = ConfigParser()
confpp_obj = ConfigPreProcessor(configfile)
+
+ yumvars = _getEnvVar()
+ confpp_obj._vars = yumvars
+ startupconf.yumvars = yumvars
+
try:
parser.readfp(confpp_obj)
except ParsingError, e:
@@ -1076,7 +1081,7 @@ def readMainConfig(startupconf):
# ' xemacs syntax hack
# Set up substitution vars
- yumvars = _getEnvVar()
+ yumvars = startupconf.yumvars
yumvars['basearch'] = startupconf.basearch
yumvars['arch'] = startupconf.arch
yumvars['releasever'] = startupconf.releasever

28
SOURCES/BZ-1113395-verify-permissions-mask.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
commit bb6908d630966d9e385659516c2759c47c0e2ee7
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri Mar 28 10:41:39 2014 +0100

Mask st_mode to fix verifying permissions for ghost files. BZ 1045415

diff --git a/yum/packages.py b/yum/packages.py
index 69c612f..9522235 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -2033,11 +2033,14 @@ class YumInstalledPackage(YumHeaderPackage):
problems.append(prob)
my_mode = my_st.st_mode
+ pf_mode = pf.mode
+ perm_mask = 0777
if 'ghost' in ftypes: # This is what rpm does, although it
- my_mode &= 0777 # doesn't usually get here.
- if check_perms and pf.verify_mode and my_mode != pf.mode:
+ my_mode &= perm_mask # doesn't usually get here.
+ pf_mode &= perm_mask
+ if check_perms and pf.verify_mode and my_mode != pf_mode:
prob = _PkgVerifyProb('mode', 'mode does not match', ftypes)
- prob.database_value = pf.mode
+ prob.database_value = pf_mode
prob.disk_value = my_st.st_mode
problems.append(prob)

51
SOURCES/BZ-1130939-dont-create-lockdir-directories.patch

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
commit ffb40e6a1b9c3f4b5b08151a04a5922fc5a9b521
Author: James Antill <james@and.org>
Date: Wed Jan 29 16:04:18 2014 -0500

Don't create lockdir directories, as they are magic now. BZ 975864

diff --git a/yum/__init__.py b/yum/__init__.py
index 222a378..0604d63 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2136,7 +2136,11 @@ much more problems).
lockfile = os.path.normpath(lockfile) # get rid of silly preceding extra /
mypid=str(os.getpid())
- while not self._lock(lockfile, mypid, 0644):
+ while True:
+ ret = self._lock(lockfile, mypid, 0644)
+ if ret:
+ break
+
oldpid = self._get_locker(lockfile)
if not oldpid:
# Invalid locker: unlink lockfile and retry
@@ -2147,6 +2151,13 @@ much more problems).
# Another copy seems to be running.
msg = _('Existing lock %s: another copy is running as pid %s.') % (lockfile, oldpid)
raise Errors.LockError(0, msg, oldpid)
+
+ if ret == 2:
+ # Means lockdir isn't setup, out of bad options just run without
+ # locks.
+ return
+
+ assert ret == 1
# We've got the lock, store it so we can auto-unlock on __del__...
self._lockfile = lockfile
@@ -2186,7 +2197,12 @@ much more problems).
lockdir = os.path.dirname(filename)
try:
if not os.path.exists(lockdir):
- os.makedirs(lockdir, mode=0755)
+ # We used to os.makedirs(lockdir, mode=0755) ... but that
+ # causes problems now due to /var/run being a magic systemd dir.
+ # So we now just give up and run, hopefully nobody runs N
+ # instances before the magic dir. is activate.
+ return 2
+
fd = os.open(filename, os.O_EXCL|os.O_CREAT|os.O_WRONLY, mode)
os.write(fd, contents)
os.close(fd)

75
SOURCES/BZ-1138205-needs-restarting.patch

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
commit 7ef0f4ad556e3d4bfe0eeebd1f110de745adec3c
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 19 16:24:58 2014 +0100

Make utils.get_process_info() respect executable names with spaces.

diff --git a/utils.py b/utils.py
index 0b7191c..b00d312 100755
--- a/utils.py
+++ b/utils.py
@@ -114,18 +114,20 @@ def get_process_info(pid):
break
if boot_time is None:
return
- ps_stat = open("/proc/%d/stat" % pid).read().split()
- ps['utime'] = jiffies_to_seconds(ps_stat[13])
- ps['stime'] = jiffies_to_seconds(ps_stat[14])
- ps['cutime'] = jiffies_to_seconds(ps_stat[15])
- ps['cstime'] = jiffies_to_seconds(ps_stat[16])
- ps['start_time'] = boot_time + jiffies_to_seconds(ps_stat[21])
+ ps_stat = open("/proc/%d/stat" % pid).read().strip()
+ # Filename of the executable might contain spaces, so we throw it away
+ ps_stat = ps_stat[ps_stat.rfind(')') + 2:].split()
+ ps['utime'] = jiffies_to_seconds(ps_stat[11])
+ ps['stime'] = jiffies_to_seconds(ps_stat[12])
+ ps['cutime'] = jiffies_to_seconds(ps_stat[13])
+ ps['cstime'] = jiffies_to_seconds(ps_stat[14])
+ ps['start_time'] = boot_time + jiffies_to_seconds(ps_stat[19])
ps['state'] = {'R' : _('Running'),
'S' : _('Sleeping'),
'D' : _('Uninterruptible'),
'Z' : _('Zombie'),
'T' : _('Traced/Stopped')
- }.get(ps_stat[2], _('Unknown'))
+ }.get(ps_stat[0], _('Unknown'))
return ps
commit cf0464bea74f6e8d4650afee4e66d66bff2bc9a1
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 19 17:19:32 2014 +0100

Refactored utils.get_process_info() to make parts of it reusable.

diff --git a/utils.py b/utils.py
index b00d312..dbcd605 100755
--- a/utils.py
+++ b/utils.py
@@ -107,13 +107,21 @@ def get_process_info(pid):
return
if 'vmsize' not in ps:
return
- boot_time = None
- for line in open("/proc/stat"):
- if line.startswith("btime "):
- boot_time = int(line[len("btime "):-1])
- break
+ boot_time = get_boot_time()
if boot_time is None:
return
+ ps.update(get_process_time(pid, boot_time))
+ return ps
+
+
+def get_boot_time():
+ for line in open("/proc/stat"):
+ if line.startswith("btime "):
+ return int(line[len("btime "):-1])
+
+
+def get_process_time(pid, boot_time):
+ ps = {}
ps_stat = open("/proc/%d/stat" % pid).read().strip()
# Filename of the executable might contain spaces, so we throw it away
ps_stat = ps_stat[ps_stat.rfind(')') + 2:].split()

18
SOURCES/BZ-1147992-debuginfo-install-dolock-exception.patch

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
commit 221d46dde594ca9b69915ac128fc1a9a19f984a1
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Feb 17 12:31:59 2014 +0100

Fix debuginfo-install doLock() traceback. BZ 1062479

diff --git a/yum/__init__.py b/yum/__init__.py
index 3b6ed82..37ab468 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -2165,6 +2165,7 @@ much more problems).
self._unlock(lockfile)
continue
if oldpid == os.getpid(): # if we own the lock, we're fine
+ ret = 1
break
# Another copy seems to be running.
msg = _('Existing lock %s: another copy is running as pid %s.') % (lockfile, oldpid)

37
SOURCES/BZ-1168120-manpage.patch

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
commit eb04b4977d16c31435449a9796189f341e7dd7d3
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Jul 10 12:05:04 2014 +0200

yum manpage: move 'history info' description to its proper place.

diff --git a/docs/yum.8 b/docs/yum.8
index 86df6b0..998a5ad 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -535,6 +535,13 @@ The info/list/summary commands take either a transaction id or a package (with
wildcards, as in \fBSpecifying package names\fP), all three can also be passed
no arguments. list can be passed the keyword "all" to list all the transactions.
+The info command can also take ranges of transaction ids, of the form start..end,
+which will then display a merged history as if all the transactions in the range
+had happened at once\&.
+.br
+Eg. "history info 1..4" will merge the first four transactions and display them
+as a single transaction.
+
The packages-list/packages-info commands takes a package (with wildcards, as in
\fBSpecifying package names\fP). And show data from the point of view of that
package.
@@ -779,12 +786,6 @@ Checks the local rpmdb and produces information on any problems it finds. You
can pass the check command the arguments "dependencies", "duplicates", "obsoletes" or "provides",
to limit the checking that is performed (the default is "all" which does all).
-The info command can also take ranges of transaction ids, of the form
-start..end, which will then display a merged history as if all the
-transactions in the range had happened at once\&.
-.br
-Eg. "history info 1..4" will merge the first four transactions and display them
-as a single transaction.
.IP
.IP "\fBhelp\fP"
Produces help, either for all commands or if given a command name then the help

38
SOURCES/BZ-1168121-fssnapshot-manpage-fix.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
commit 07fc9f374b8f069be28c353d1a0949f41da7adf2
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Thu Feb 18 14:00:09 2016 +0100

docs: fix fssnapshot section in the manpage. BZ 1168121
- Include both aliases in the hanging tag
- Only use one alias throughout the text
- Fix a typo

diff --git a/docs/yum.8 b/docs/yum.8
index e428148..8569943 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -718,9 +718,9 @@ updateinfo data:
.br
.IP
-.IP "\fBfssnapshot\fP"
+.IP "\fBfssnapshot\fP or \fBfssnap\fP"
This command has a few sub-commands to act on the LVM data of the host, to list
-snapshots and the create and remove them. The simplest commands, to display
+snapshots and to create and remove them. The simplest commands, to display
information about the configured LVM snapshotable devices, are:
.br
@@ -734,9 +734,9 @@ information about the configured LVM snapshotable devices, are:
then you can create and delete snapshots using:
.br
-.I \fR yum fssnap create
+.I \fR yum fssnapshot create
.br
-.I \fR yum fssnap delete <device(s)>
+.I \fR yum fssnapshot delete <device(s)>
.br
.br

58
SOURCES/BZ-1168385-group-conditionals-deselect.patch

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
commit 0df9058960d3fa24aa7695a4a14524127cc0e9be
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue Apr 21 08:44:52 2015 +0200

Fix tsInfo.conditionals in deselect() when the package is not yet in the transaction BZ#1168385

diff --git a/AUTHORS b/AUTHORS
index 71845e1..350e136 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -24,6 +24,7 @@ YUM AUTHORS
James Antill
Panu Matilainen
Tambet Ingo
+ Valentina Mukhamedzhanova
Original Yup people:
diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index 9ce5025..ec2c7cb 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -237,6 +237,7 @@ class TransactionData:
if not txmbrs:
if self._inSack is not None:
pkgs = self._inSack.returnPackages(patterns=[pattern])
+ if pkgs: pass
elif self.pkgSack is None:
pkgs = []
else:
commit c8b564968286ffccbd46beeb40c95d5e1c74a2aa
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Jul 13 13:45:45 2015 +0200

Fix UnboundLocalError in deselect()

diff --git a/yum/transactioninfo.py b/yum/transactioninfo.py
index ec2c7cb..8d47caa 100644
--- a/yum/transactioninfo.py
+++ b/yum/transactioninfo.py
@@ -235,13 +235,13 @@ class TransactionData:
txmbrs = self.matchNaevr(na[0], na[1])
if not txmbrs:
+ pkgs = []
if self._inSack is not None:
pkgs = self._inSack.returnPackages(patterns=[pattern])
- if pkgs: pass
- elif self.pkgSack is None:
- pkgs = []
- else:
+
+ if not pkgs and self.pkgSack is not None:
pkgs = self.pkgSack.returnPackages(patterns=[pattern])
+
if not pkgs:
pkgs = self.rpmdb.returnPackages(patterns=[pattern])

22
SOURCES/BZ-1175309-enable-repos-instruction.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
commit 6c9e839ab7ebee6357bbac8ab8ec143fc8ead461
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri May 13 13:50:14 2016 +0200

Mention subscription-manager for enabling repos.

diff --git a/yumcommands.py b/yumcommands.py
index 1d0f5ac..2c8cecd 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -262,7 +262,10 @@ def checkEnabledRepo(base, possible_local_files=[]):
msg = _('There are no enabled repos.\n'
' Run "yum repolist all" to see the repos you have.\n'
- ' You can enable repos with yum-config-manager --enable <repo>')
+ ' To enable Red Hat Subscription Management repositories:\n'
+ ' subscription-manager repos --enable <repo>\n'
+ ' To enable custom repositories:\n'
+ ' yum-config-manager --enable <repo>')
base.logger.critical(msg)
raise cli.CliError

22
SOURCES/BZ-1175315-dont-require-enabled-repos-for-url.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
commit 9115c850c9fda46c26dcc0f2f627b7483aa39435
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Wed Jun 14 18:38:03 2017 +0200

Don't require enabled repos for URL installs. BZ 1175315
This makes the check consistent with installPkgs() (cli.py:979).

diff --git a/yumcommands.py b/yumcommands.py
index 502bcb3..1be1051 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -253,7 +253,8 @@ def checkEnabledRepo(base, possible_local_files=[]):
return
for lfile in possible_local_files:
- if lfile.endswith(".rpm") and os.path.exists(lfile):
+ if lfile.endswith(".rpm") and (yum.misc.re_remote_url(lfile) or
+ os.path.exists(lfile)):
return
# runs prereposetup (which "most" plugins currently use to add repos.)

88
SOURCES/BZ-1182075-yum-security-manpage.patch

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
commit 2e04296024bdb3b4745e7e36420eaffa04f80ec0
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Jun 17 18:50:40 2015 +0200

Add missing documentation from yum-security manpage. bug#1182075

diff --git a/docs/yum.8 b/docs/yum.8
index a0038f6..99862fa 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -938,6 +938,20 @@ Specifies an alternate directory to store packages.
Set any config option in yum config or repo files. For options in the global
config just use: \-\-setopt=option=value for repo options use: \-\-setopt=repoid.option=value
.PP
+.IP "\fB\-\-security\fP"
+This option includes packages that say they fix a security issue, in updates.
+.br
+.IP "\fB\--advisory=ADVS, --advisories=ADVS\fP"
+This option includes in updates packages corresponding to the advisory ID, Eg. FEDORA-2201-123.
+.IP "\fB\--bz=BZS\fP"
+This option includes in updates packages that say they fix a Bugzilla ID, Eg. 123.
+.IP "\fB\--cve=CVES\fP"
+This option includes in updates packages that say they fix a CVE - Common Vulnerabilities and Exposures ID (http://cve.mitre.org/about/), Eg. CVE-2201-0123.
+.IP "\fB\--bugfix\fP"
+This option includes in updates packages that say they fix a bugfix issue.
+.IP "\fB\--sec-severity=SEVS, --secseverity=SEVS\fP"
+This option includes in updates security relevant packages of the specified severity.
+
.SH "LIST OPTIONS"
The following are the ways which you can invoke \fByum\fP in list
@@ -1045,6 +1059,56 @@ Tell any enabled plugins to eliminate their cached data.
.IP "\fByum clean all\fP"
Does all of the above.
+.SH "EXAMPLES"
+.PP
+To list all updates that are security relevant, and get a return code on whether there are security updates use:
+.IP
+yum --security check-update
+.PP
+To upgrade packages that have security errata (upgrades to the latest
+available package) use:
+.IP
+yum --security update
+.PP
+To upgrade packages that have security errata (upgrades to the last
+security errata package) use:
+.IP
+yum --security update-minimal
+.PP
+To get a list of all BZs that are fixed for packages you have installed use:
+.IP
+yum updateinfo list bugzillas
+.PP
+To get a list of all security advisories, including the ones you have already
+installed use:
+.IP
+yum updateinfo list all security
+.PP
+To get the information on advisory FEDORA-2707-4567 use:
+.IP
+yum updateinfo info FEDORA-2707-4567
+.PP
+To update packages to the latest version which contain fixes for Bugzillas 123, 456 and 789; and all security updates use:
+.IP
+yum --bz 123 --bz 456 --bz 789 --security update
+.PP
+To update to the packages which just update Bugzillas 123, 456 and 789; and all security updates use:
+.IP
+yum --bz 123 --bz 456 --bz 789 --security update-minimal
+.PP
+To get an info list of the latest packages which contain fixes for Bugzilla 123; CVEs CVE-2207-0123 and CVE-2207-3210; and Fedora advisories FEDORA-2707-4567 and FEDORA-2707-7654 use:
+.IP
+yum --bz 123 --cve CVE-2207-0123 --cve CVE-2207-3210 --advisory FEDORA-2707-4567 --advisory FEDORA-2707-7654 info updates
+.PP
+To get a list of packages which are "new".
+.IP
+yum updateinfo list new
+.PP
+To get a summary of advisories you haven't installed yet use:
+.IP
+yum updateinfo summary
+
+
.PP
.SH "PLUGINS"
Yum can be extended through the use of plugins. A plugin is a Python ".py" file

40
SOURCES/BZ-1182096-yum-cron-conf-upgrade-minimal.patch

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
commit cc4dc5b663b0be13fe6bf4de96458f87c90793ad
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu May 21 11:08:06 2015 +0200

Replace 'upgrade-minimal' with documented 'update-minimal' in yum-cron.conf files. BZ#1182096

diff --git a/etc/yum-cron-hourly.conf b/etc/yum-cron-hourly.conf
index 2a588cd..63c0bb6 100644
--- a/etc/yum-cron-hourly.conf
+++ b/etc/yum-cron-hourly.conf
@@ -3,9 +3,9 @@
# default = yum upgrade
# security = yum --security upgrade
# security-severity:Critical = yum --sec-severity=Critical upgrade
-# minimal = yum --bugfix upgrade-minimal
-# minimal-security = yum --security upgrade-minimal
-# minimal-security-severity:Critical = --sec-severity=Critical upgrade-minimal
+# minimal = yum --bugfix update-minimal
+# minimal-security = yum --security update-minimal
+# minimal-security-severity:Critical = --sec-severity=Critical update-minimal
update_cmd = default
# Whether a message should emitted when updates are available.
diff --git a/etc/yum-cron.conf b/etc/yum-cron.conf
index 960fcc9..7ab4d04 100644
--- a/etc/yum-cron.conf
+++ b/etc/yum-cron.conf
@@ -3,9 +3,9 @@
# default = yum upgrade
# security = yum --security upgrade
# security-severity:Critical = yum --sec-severity=Critical upgrade
-# minimal = yum --bugfix upgrade-minimal
-# minimal-security = yum --security upgrade-minimal
-# minimal-security-severity:Critical = --sec-severity=Critical upgrade-minimal
+# minimal = yum --bugfix update-minimal
+# minimal-security = yum --security update-minimal
+# minimal-security-severity:Critical = --sec-severity=Critical update-minimal
update_cmd = default
# Whether a message should be emitted when updates are available,

21
SOURCES/BZ-1183669-corrupt-cache.patch

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
commit fb107337b2490d314a4f31562427cdebe9eca4e4
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Mar 17 16:35:29 2016 +0100

Disable repo with skip_if_unavailable=True if repomd.xml can't be retrieved.

diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index fc5d538..3f7e975 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -1460,6 +1460,10 @@ Insufficient space in download directory %s
else:
result = self._getFileRepoXML(local, text)
if result is None:
+ if self.skip_if_unavailable and self._metadata_cache_req in ('write', 'read-only:future'):
+ # Since skip_if_unavailable=True, we can just disable this repo
+ raise Errors.RepoError, "Can't download repomd.xml for %s" % self.ui_id
+
# Ignore this as we have a copy
self._revertOldRepoXML()
return False

66
SOURCES/BZ-1186690-compare_providers_priorities.patch

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
commit 9fb7032802a0f56cc85cf301478b48b3c72449e7
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue May 10 16:42:01 2016 +0200

Add compare_providers_priority repository option.

diff --git a/test/testbase.py b/test/testbase.py
index 467f8fb..73c97a1 100644
--- a/test/testbase.py
+++ b/test/testbase.py
@@ -89,6 +89,7 @@ class FakeRepo(object):
sack = self.__fake_sack
self.sack = sack
self.cost = 1000
+ self.compare_providers_priority = 80
def __cmp__(self, other):
""" Sort base class repos. by alphanumeric on their id, also
diff --git a/yum/config.py b/yum/config.py
index cae914d..1ee6dd3 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1032,6 +1032,8 @@ class RepoConf(BaseConfig):
check_config_file_age = Inherit(YumConf.check_config_file_age)
+ compare_providers_priority = IntOption(80, range_min=1, range_max=99)
+
class VersionGroupConf(BaseConfig):
"""Option definitions for version groups."""
diff --git a/yum/depsolve.py b/yum/depsolve.py
index b482115..3453456 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -1653,6 +1653,12 @@ class Depsolve(object):
pkgresults[po] += 5
# End of O(N*N): for nextpo in pkgs:
+
+ # Respect the repository priority for each provider, the default is 80
+ pkgresults[po] += (100 - po.repo.compare_providers_priority) * 10
+ self.verbose_logger.log(logginglevels.DEBUG_4,
+ _('compare_providers_priority for %s is %s' % (po, po.repo.compare_providers_priority)))
+
if _common_sourcerpm(po, reqpo):
self.verbose_logger.log(logginglevels.DEBUG_4,
_('common sourcerpm %s and %s' % (po, reqpo)))
diff -up yum-3.4.3/docs/yum.conf.5.old yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.old 2016-05-10 17:00:13.406111903 +0200
+++ yum-3.4.3/docs/yum.conf.5 2016-05-10 17:01:03.302427161 +0200
@@ -1229,6 +1229,14 @@ parallel, if possible. Defaults to True
Overrides the \fBui_repoid_vars\fR option from the [main] section for this
repository.
+.IP
+\fBcompare_providers_priority \fR
+During depsolving, when choosing the best provider among several, yum will respect
+the priority of each provider's repository (note that there are other factors
+which yum considers, which may overweigh the repository priority). The value is
+an integer from 1 to 99, 1 being the most preferred repository, and 99 being
+the least preferred one. By default all repositories have the priority of 80.
+
.SH "URL INCLUDE SYNTAX"
.LP
The inclusion of external configuration files is supported for /etc/yum.conf

161
SOURCES/BZ-1188960-API-missing-requires.patch

@ -0,0 +1,161 @@ @@ -0,0 +1,161 @@
commit 423f5ee15cb0184d6583b57429ba9cb5bd8cdd35
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Jun 24 17:05:59 2015 +0200

Plugin API update: missing_requires, pretty_output_update and promptYN fix. BZ#1188960

diff --git a/output.py b/output.py
index 091b58e..5a73f8e 100755
--- a/output.py
+++ b/output.py
@@ -2795,6 +2795,13 @@ to exit.
if lastdbv.end_rpmdbversion != rpmdbv:
self._rpmdb_warn_checks()
+ @staticmethod
+ def pretty_output_restring(restring):
+ for msg in restring:
+ prefix = _('Error: %s')
+ prefix2nd = (' ' * (utf8_width(prefix) - 2))
+ yield (prefix, msg.replace('\n', '\n' + prefix2nd))
+
class DepSolveProgressCallBack:
"""A class to provide text output callback functions for Dependency Solver callback."""
diff --git a/utils.py b/utils.py
index dbcd605..5ba320f 100755
--- a/utils.py
+++ b/utils.py
@@ -393,10 +393,8 @@ class YumUtilBase(YumBaseCli):
return 0
elif result == 1:
# Fatal error
- for msg in resultmsgs:
- prefix = _('Error: %s')
- prefix2nd = (' ' * (utf8_width(prefix) - 2))
- self.logger.critical(prefix, msg.replace('\n', '\n' + prefix2nd))
+ for prefix, msg in self.pretty_output_restring(resultmsgs):
+ self.logger.critical(prefix, msg)
if not self.conf.skip_broken:
self.verbose_logger.info(_(" You could try using --skip-broken to work around the problem"))
if not self._rpmdb_warn_checks(out=self.verbose_logger.info, warn=False):
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 797826f..a1aeac3 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -120,6 +120,7 @@ class Depsolve(object):
self.installedFileRequires = None
self.installedUnresolvedFileRequires = None
+ self._missing_requires = False
def doTsSetup(self):
"""Sets up the transaction set before it is used."""
@@ -375,6 +376,7 @@ class Depsolve(object):
return self._prco_req_nfv2req(req[0], req[1], req[2])
def _err_missing_requires(self, reqPo, reqTup):
+ self._missing_requires = True
if hasattr(self.dsCallback, 'format_missing_requires'):
msg = self.dsCallback.format_missing_requires(reqPo, reqTup)
if msg is not None: # PK
diff --git a/yum/plugins.py b/yum/plugins.py
index f34ea19..7034da9 100644
--- a/yum/plugins.py
+++ b/yum/plugins.py
@@ -63,7 +63,7 @@ from yum.i18n import utf8_width
# API, the major version number must be incremented and the minor version number
# reset to 0. If a change is made that doesn't break backwards compatibility,
# then the minor number must be incremented.
-API_VERSION = '2.6'
+API_VERSION = '2.7'
class DeprecatedInt(int):
"""A simple int subclass that is used to check when a deprecated
@@ -416,18 +416,22 @@ class PluginConduit:
converted_level = logginglevels.logLevelFromErrorLevel(level)
self.logger.log(converted_level, msg)
- def promptYN(self, msg):
+ def promptYN(self, msg, prompt=None):
"""Return a yes or no response, either from assumeyes already
being set, or from prompting the user.
- :param msg: the message to prompt the user with
+ :param msg: the message to show to the user
+ :param prompt: the question to ask the user (optional); defaults to 'Is this ok [y/N]: '
:return: 1 if the response is yes, and 0 if the response is no
"""
self.info(2, msg)
+ if self._base.conf.assumeno:
+ return False
if self._base.conf.assumeyes:
- return 1
+ return True
else:
- return self._base.userconfirm()
+ kwargs = {'prompt': prompt} if prompt else {}
+ return bool(self._base.userconfirm(**kwargs))
def getYumVersion(self):
"""Return a string representing the current version of yum."""
@@ -704,6 +708,14 @@ class DepsolvePluginConduit(MainPluginConduit):
self.resultcode = rescode
self.resultstring = restring
+ @property
+ def missing_requires(self):
+ """Boolean indicating if depsolving failed due to missing dependencies."""
+ return self._base._missing_requires
+
+ def pretty_output_restring(self):
+ return '\n'.join(prefix % msg for prefix, msg in self._base.pretty_output_restring(self.resultstring))
+
class CompareProvidersPluginConduit(MainPluginConduit):
"""Conduit to compare different providers of packages."""
diff --git a/yummain.py b/yummain.py
index 0c7c535..32680a8 100755
--- a/yummain.py
+++ b/yummain.py
@@ -248,10 +248,8 @@ def main(args):
return base.exit_code
elif result == 1:
# Fatal error
- for msg in resultmsgs:
- prefix = _('Error: %s')
- prefix2nd = (' ' * (utf8_width(prefix) - 2))
- logger.critical(prefix, msg.replace('\n', '\n' + prefix2nd))
+ for prefix, msg in base.pretty_output_restring(resultmsgs):
+ logger.critical(prefix, msg)
if base._depsolving_failed:
if not base.conf.skip_broken:
verbose_logger.info(_(" You could try using --skip-broken to work around the problem"))
commit 1c883b65432c288ad941a362a49c15a8e4fb74b9
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Jun 29 16:56:13 2015 +0200

Add conduit.confList to plugin API

diff --git a/yum/plugins.py b/yum/plugins.py
index 7034da9..6857626 100644
--- a/yum/plugins.py
+++ b/yum/plugins.py
@@ -504,6 +504,17 @@ class PluginConduit:
"""
return config.getOption(self._conf, section, opt, config.BoolOption(default))
+ def confList(self, section, opt, default=None):
+ """Read a boolean value from the plugin's own configuration file
+
+ :param section: configuration file section to read
+ :param opt: option name to read
+ :param default: value to read if the option is missing
+ :return: boolean option value read, or *default* if the option
+ was missing or could not be parsed
+ """
+ return config.getOption(self._conf, section, opt, config.ListOption(default))
+
def registerPackageName(self, name):
"""Register the name of a package to use.

32
SOURCES/BZ-1192239-update-minimal.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
commit bfeae9135994630147c4d6af8679f95157a90d76
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri Feb 14 13:54:30 2014 +0100

Fix update-minimal traceback (#1048584) and ignoring updates.

diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index 1cc207f..8d91f88 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -513,7 +513,7 @@ def update_minimal(base, extcmds=[]):
if extcmds and not _match_sec_cmd(extcmds, name, notice):
continue
if (not ndata and
- not _ysp_should_filter_pkg(base, name, notice, used_map)):
+ not _ysp_should_filter_pkg(opts, name, notice, used_map)):
continue
txmbrs.extend(base.update(name=pkgtup[0], arch=pkgtup[1],
epoch=pkgtup[2],
diff --git a/yumcommands.py b/yumcommands.py
index c93faa1..4e3b730 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -4156,7 +4156,7 @@ class UpdateMinimalCommand(YumCommand):
num = len(base.tsInfo)
_upi.update_minimal(base, extcmds)
- num -= len(base.tsInfo)
+ num = len(base.tsInfo) - num
if num > 0:
msg = '%d packages marked for minimal Update' % num

56
SOURCES/BZ-1193871-updateinfo-notice-when-arch-changed.patch

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
diff --git a/yum/update_md.py b/yum/update_md.py
--- a/yum/update_md.py 2015-01-19 07:44:35.567107008 -0500
+++ b/yum/update_md.py 2015-01-19 08:57:31.576489424 -0500
@@ -398,6 +399,9 @@ class UpdateMetadata(object):
except Errors.RepoMDError:
continue # No metadata found for this repo
+ self.arch_storage = ArchStorage()
+ self.archlist = self.arch_storage.archlist
+
def get_notices(self, name=None):
""" Return all notices. """
if name is None:
@@ -434,16 +438,29 @@ class UpdateMetadata(object):
name = oldpkgtup[0]
arch = oldpkgtup[1]
ret = []
+ other_arch_list = []
+ notices = set()
for notice in self.get_notices(name):
for upkg in notice['pkglist']:
for pkg in upkg['packages']:
+ other_arch = False
if pkg['name'] != name or pkg['arch'] != arch:
- continue
+ if (notice not in notices and pkg['name'] == name and pkg['arch'] in self.archlist):
+ other_arch = True
+ else:
+ continue
pkgtup = (pkg['name'], pkg['arch'], pkg['epoch'] or '0',
pkg['version'], pkg['release'])
if _rpm_tup_vercmp(pkgtup, oldpkgtup) <= 0:
continue
- ret.append((pkgtup, notice))
+ if other_arch:
+ other_arch_list.append((pkgtup, notice))
+ else:
+ ret.append((pkgtup, notice))
+ notices.add(notice)
+ for pkgtup, notice in other_arch_list:
+ if notice not in notices:
+ ret.append((pkgtup, notice))
ret.sort(cmp=_rpm_tup_vercmp, key=lambda x: x[0], reverse=True)
return ret
diff -up yum-3.4.3/yum/update_md.py.old yum-3.4.3/yum/update_md.py
--- yum-3.4.3/yum/update_md.py.old 2015-05-28 19:23:35.589691937 +0200
+++ yum-3.4.3/yum/update_md.py 2015-05-28 19:24:05.971806965 +0200
@@ -33,6 +33,7 @@ import Errors
import logginglevels
import rpmUtils.miscutils
+from rpmUtils.arch import ArchStorage
def safe_iterparse(filename, logger=None):

84
SOURCES/BZ-1194915-add-logging-for-bad-notice-dupes.patch

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
diff -up yum-3.4.3/yum/update_md.py.org yum-3.4.3/yum/update_md.py
--- yum-3.4.3/yum/update_md.py.org 2017-01-24 18:55:03.529842775 +0100
+++ yum-3.4.3/yum/update_md.py 2017-01-24 18:55:57.213511475 +0100
@@ -58,7 +58,7 @@ class UpdateNotice(object):
A single update notice (for instance, a security fix).
"""
- def __init__(self, elem=None):
+ def __init__(self, elem=None, repoid=None, vlogger=None):
self._md = {
'from' : '',
'type' : '',
@@ -83,6 +83,9 @@ class UpdateNotice(object):
if elem:
self._parse(elem)
+ self._repoid = repoid
+ self._vlogger = vlogger
+
def __getitem__(self, item):
""" Allows scriptable metadata access (ie: un['update_id']). """
if type(item) is int:
@@ -103,6 +106,24 @@ class UpdateNotice(object):
# Tests to see if it's "the same data", which means that the
# packages can be different (see add_notice).
+ def _rid(un):
+ if hasattr(un, '_repoid') and un._repoid is not None:
+ return un._repoid
+ else:
+ return '<unknown>'
+
+ def _log_failure(data):
+ """Log the mismatched data similarly to conflict markers in git."""
+ if self._vlogger is None:
+ return
+ msg = _('Duplicate of %s differs in some fields:\n')
+ msg %= other._md['update_id']
+ msg += '<<<<<<< %s:%s\n' % (_rid(other), data)
+ msg += '%r\n=======\n%r\n' % (other._md[data], self._md[data])
+ msg += '>>>>>>> %s:%s' % (_rid(self), data)
+ # --verbose mode enables this
+ self._vlogger.log(logginglevels.DEBUG_3, msg)
+
if not other or not hasattr(other, '_md'):
return False
@@ -113,6 +134,7 @@ class UpdateNotice(object):
if data == 'status': # FIXME: See below...
continue
if self._md[data] != other._md[data]:
+ _log_failure(data)
return False
# FIXME: Massive hack, Fedora is really broken and gives status=stable
# and status=testing for updateinfo notices, just depending on which
@@ -120,8 +142,10 @@ class UpdateNotice(object):
data = 'status'
if self._md[data] != other._md[data]:
if self._md[data] not in ('stable', 'testing'):
+ _log_failure(data)
return False
if other._md[data] not in ('stable', 'testing'):
+ _log_failure(data)
return False
# They are both really "stable" ...
self._md[data] = 'stable'
@@ -574,7 +598,7 @@ class UpdateMetadata(object):
for event, elem in safe_iterparse(infile, logger=self._logger):
if elem.tag == 'update':
try:
- un = UpdateNotice(elem)
+ un = UpdateNotice(elem, repoid, self._vlogger)
except UpdateNoticeException, e:
msg = _("An update notice%s is broken, skipping.") % _rid(repoid)
if self._vlogger:
@@ -587,6 +611,8 @@ class UpdateMetadata(object):
msg = _("Update notice %s%s is broken, or a bad duplicate, skipping.") % (un['update_id'], _rid(repoid))
if not have_dup:
msg += _('\nYou should report this problem to the owner of the %srepository.') % _rid(repoid, "%s ")
+ msg += _('\nIf you are the owner, consider re-running the same command with --verbose to see the '
+ 'exact data that caused the conflict.')
have_dup = True
if self._vlogger:
self._vlogger.warn("%s", msg)

33
SOURCES/BZ-1195745-failed-repo-message.patch

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
commit d83aab7e518f77a0de1e938fc4a7e7c4c55f1a17
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri May 6 14:47:55 2016 +0200

Recommend --disablerepo and subscription-manager when a repo fails. BZ 1195745

diff --git a/yummain.py b/yummain.py
index 32680a8..b1666a2 100755
--- a/yummain.py
+++ b/yummain.py
@@ -85,13 +85,18 @@ def main(args):
distribution release than is supported by the repository (and the
packages for the previous distribution release still work).
- 3. Disable the repository, so yum won't use it by default. Yum will then
- just ignore the repository until you permanently enable it again or use
- --enablerepo for temporary usage:
+ 3. Run the command with the repository temporarily disabled
+ yum --disablerepo=%(repoid)s ...
+
+ 4. Disable the repository permanently, so yum won't use it by default. Yum
+ will then just ignore the repository until you permanently enable it
+ again or use --enablerepo for temporary usage:
yum-config-manager --disable %(repoid)s
+ or
+ subscription-manager repos --disable=%(repoid)s
- 4. Configure the failing repository to be skipped, if it is unavailable.
+ 5. Configure the failing repository to be skipped, if it is unavailable.
Note that yum will try to contact the repo. when it runs most commands,
so will have to try and fail each time (and thus. yum will be be much
slower). If it is a very temporary problem though, this is often a nice

67
SOURCES/BZ-1199976-kbase-articles.patch

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
diff --git a/output.py b/output.py
index 091b58e..b14f129 100755
--- a/output.py
+++ b/output.py
@@ -447,6 +447,8 @@ class YumOutput:
self.term = YumTerm()
self._last_interrupt = None
+ self.reported_error_msgs = {k: False for (k, v) in ERRORS_TO_KBASE_ARTICLES.iteritems()}
+
def printtime(self):
"""Return a string representing the current time in the form::
@@ -471,8 +473,22 @@ class YumOutput:
"""
self.logger.error('%s: %s', errobj.url, errobj.exception)
self.logger.error(_('Trying other mirror.'))
+ self.suggestKBaseArticle(errobj)
raise errobj.exception
+ def suggestKBaseArticle(self, errobj):
+ errcode = None
+ if hasattr(errobj.exception, 'code') and errobj.exception.code in ERRORS_TO_KBASE_ARTICLES:
+ errcode = errobj.exception.code
+ elif hasattr(errobj.exception, 'errno') and errobj.exception.errno in ERRORS_TO_KBASE_ARTICLES:
+ errcode = errobj.exception.errno
+ if not errcode:
+ return
+
+ if not self.reported_error_msgs[errcode]:
+ self.logger.error(ERRORS_TO_KBASE_ARTICLES[errcode])
+ self.reported_error_msgs[errcode] = True
+
def simpleProgressBar(self, current, total, name=None):
"""Output the current status to the terminal using a simple
diff --git a/yum/constants.py b/yum/constants.py
index 5c728d4..02b2527 100644
--- a/yum/constants.py
+++ b/yum/constants.py
@@ -120,3 +120,25 @@ REPO_PROBLEM_METADATA=2
REPO_PROBLEM_COMPS=3
REPO_PROBLEM_OTHER=4
REPO_PROBLEM_PACKAGE=5
+
+
+ERRORS_TO_KBASE_ARTICLES = {
+ 404: """To address this issue please refer to the below knowledge base article
+
+https://access.redhat.com/articles/1320623
+
+If above article doesn't help to resolve this issue please open a ticket with Red Hat Support.
+""",
+ 403: """To address this issue please refer to the below knowledge base article
+
+https://access.redhat.com/solutions/69319
+
+If above article doesn't help to resolve this issue please open a ticket with Red Hat Support.
+""",
+ 60: """It was impossible to connect to the Red Hat servers.
+This could mean a connectivity issue in your environment, such as the requirement to configure a proxy,
+or a transparent proxy that tampers with TLS security, or an incorrect system clock.
+Please collect information about the specific failure that occurs in your environment,
+using the instructions in: https://access.redhat.com/solutions/1527033 and open a ticket with Red Hat Support.
+"""
+}
\ No newline at end of file

42
SOURCES/BZ-1202680-handle-non-ascii-email.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
commit 4e1de20b61ae3227d9fc973193a60cf7997e8606
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Fri Feb 19 11:05:23 2016 +0100

yum-cron: don't crash with non-ascii email. BZ 1202680
Previously, we constructed our MIMEText object with the default us-ascii
charset, which caused it to encode the unicode string (self.output) with
the us-ascii codec. This worked fine as long as the string contained
ascii-only chars. However, if yum-cron was run with a language which
makes use of non-ascii chars, this would fail and MIMEText would crash.
To fix that, we need to tell MIMEText to encode the message with utf-8
instead. However, that also causes the message to be transfer-encoded
to base64 which is heavier and uglier, so let's limit that to non-ascii
email only.

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 039f537..ccba690 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -223,8 +223,18 @@ class EmailEmitter(UpdateEmitter):
# Don't send empty emails
if not self.output:
return
- # Build up the email to be sent
- msg = MIMEText(''.join(self.output))
+ # Build up the email to be sent. Encode it with us-ascii instead of
+ # utf-8 if possible. This ensures the email package will not
+ # transfer-encode it to base64 in such a case (it decides based on the
+ # charset passed to the MIMEText constructor).
+ output = ''.join(self.output)
+ try:
+ output.encode('us-ascii')
+ except UnicodeEncodeError:
+ charset = 'utf-8'
+ else:
+ charset = 'us-ascii'
+ msg = MIMEText(output, 'plain', charset)
msg['Subject'] = self.subject
msg['From'] = self.opts.email_from
msg['To'] = ",".join(self.opts.email_to)

60
SOURCES/BZ-1208803-autosavets.patch

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
commit 8d5248c4ab3e8efab00537da8f35a77b86f3c333
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri May 6 11:30:56 2016 +0200

Add autosavets option allowing to avoid autosaving transactions. BZ 1208803

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index efc6765..4d53c8e 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -897,6 +897,12 @@ Note that if loadts_ignorerpm is True, this option does nothing.
Boolean (1, 0, True, False, yes, no) Defaults to False
.IP
+\fBautosavets\fR
+Should yum automatically save a transaction to a file when the transaction is
+solved but not run.
+Boolean (1, 0, True, False, yes, no) Defaults to True
+
+.IP
\fBfssnap_automatic_pre\fR
Should yum try to automatically create a snapshot before it runs a transaction.
Boolean (1, 0, True, False, yes, no) Defaults to False
diff --git a/yum/__init__.py b/yum/__init__.py
index c896fff..764e97d 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1355,7 +1355,8 @@ much more problems).
self._depsolving_failed = False
if rescode == 2:
- self.save_ts(auto=True)
+ if self.conf.autosavets:
+ self.save_ts(auto=True)
# Make sure we don't fail in rpm if we're installing a package that is
# allowed multiple installs but has a newer version already installed.
diff --git a/yum/config.py b/yum/config.py
index 84be564..cae914d 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -893,6 +893,7 @@ class YumConf(StartupConf):
loadts_ignoremissing = BoolOption(False)
loadts_ignorerpm = BoolOption(False)
loadts_ignorenewrpm = BoolOption(False)
+ autosavets = BoolOption(True)
clean_requirements_on_remove = BoolOption(False)
diff -up yum-3.4.3/test/testbase.py.old yum-3.4.3/test/testbase.py
--- yum-3.4.3/test/testbase.py.old 2016-05-10 16:58:02.812286775 +0200
+++ yum-3.4.3/test/testbase.py 2016-05-10 16:58:43.590544423 +0200
@@ -69,6 +69,7 @@ class FakeConf(object):
self.diskspacecheck = True
self.depsolve_loop_limit = 10
self.override_install_langs = ''
+ self.autosavets = True
class FakeSack:
""" Fake PackageSack to use with FakeRepository"""

74
SOURCES/BZ-1211384-yum-grouplist-headers.patch

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
diff -up yum-3.4.3/cli.py.old yum-3.4.3/cli.py
--- yum-3.4.3/cli.py.old 2015-05-28 18:04:17.237676571 +0200
+++ yum-3.4.3/cli.py 2015-05-28 18:05:27.644943137 +0200
@@ -1807,22 +1807,22 @@ class YumBaseCli(yum.YumBase, output.Yum
msg += ' [%s]' % group.langonly
self.verbose_logger.info('%s', msg)
- _out_grp(_('Installed environment groups:'), ievgrps)
- _out_grp(_('Available environment groups:'), evgrps)
+ _out_grp(_('Installed Environment Groups:'), ievgrps)
+ _out_grp(_('Available Environment Groups:'), evgrps)
groups = []
for group in installed:
if group.langonly: continue
if not wts['pkg']: continue
groups.append(group)
- _out_grp(_('Installed groups:'), groups)
+ _out_grp(_('Installed Groups:'), groups)
groups = []
for group in installed:
if not group.langonly: continue
if not wts['lang']: continue
groups.append(group)
- _out_grp(_('Installed language groups:'), groups)
+ _out_grp(_('Installed Language Groups:'), groups)
groups = []
for group in available:
@@ -1836,7 +1836,7 @@ class YumBaseCli(yum.YumBase, output.Yum
if not group.langonly: continue
if not wts['lang']: continue
groups.append(group)
- _out_grp(_('Available language groups:'), groups)
+ _out_grp(_('Available Language Groups:'), groups)
if not done:
self.logger.error(_('Warning: no environments/groups match: %s'),
diff -up yum-3.4.3/po/yum.pot.old yum-3.4.3/po/yum.pot
--- yum-3.4.3/po/yum.pot.old 2015-05-28 18:05:37.610980869 +0200
+++ yum-3.4.3/po/yum.pot 2015-05-28 18:06:23.557154824 +0200
@@ -398,11 +398,11 @@ msgid "Cleaning up plugins"
msgstr ""
#: ../cli.py:1732
-msgid "Installed environment groups:"
+msgid "Installed Environment Groups:"
msgstr ""
#: ../cli.py:1733
-msgid "Available environment groups:"
+msgid "Available Environment Groups:"
msgstr ""
#: ../cli.py:1740
@@ -410,7 +410,7 @@ msgid "Installed groups:"
msgstr ""
#: ../cli.py:1747
-msgid "Installed language groups:"
+msgid "Installed Language Groups:"
msgstr ""
#: ../cli.py:1754
@@ -418,7 +418,7 @@ msgid "Available Groups:"
msgstr ""
#: ../cli.py:1761
-msgid "Available language groups:"
+msgid "Available Language Groups:"
msgstr ""
#: ../cli.py:1764

19
SOURCES/BZ-1212506-running-kernel-epoch.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
commit fefb6a732e0c15c73300858c3fa7d7e89e79d18f
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 11 10:52:49 2015 +0100

Make sure epoch is a string while checking for running kernel. BZ#1200159

diff --git a/yum/misc.py b/yum/misc.py
index 6850ae2..f72f028 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -818,6 +818,8 @@ def get_running_kernel_pkgtup(ts):
e = h['epoch']
if h['epoch'] is None:
e = '0'
+ else:
+ e = str(e)
return (h['name'], h['arch'], e, h['version'], h['release'])
return (None, None, None, None, None)

57
SOURCES/BZ-1212514-not-enough-space.patch

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
commit 7b125d415195713596c798e8ac79e4812873d948
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue Dec 9 10:27:40 2014 +0100

Expect KB as well as MB in disk requirements message from rpm. BZ 1051931

diff --git a/cli.py b/cli.py
index b7f5b5a..f04fe63 100755
--- a/cli.py
+++ b/cli.py
@@ -498,13 +498,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
"""
summary = ''
# do disk space report first
- p = re.compile('needs (\d+)MB on the (\S+) filesystem')
+ p = re.compile('needs (\d+)(K|M)B on the (\S+) filesystem')
disk = {}
for m in p.finditer(errstring):
- if m.group(2) not in disk:
- disk[m.group(2)] = int(m.group(1))
- if disk[m.group(2)] < int(m.group(1)):
- disk[m.group(2)] = int(m.group(1))
+ size_in_mb = int(m.group(1)) if m.group(2) == 'M' else round(int(m.group(1))/1024.0, 3)
+ if m.group(3) not in disk:
+ disk[m.group(3)] = size_in_mb
+ if disk[m.group(3)] < size_in_mb:
+ disk[m.group(3)] = size_in_mb
if disk:
summary += _('Disk Requirements:\n')
commit 6ea8a6cf572efa7d7601dfc8535f5cc3cd80c3bd
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue Mar 17 11:19:10 2015 +0100

Fix rounding issue in required disk space message.

diff --git a/cli.py b/cli.py
index cefc67e..9766f89 100755
--- a/cli.py
+++ b/cli.py
@@ -25,6 +25,7 @@ import sys
import time
import random
import logging
+import math
from optparse import OptionParser,OptionGroup,SUPPRESS_HELP
import rpm
@@ -501,7 +502,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
p = re.compile('needs (\d+)(K|M)B on the (\S+) filesystem')
disk = {}
for m in p.finditer(errstring):
- size_in_mb = int(m.group(1)) if m.group(2) == 'M' else round(int(m.group(1))/1024.0, 3)
+ size_in_mb = int(m.group(1)) if m.group(2) == 'M' else math.ceil(int(m.group(1))/1024.0)
if m.group(3) not in disk:
disk[m.group(3)] = size_in_mb
if disk[m.group(3)] < size_in_mb:

113
SOURCES/BZ-1212519-exclude-installed.patch

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
commit d875b67997356e7e1b4509607fec81ca8220c597
Author: James Antill <james@and.org>
Date: Tue Mar 3 01:54:02 2015 -0500

Add query_install_excludes conf./docs and use it for list/info/search/provides.

diff --git a/cli.py b/cli.py
index f04fe63..cefc67e 100755
--- a/cli.py
+++ b/cli.py
@@ -2299,7 +2299,8 @@ class YumOptionParser(OptionParser):
self.base.conf.disable_excludes = self._splitArg(opts.disableexcludes)
self.base.conf.disable_includes = self._splitArg(opts.disableincludes)
- for exclude in self._splitArg(opts.exclude):
+ self.base.cmdline_excludes = self._splitArg(opts.exclude)
+ for exclude in self.base.cmdline_excludes:
try:
excludelist = self.base.conf.exclude
excludelist.append(exclude)
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index e0f4c8b..62aa78e 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -156,10 +156,20 @@ This is commonly used so a package isn't upgraded or installed accidentally, but
can be used to remove packages in any way that "yum list" will show packages.
Shell globs using wildcards (eg. * and ?) are allowed.
-Can be disabled using --disableexcludes.
+Can be disabled using disable_excludes or --disableexcludes.
Command-line option: \fB\-x\fP
.IP
+\fBdisable_excludes\fR
+A way to permanently set the --disableexcludes command line option.
+
+.IP
+\fBquery_install_excludes\fR
+This applies the command line exclude option (only, not the configuration
+exclude above) to installed packages being shown in some query commands
+(currently: list/info/search/provides).
+
+.IP
\fBinstallonlypkgs \fR
List of package provides that should only ever be installed, never updated.
Kernels in particular fall into this category. Defaults to kernel,
diff --git a/output.py b/output.py
index 2787d86..091b58e 100755
--- a/output.py
+++ b/output.py
@@ -1330,6 +1330,13 @@ class YumOutput:
:param verbose: whether to output extra verbose information
:param highlight: highlighting options for the highlighted matches
"""
+ if (po.repo.id == "installed" and
+ self.conf.query_install_excludes and self.cmdline_excludes):
+ # Very similar to _cmdline_exclude from yumcommands
+ e,m,u = yum.packages.parsePackages([po], self.cmdline_excludes)
+ if e or m:
+ return
+
if self.conf.showdupesfromrepos:
msg = '%s : ' % po
else:
diff --git a/yum/config.py b/yum/config.py
index 02061ba..efe7be9 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -821,6 +821,7 @@ class YumConf(StartupConf):
# XXX rpm_check_debug is unused, left around for API compatibility for now
rpm_check_debug = BoolOption(True)
disable_excludes = ListOption()
+ query_install_excludes = BoolOption(True)
skip_broken = BoolOption(False)
# Note that "instant" is the old behaviour, but group:primary is very
# similar but better :).
diff --git a/yumcommands.py b/yumcommands.py
index e77d209..6fa11fa 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -41,6 +41,7 @@ import errno
import yum.config
from yum import updateinfo
+from yum.packages import parsePackages
def _err_mini_usage(base, basecmd):
if basecmd not in base.yum_cli_commands:
@@ -584,6 +585,14 @@ def _list_cmd_calc_columns(base, ypl):
columns = base.calcColumns(data, remainder_column=1)
return (-columns[0], -columns[1], -columns[2])
+def _cmdline_exclude(pkgs, cmdline_excludes):
+ """ Do an extra exclude for installed packages that match the cmd line. """
+ if not cmdline_excludes:
+ return pkgs
+ e,m,u = parsePackages(pkgs, cmdline_excludes)
+ excluded = set(e + m)
+ return [po for po in pkgs if po not in excluded]
+
class InfoCommand(YumCommand):
"""A class containing methods needed by the cli to execute the
info command.
@@ -682,6 +691,9 @@ class InfoCommand(YumCommand):
clin = base.conf.color_list_installed_newer
clir = base.conf.color_list_installed_reinstall
clie = base.conf.color_list_installed_extra
+ if base.conf.query_install_excludes:
+ ypl.installed = _cmdline_exclude(ypl.installed,
+ base.cmdline_excludes)
rip = base.listPkgs(ypl.installed, _('Installed Packages'), basecmd,
highlight_na=update_pkgs, columns=columns,
highlight_modes={'>' : clio, '<' : clin,

35
SOURCES/BZ-1233152-pvm-api-lv_attr.patch

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
commit 1ba900a1c6a0a6d4dc3c2fd7a5de3027ecb3a153
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Jul 1 16:17:20 2015 +0200

Fix lvm API calls. Patch by Marek Marusic. BZ#1233152

diff --git a/yum/fssnapshots.py b/yum/fssnapshots.py
index 9af252d..a07271d 100755
--- a/yum/fssnapshots.py
+++ b/yum/fssnapshots.py
@@ -25,21 +25,21 @@ except:
def _is_origin(lv):
- snap = lv.getProperty("lv_attr")
+ snap = lv.getAttr()
# snap=(<value>, <is settable>)
if not snap[0]: # Broken??
return None
return snap[0][0] in ('o', 'O')
def _is_snap(lv):
- snap = lv.getProperty("lv_attr")
+ snap = lv.getAttr()
# snap=(<value>, <is settable>)
if not snap[0]: # Broken??
return None
return snap[0][0] in ('s', 'S')
def _is_virt(lv):
- snap = lv.getProperty("lv_attr")
+ snap = lv.getAttr()
# snap=(<value>, <is settable>)
if not snap[0]: # Broken??
return None

155
SOURCES/BZ-1234967-handle-invalid-yumdb.patch

@ -0,0 +1,155 @@ @@ -0,0 +1,155 @@
commit f5c953e2b8c49187f8e874a53f1bb6ed89e4d810
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Tue Feb 16 13:42:20 2016 +0100

Allow for validating attributes read from yumdb
Make sure we don't expose corrupted attributes read from the yumdb to
the consumers. There's at least one report of such a corruption: BZ
1234967. Instead, make requesting a malformed yumdb attribute
equivalent to requesting a non-existent one -- which is a valid
scenario, already handled by the consumers.
Note that the actual validator function that fixes the above bug will be
committed separately.

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 229e1a1..270ade9 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -1755,6 +1755,9 @@ class RPMDBAdditionalDataPackage(object):
'group_member',
'command_line'])
+ # Validate these attributes when they are read from a file
+ _validators = {}
+
def __init__(self, conf, pkgdir, yumdb_cache=None):
self._conf = conf
self._mydir = pkgdir
@@ -1903,6 +1906,15 @@ class RPMDBAdditionalDataPackage(object):
fo.close()
del fo
+ # Validate the attribute we just read from the file. Some attributes
+ # may require being in a specific format and we can't guarantee the
+ # file has not been tampered with outside of yum.
+ if attr in self._validators:
+ valid = self._validators[attr]
+ if not valid(value):
+ raise AttributeError, \
+ "Invalid value of attribute %s on %s" % (attr, self)
+
if info.st_nlink > 1 and self._yumdb_cache is not None:
self._yumdb_cache[key] = value
self._auto_cache(attr, value, fn, info)
commit 6972a28059790177ab95e0bce92311aa882ae465
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Tue Feb 16 13:53:04 2016 +0100

Don't crash on invalid from_repo in yumdb. BZ 1234967
Implement a yumdb validator function for the from_repo attribute. This
prevents yum from crashing if an implicit conversion to unicode takes
place somewhere and the attribute contains non-ascii chars due to some
yumdb corruption.
Reproducers:
$ yum install foo
$ yumdb set from_repo <non-ascii-chars> foo
$ yum list foo # crash
$ yum --disablerepo=<repo-with-foo> reinstall foo # crash
$ yum --verbose version installed # crash

diff --git a/yum/__init__.py b/yum/__init__.py
index 84bea3e..1f6ce16 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -95,7 +95,6 @@ from yum.rpmtrans import RPMTransaction,SimpleCliCallBack
from yum.i18n import to_unicode, to_str, exception2msg
from yum.drpm import DeltaInfo, DeltaPackage
-import string
import StringIO
from weakref import proxy as weakref
@@ -476,17 +475,7 @@ class YumBase(depsolve.Depsolve):
continue
# Check the repo.id against the valid chars
- bad = None
- for byte in section:
- if byte in string.ascii_letters:
- continue
- if byte in string.digits:
- continue
- if byte in "-_.:":
- continue
-
- bad = byte
- break
+ bad = misc.validate_repoid(section)
if bad:
self.logger.warning("Bad id for repo: %s, byte = %s %d" %
diff --git a/yum/misc.py b/yum/misc.py
index f72f028..345934b 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -24,6 +24,7 @@ import bz2
import gzip
import shutil
import urllib
+import string
_available_compression = ['gz', 'bz2']
try:
import lzma
@@ -1248,3 +1249,12 @@ def filter_pkgs_repoid(pkgs, repoid):
continue
ret.append(pkg)
return ret
+
+def validate_repoid(repoid):
+ """Return the first invalid char found in the repoid, or None."""
+ allowed_chars = string.ascii_letters + string.digits + '-_.:'
+ for char in repoid:
+ if char not in allowed_chars:
+ return char
+ else:
+ return None
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 270ade9..11814f1 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -1756,7 +1756,10 @@ class RPMDBAdditionalDataPackage(object):
'command_line'])
# Validate these attributes when they are read from a file
- _validators = {}
+ _validators = {
+ # Fixes BZ 1234967
+ 'from_repo': lambda repoid: misc.validate_repoid(repoid) is None,
+ }
def __init__(self, conf, pkgdir, yumdb_cache=None):
self._conf = conf
commit c02805ed3b23f97843931e0784d2823b8024e441
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Tue Feb 16 17:20:26 2016 +0100

docs: mention special case for unknown from_repo

diff --git a/docs/yum.8 b/docs/yum.8
index e428148..eb52fb7 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -964,6 +964,8 @@ The format of the output of yum list is:
name.arch [epoch:]version-release repo or @installed-from-repo
+Note that if the repo cannot be determined, "installed" is printed instead.
+
.IP "\fByum list [all | glob_exp1] [glob_exp2] [\&.\&.\&.]\fP"
List all available and installed packages\&.
.IP "\fByum list available [glob_exp1] [\&.\&.\&.]\fP"

19
SOURCES/BZ-1235623-new-provides-realpath-file-search.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
diff -up yum-3.4.3/yum/depsolve.py.old yum-3.4.3/yum/depsolve.py
--- yum-3.4.3/yum/depsolve.py.old 2016-03-21 15:27:30.107670469 +0100
+++ yum-3.4.3/yum/depsolve.py 2016-03-21 15:32:38.931701401 +0100
@@ -1271,7 +1271,14 @@ class Depsolve(object):
nprov = self.tsInfo.getNewProvides(filename)
if nprov:
iFP.setdefault(filename, []).extend([po.pkgtup for po in nprov])
- continue
+ continue
+
+ if filename != os.path.realpath(filename):
+ realpath = os.path.realpath(filename)
+ nprov = self.tsInfo.getNewProvides(realpath)
+ if nprov:
+ iFP.setdefault(realpath, []).extend([po.pkgtup for po in nprov])
+ continue
for pkgtup in reverselookup[filename]:
po = self.tsInfo.getMembersWithState(pkgtup, TS_INSTALL_STATES)

25
SOURCES/BZ-1244119-fssnapshot-automatic-percentage-manpage.patch

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
commit 7db4c7826a538e0a3a59f1f5d6fca26de7895204
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Jul 30 15:20:27 2015 +0200

Fix fssnap_automatic_devices and fssnap_automatic_percentage in yum.conf manpage

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 22701e0..5993b57 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -894,12 +894,12 @@ How many old snapshots should yum keep when trying to automatically create a
new snapshot. Setting to 0 disables this feature. Default is '1'.
.IP
-\fBfssnap_automatic_percentage\fR
+\fBfssnap_percentage\fR
The size of new snaphosts, expressed as a percentage of the old origin device.
Any number between 1 and 100. Default is '100'.
.IP
-\fBfssnap_automatic_devices\fR
+\fBfssnap_devices\fR
The origin LVM devices to use for snapshots. Wildcards and negation are allowed,
first match (positive or negative) wins.
Default is: !*/swap !*/lv_swap glob:/etc/yum/fssnap.d/*.conf

48
SOURCES/BZ-1259837-igroups-empty-lines.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
diff -up yum-3.4.3/yum/igroups.py.old yum-3.4.3/yum/igroups.py
--- yum-3.4.3/yum/igroups.py.old 2015-09-09 16:18:23.494390878 +0200
+++ yum-3.4.3/yum/igroups.py 2015-09-09 17:10:33.451517354 +0200
@@ -43,6 +43,12 @@ def _makedirs_no_umask(*args):
return ret
+def _read_str(fo):
+ for s in fo:
+ if s[:-1]:
+ return s[:-1]
+ return ''
+
class InstalledGroup(object):
def __init__(self, gid):
self.gid = gid
@@ -107,11 +113,11 @@ class InstalledGroups(object):
if not os.access(self.filename, os.R_OK):
return
- def _read_str(fo):
- return fo.readline()[:-1]
-
fo = open(self.filename)
- ver = int(_read_str(fo))
+ try:
+ ver = int(_read_str(fo))
+ except ValueError:
+ return
if ver != 1:
return
@@ -132,11 +138,11 @@ class InstalledGroups(object):
if not os.access(self.grp_filename, os.R_OK):
return
- def _read_str(fo):
- return fo.readline()[:-1]
-
fo = open(self.grp_filename)
- ver = int(_read_str(fo))
+ try:
+ ver = int(_read_str(fo))
+ except ValueError:
+ return
if ver != 1:
return

146
SOURCES/BZ-1267234-groupinstall-fail-on-non-existent.patch

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
commit 7e7f374c1ac6984fc50726dd649c4f4c2f56266c
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Jan 29 12:08:30 2014 -0500

Make 'yum install @group' give an error when trying to install a
non-existent group.

diff --git a/cli.py b/cli.py
index c8884ae..eed63a2 100755
--- a/cli.py
+++ b/cli.py
@@ -964,6 +964,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
else:
assert basecmd == 'install', basecmd
txmbrs = self.install(pattern=arg)
+ except yum.Errors.GroupInstallError, e:
+ self.verbose_logger.log(yum.logginglevels.INFO_2, e)
except yum.Errors.InstallError:
self.verbose_logger.log(yum.logginglevels.INFO_2,
_('No package %s%s%s available.'),
@@ -1922,6 +1924,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
for igrp in self.igroups.groups:
pkgs_used.extend(self._at_groupupgrade('@' + igrp))
+ done = False
for group_string in grouplist:
grp_grp = True
@@ -1966,11 +1969,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
if not group_matched:
self.logger.error(_('Warning: group %s does not exist.'), group_string)
continue
+ done = True
if not pkgs_used:
if self.conf.group_command == 'objects':
self.logger.critical(_("Maybe run: yum groups mark install (see man yum)"))
- return 0, [_('No packages in any requested group available to install or update')]
+ exit_status = 1
+ if upgrade:
+ # upgrades don't fail
+ exit_status = 0
+ if done:
+ # at least one group_string was a valid group
+ exit_status = 0
+ return exit_status, [_('No packages in any requested group available to install or update')]
else:
return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)]
diff --git a/yum/Errors.py b/yum/Errors.py
index 70de539..2c2f022 100644
--- a/yum/Errors.py
+++ b/yum/Errors.py
@@ -105,6 +105,9 @@ class GroupsError(YumBaseError):
class InstallError(YumBaseError):
pass
+class GroupInstallError(InstallError):
+ pass
+
class UpdateError(YumBaseError):
pass
diff --git a/yum/__init__.py b/yum/__init__.py
index bbd20f3..b40c7e4 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1158,8 +1158,7 @@ class YumBase(depsolve.Depsolve):
if hasattr(self, 'term'):
hibeg, hiend = self.term.MODE['bold'], self.term.MODE['normal']
- func(_("The program %s%s%s is found in the yum-utils package.") %
- (hibeg, prog, hiend))
+ func(_("The program %s is found in the yum-utils package.") % self._try_bold(prog))
def buildTransaction(self, unfinished_transactions_check=True):
"""Go through the packages in the transaction set, find them
@@ -4451,6 +4450,12 @@ much more problems).
if node == slow:
return None
+ def _try_bold(self, string_):
+ """Attempt to make the string look bold in terminal."""
+ if hasattr(self, 'term'):
+ return '%s%s%s' % (self.term.MODE['bold'], string_, self.term.MODE['normal'])
+ return string_
+
def _at_groupinstall(self, pattern, upgrade=False):
" Do groupinstall via. leading @ on the cmd line, for install."
assert pattern[0] == '@'
@@ -4464,42 +4469,31 @@ much more problems).
self.logger.warning(e)
return tx_return
+ found = False
if group_string and group_string[0] == '^':
group_string = group_string[1:]
# Actually dealing with "environment groups".
- found = False
for env_grp in comps.return_environments(group_string):
found = True
- try:
- txmbrs = self.selectEnvironment(env_grp.environmentid,
- upgrade=upgrade)
- tx_return.extend(txmbrs)
- except yum.Errors.GroupsError:
- assert False, "Checked in for loop."
- continue
- if not found:
- self.logger.error(_('Warning: Environment group %s does not exist.'),
- group_string)
- return tx_return
-
- found = False
- for group in comps.return_groups(group_string):
- found = True
- try:
+ txmbrs = self.selectEnvironment(env_grp.environmentid,
+ upgrade=upgrade)
+ tx_return.extend(txmbrs)
+ else:
+ for group in comps.return_groups(group_string):
+ found = True
txmbrs = self.selectGroup(group.groupid, upgrade=upgrade)
tx_return.extend(txmbrs)
- except yum.Errors.GroupsError:
- assert False, "Checked in for loop."
- continue
if not found:
- self.logger.error(_('Warning: Package group %s does not exist.'),
- group_string)
-
+ raise Errors.GroupInstallError, _('Group %s does not exist.') % self._try_bold(group_string)
return tx_return
def _at_groupupgrade(self, pattern):
" Do group upgrade via. leading @ on the cmd line, for update."
- return self._at_groupinstall(pattern, upgrade=True)
+ try:
+ return self._at_groupinstall(pattern, upgrade=True)
+ except Errors.GroupInstallError, e:
+ self.logger.warning(_('Warning: %s'), e)
+ return []
def _at_groupremove(self, pattern):
" Do groupremove via. leading @ on the cmd line, for remove."

22
SOURCES/BZ-1267897-exclude-dups-from-security-updates.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
diff -up yum-3.4.3/yum/updateinfo.py.old yum-3.4.3/yum/updateinfo.py
--- yum-3.4.3/yum/updateinfo.py.old 2016-03-22 12:12:51.413858074 +0100
+++ yum-3.4.3/yum/updateinfo.py 2016-03-22 12:14:56.392798309 +0100
@@ -411,13 +411,17 @@ def exclude_updates(base, filters=None):
name2tup = _get_name2oldpkgtup(base)
cnt = 0
+ pkgs_to_del = []
for pkg in pkgs:
name = pkg.name
if (name not in name2tup or
not _ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
- ysp_del_pkg(pkg)
+ pkgs_to_del.append(pkg.name)
continue
cnt += 1
+ if pkgs_to_del:
+ for p in base.doPackageLists(pkgnarrow='available', patterns=pkgs_to_del, showdups=True).available:
+ ysp_del_pkg(p)
_ysp_chk_used_map(used_map, lambda x: base.verbose_logger.warn("%s", x))

70
SOURCES/BZ-1272058-arches.patch

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
commit 13a1fddf27dd16a70b639630d209c0f16bd5097e
Author: Dennis Gilmore <dennis@ausil.us>
Date: Wed Feb 12 18:12:54 2014 -0500

ppc64le is its own arch treat it as such.
ppc64le is ppc64 little endian, it is a completely incompatable arch
to all other 64 bit power builds and can not be multilibbed with ppc.
While it works okay in the default Fedora setup its because Fedora
patches _ppc64_native_is_best to True as soon as its False you get
unexpected results.
This patch covers things in both setups and makes it clear how it
works.
Signed-off-by: Dennis Gilmore <dennis@ausil.us>

diff --git a/rpmUtils/arch.py b/rpmUtils/arch.py
index 6172b1a..54fa189 100644
--- a/rpmUtils/arch.py
+++ b/rpmUtils/arch.py
@@ -31,7 +31,10 @@ arches = {
"x86_64": "athlon",
"amd64": "x86_64",
"ia32e": "x86_64",
-
+
+ #ppc64le
+ "ppc64le": "noarch",
+
# ppc
"ppc64p7": "ppc64",
"ppc64pseries": "ppc64",
@@ -412,7 +415,7 @@ def getBestArch(myarch=None):
if arch.startswith("sparc64"):
arch = multilibArches[arch][1]
- if arch.startswith("ppc64") and not _ppc64_native_is_best:
+ if arch.startswith("ppc64") and not _ppc64_native_is_best and arch != "ppc64le":
arch = 'ppc'
return arch
@@ -430,6 +433,8 @@ def getBaseArch(myarch=None):
if myarch.startswith("sparc64"):
return "sparc"
+ elif myarch == "ppc64le":
+ return "ppc64le"
elif myarch.startswith("ppc64") and not _ppc64_native_is_best:
return "ppc"
elif myarch.startswith("arm64"):
commit 1a1a33f195a6fb6e8738e48fcb6142c53a539b6d
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue Apr 5 14:54:05 2016 +0200

Add aarch64 to rpmUtils.arch.arches.

diff --git a/rpmUtils/arch.py b/rpmUtils/arch.py
index a3bade5..d63ec25 100644
--- a/rpmUtils/arch.py
+++ b/rpmUtils/arch.py
@@ -80,6 +80,9 @@ arches = {
# arm64
"arm64": "noarch",
+ # aarch64
+ "aarch64": "noarch",
+
# super-h
"sh4a": "sh4",
"sh4": "noarch",

173
SOURCES/BZ-1274211-skip-missing-names.patch

@ -0,0 +1,173 @@ @@ -0,0 +1,173 @@
commit d4ff5427368977f74a8ba7b0be51752023592025
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 16 16:22:34 2016 +0100

Add config options skip_missing_names_on_install and skip_missing_names_on_update. BZ#1274211

diff --git a/cli.py b/cli.py
index fd6e715..54a2e81 100755
--- a/cli.py
+++ b/cli.py
@@ -982,6 +982,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
except:
self.verbose_logger.warning(_('Bad %s argument %s.'),
basecmd, arg)
+ if not self.conf.skip_missing_names_on_install:
+ return 1, [_('Not tolerating missing names on install, stopping.')]
continue
txmbrs = self.install(name=n, arch=a)
elif basecmd == 'install-nevra':
@@ -992,6 +994,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
except:
self.verbose_logger.warning(_('Bad %s argument %s.'),
basecmd, arg)
+ if not self.conf.skip_missing_names_on_install:
+ return 1, [_('Not tolerating missing names on install, stopping.')]
continue
txmbrs = self.install(name=n,
epoch=e, version=v, release=r, arch=a)
@@ -1000,12 +1004,16 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
txmbrs = self.install(pattern=arg)
except yum.Errors.GroupInstallError, e:
self.verbose_logger.log(yum.logginglevels.INFO_2, e)
+ if not self.conf.skip_missing_names_on_install:
+ return 1, [_('Not tolerating missing names on install, stopping.')]
except yum.Errors.InstallError:
self.verbose_logger.log(yum.logginglevels.INFO_2,
_('No package %s%s%s available.'),
self.term.MODE['bold'], arg,
self.term.MODE['normal'])
self._maybeYouMeant(arg)
+ if not self.conf.skip_missing_names_on_install:
+ return 1, [_('Not tolerating missing names on install, stopping.')]
else:
done = True
self._install_upgraded_requires(txmbrs)
@@ -1057,10 +1065,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
self._install_upgraded_requires(txmbrs)
continue
- txmbrs = self.update(pattern=item, update_to=update_to)
+ try:
+ txmbrs = self.update(pattern=item, update_to=update_to)
+ except (yum.Errors.UpdateMissingNameError, yum.Errors.GroupInstallError):
+ self._checkMaybeYouMeant(item)
+ return 1, [_('Not tolerating missing names on update, stopping.')]
+
self._install_upgraded_requires(txmbrs)
if not txmbrs:
self._checkMaybeYouMeant(item)
+ if not self.conf.skip_missing_names_on_update:
+ matches = self.doPackageLists(pkgnarrow='all', patterns=[item], ignore_case=False)
+ if matches.available and not matches.installed:
+ return 1, [_('Not tolerating missing names on update, stopping.')]
if len(self.tsInfo) > oldcount:
change = len(self.tsInfo) - oldcount
diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 116829a..f823c6f 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -945,6 +945,17 @@ Either `0' or `1'. Set this to `0' to disable the checking for writability on
/usr in the installroot (when going into the depsolving stage). Default is `1'
(perform the check).
+.IP
+\fBskip_missing_names_on_install\fR
+If set to False, 'yum install' will fail if it can't find any of the provided
+names (package, group, rpm file). Boolean (1, 0, True, False, yes, no). Defaults to True.
+
+.IP
+\fBskip_missing_names_on_update\fR
+If set to False, 'yum update' will fail if it can't find any of the provided
+names (package, group, rpm file). It will also fail if the provided name is a package
+which is available, but not installed. Boolean (1, 0, True, False, yes, no). Defaults to True.
+
.SH "[repository] OPTIONS"
.LP
The repository section(s) take the following form:
diff --git a/test/testbase.py b/test/testbase.py
index 6d240b0..b303356 100644
--- a/test/testbase.py
+++ b/test/testbase.py
@@ -46,6 +46,8 @@ class FakeConf(object):
self.tsflags = []
self.installonly_limit = 0
self.skip_broken = False
+ self.skip_missing_names_on_install = True
+ self.skip_missing_names_on_update = True
self.disable_excludes = []
self.multilib_policy = 'best'
self.persistdir = '/should-not-exist-bad-test!'
diff --git a/yum/Errors.py b/yum/Errors.py
index f69c061..3f87b0b 100644
--- a/yum/Errors.py
+++ b/yum/Errors.py
@@ -117,6 +117,9 @@ class GroupInstallError(InstallError):
class UpdateError(YumBaseError):
pass
+
+class UpdateMissingNameError(UpdateError):
+ pass
class RemoveError(YumBaseError):
pass
diff --git a/yum/__init__.py b/yum/__init__.py
index 1f6ce16..acaa973 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4581,7 +4581,10 @@ much more problems).
return self._at_groupinstall(pattern, upgrade=True)
except Errors.GroupInstallError, e:
self.logger.warning(_('Warning: %s'), e)
- return []
+ if self.conf.skip_missing_names_on_update:
+ return []
+ else:
+ raise
def _at_groupremove(self, pattern):
" Do groupremove via. leading @ on the cmd line, for remove."
@@ -5185,6 +5188,8 @@ much more problems).
if not availpkgs and not instpkgs:
self.logger.critical(_('No Match for argument: %s') % to_unicode(arg))
+ if not self.conf.skip_missing_names_on_update:
+ raise Errors.UpdateMissingNameError, _('Not tolerating missing names on update, stopping.')
else: # we have kwargs, sort them out.
nevra_dict = self._nevra_kwarg_parse(kwargs)
diff --git a/yum/config.py b/yum/config.py
index 6bd8d24..954700b 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -729,6 +729,8 @@ class StartupConf(BaseConfig):
syslog_facility = Option('LOG_USER')
syslog_device = Option('/dev/log')
persistdir = Option('/var/lib/yum')
+ skip_missing_names_on_install = BoolOption(True)
+ skip_missing_names_on_update = BoolOption(True)
class YumConf(StartupConf):
"""Configuration option definitions for yum.conf's [main] section.
commit be18ab78927522db11cfae5e4f270b073ed1df0b
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 16 16:16:49 2016 +0100

Fix returnPackages() to respect ignore_case.

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 11814f1..0990edd 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -607,6 +607,9 @@ class RPMDBPackageSack(PackageSackBase):
# will pick up any loads :)
pkgs = self.searchNames([pat])
if not pkgs:
+ # We could be given gliBc or mysql
+ if ignore_case:
+ break
# We need to do a big search for 'pkg*'
if misc.re_glob(pat):
break

243
SOURCES/BZ-1278333-yum-shell-support-exit-status.patch

@ -0,0 +1,243 @@ @@ -0,0 +1,243 @@
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2017-11-24 20:52:02.648462776 +0100
+++ yum-3.4.3/docs/yum.conf.5 2017-11-24 20:52:18.483380945 +0100
@@ -1016,6 +1016,15 @@ If set to False, 'yum update' will fail
names (package, group, rpm file). It will also fail if the provided name is a package
which is available, but not installed. Boolean (1, 0, True, False, yes, no). Defaults to True.
+.IP
+\fBshell_exit_status\fR
+Determines the exit status that should be returned by `yum shell' when it
+terminates after reading the `exit' command or EOF.
+Possible values are: 0, ?.
+If ? is set, the exit status is that of the last command executed before `exit'
+(bash-like behavior).
+Defaults to 0.
+
.SH "[repository] OPTIONS"
.LP
The repository section(s) take the following form:
diff -up yum-3.4.3/docs/yum-shell.8.orig yum-3.4.3/docs/yum-shell.8
--- yum-3.4.3/docs/yum-shell.8.orig 2011-06-28 22:27:22.000000000 +0200
+++ yum-3.4.3/docs/yum-shell.8 2017-11-24 20:52:18.483380945 +0100
@@ -31,6 +31,12 @@ information. There are a few additional
reset: reset (zero-out) the transaction
solve: run the dependency solver on the transaction
run: run the transaction
+.IP
+.IP "\fBexit\fP"
+ Causes the shell to exit, setting the exit status as specified by the
+ \fBshell_exit_status\fR option in \fIyum.conf(5)\fR.
+ This command is also triggered when EOF is read (usually the C-d keystroke
+ or end of script).
.PP
.SH "Examples"
diff -up yum-3.4.3/shell.py.orig yum-3.4.3/shell.py
--- yum-3.4.3/shell.py.orig 2017-11-24 20:52:02.580463129 +0100
+++ yum-3.4.3/shell.py 2017-11-24 20:52:18.483380945 +0100
@@ -126,6 +126,7 @@ class YumShell(cmd.Cmd):
:param line: the next line of input
"""
+ self.result = 0
if len(line) > 0 and line.strip()[0] == '#':
pass
else:
@@ -150,7 +151,8 @@ class YumShell(cmd.Cmd):
except Errors.YumBaseError:
pass
else:
- self.base.doCommands()
+ result, _ = self.base.doCommands()
+ self.result = result
def emptyline(self):
"""Do nothing on an empty line of input."""
@@ -211,13 +213,14 @@ class YumShell(cmd.Cmd):
self.base.shellUsage()
self.verbose_logger.info(msg)
+ self.result = 0
def do_EOF(self, line):
"""Exit the shell when EOF is reached.
:param line: unused
"""
- self.resultmsgs = ['Leaving Shell']
+ self.do_exit(line)
return True
def do_quit(self, line):
@@ -225,7 +228,7 @@ class YumShell(cmd.Cmd):
:param line: unused
"""
- self.resultmsgs = ['Leaving Shell']
+ self.do_exit(line)
return True
def do_exit(self, line):
@@ -233,6 +236,9 @@ class YumShell(cmd.Cmd):
:param line: unused
"""
+ # Make sure we don't go onto the next stage in yummain (result == 2)
+ if self.base.conf.shell_exit_status == '0' or self.result == 2:
+ self.result = 0
self.resultmsgs = ['Leaving Shell']
return True
@@ -254,6 +260,7 @@ class YumShell(cmd.Cmd):
:param line: the remainder of the line, containing the name of
a subcommand. If no subcommand is given, run the list subcommand.
"""
+ self.result = 0
(cmd, args, line) = self.parseline(line)
if cmd in ['list', None]:
self.verbose_logger.log(logginglevels.INFO_2,
@@ -267,11 +274,13 @@ class YumShell(cmd.Cmd):
(code, msgs) = self.base.buildTransaction()
except Errors.YumBaseError, e:
self.logger.critical('Error building transaction: %s', e)
+ self.result = 1
return False
if code == 1:
for msg in msgs:
self.logger.critical('Error: %s', msg)
+ self.result = 1
else:
self.verbose_logger.log(logginglevels.INFO_2,
'Success resolving dependencies')
@@ -292,6 +301,7 @@ class YumShell(cmd.Cmd):
value is given, print the current value. If a value is
supplied, set the option to the given value.
"""
+ self.result = 0
(cmd, args, line) = self.parseline(line)
# logs
if cmd in ['debuglevel', 'errorlevel']:
@@ -305,6 +315,7 @@ class YumShell(cmd.Cmd):
val = int(val)
except ValueError:
self.logger.critical('Value %s for %s cannot be made to an int', val, cmd)
+ self.result = 1
return
setattr(self.base.conf, cmd, val)
if cmd == 'debuglevel':
@@ -321,6 +332,7 @@ class YumShell(cmd.Cmd):
value = opts[0]
if value.lower() not in BOOLEAN_STATES:
self.logger.critical('Value %s for %s is not a Boolean', value, cmd)
+ self.result = 1
return False
value = BOOLEAN_STATES[value.lower()]
setattr(self.base.conf, cmd, value)
@@ -363,6 +375,7 @@ class YumShell(cmd.Cmd):
a subcommand and other parameters if required. If no
subcommand is given, run the list subcommand.
"""
+ self.result = 0
(cmd, args, line) = self.parseline(line)
if cmd in ['list', None]:
# Munge things to run the repolist command
@@ -380,7 +393,8 @@ class YumShell(cmd.Cmd):
except Errors.YumBaseError:
pass
else:
- self.base.doCommands()
+ result, _ = self.base.doCommands()
+ self.result = result
elif cmd == 'enable':
repos = self._shlex_split(args)
@@ -392,8 +406,10 @@ class YumShell(cmd.Cmd):
changed = self.base.repos.enableRepo(repo)
except Errors.ConfigError, e:
self.logger.critical(e)
+ self.result = 1
except Errors.RepoError, e:
self.logger.critical(e)
+ self.result = 1
else:
for repo in changed:
@@ -402,6 +418,7 @@ class YumShell(cmd.Cmd):
except Errors.RepoError, e:
self.logger.critical('Disabling Repository')
self.base.repos.disableRepo(repo)
+ self.result = 1
return False
self.base.up = None
@@ -413,8 +430,10 @@ class YumShell(cmd.Cmd):
offrepos = self.base.repos.disableRepo(repo)
except Errors.ConfigError, e:
self.logger.critical(e)
+ self.result = 1
except Errors.RepoError, e:
self.logger.critical(e)
+ self.result = 1
else:
# close the repos, too
@@ -432,36 +451,45 @@ class YumShell(cmd.Cmd):
print cmd
print args
print line
+ self.result = 0
def do_run(self, line):
"""Run the transaction.
:param line: unused
"""
+ self.result = 0
if len(self.base.tsInfo) > 0:
try:
(code, msgs) = self.base.buildTransaction()
if code == 1:
for msg in msgs:
self.logger.critical('Error: %s', msg)
+ self.result = 1
return False
returnval = self.base.doTransaction()
except Errors.YumBaseError, e:
self.logger.critical('Error: %s', e)
+ self.result = 1
except KeyboardInterrupt, e:
self.logger.critical('\n\nExiting on user cancel')
+ self.result = 1
except IOError, e:
if e.errno == 32:
self.logger.critical('\n\nExiting on Broken Pipe')
+ self.result = 1
else:
if returnval not in [0,1,-1]:
self.verbose_logger.info('Transaction encountered a serious error.')
+ self.result = 1
else:
if returnval == 1:
self.verbose_logger.info('There were non-fatal errors in the transaction')
+ self.result = 1
elif returnval == -1:
self.verbose_logger.info("Transaction didn't start")
+ self.result = 1
self.verbose_logger.log(logginglevels.INFO_2,
'Finished Transaction')
self.base.closeRpmDB()
diff -up yum-3.4.3/yum/config.py.orig yum-3.4.3/yum/config.py
--- yum-3.4.3/yum/config.py.orig 2017-11-24 20:52:02.648462776 +0100
+++ yum-3.4.3/yum/config.py 2017-11-24 20:52:18.484380940 +0100
@@ -931,6 +931,8 @@ class YumConf(StartupConf):
usr_w_check = BoolOption(True)
+ shell_exit_status = SelectionOption('0', ('0', '?'))
+
_reposlist = []
def dump(self):

19
SOURCES/BZ-1279483-hidden-groups-manpage.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
commit 4690124107fa99ff18bb77a1f19665edbfedd588
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue Apr 5 15:05:27 2016 +0200

Clarify using 'group list' command for hidden groups in the man page.

diff --git a/docs/yum.8 b/docs/yum.8
index b837f9f..9c09c48 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -283,6 +283,8 @@ default package are installed (when not in group_command=objects mode).
You can pass optional arguments to the list/summary commands: installed,
available, environment, language, packages, hidden and ids (or any of those
prefixed by "no" to turn them off again).
+Note that groups that are available but hidden will not be listed unless
+\'hidden\' keyword is passed to the command.
If you pass the \-v option, to enable verbose mode, then the groupids are
displayed by default (but "yum group list ids" is often easier to read).

143
SOURCES/BZ-1281593-yum-fs-vars.patch

@ -0,0 +1,143 @@ @@ -0,0 +1,143 @@
commit 22271bf34e71bbfc75d0a59354fc0108e004f36c
Author: James Antill <james@and.org>
Date: Mon Jun 9 16:09:32 2014 -0400

Read FS yumvars before yum.conf setup, and reread if installroot changed.

diff --git a/yum/config.py b/yum/config.py
index 6e0ecdc..1b5a11d 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1022,6 +1022,23 @@ class VersionGroupConf(BaseConfig):
pkglist = ListOption()
run_with_packages = BoolOption(False)
+def _read_yumvars(yumvars, root):
+ # Read the FS yumvars
+ try:
+ dir_fsvars = root + "/etc/yum/vars/"
+ fsvars = os.listdir(dir_fsvars)
+ except OSError:
+ fsvars = []
+ for fsvar in fsvars:
+ if os.path.islink(dir_fsvars + fsvar):
+ continue
+ try:
+ val = open(dir_fsvars + fsvar).readline()
+ if val and val[-1] == '\n':
+ val = val[:-1]
+ except (OSError, IOError):
+ continue
+ yumvars[fsvar] = val
def readStartupConfig(configfile, root, releasever=None):
"""Parse Yum's main configuration file and return a
@@ -1044,6 +1061,7 @@ def readStartupConfig(configfile, root, releasever=None):
confpp_obj = ConfigPreProcessor(configfile)
yumvars = _getEnvVar()
+ _read_yumvars(yumvars, yumconf.installroot)
confpp_obj._vars = yumvars
startupconf.yumvars = yumvars
@@ -1102,22 +1120,12 @@ def readMainConfig(startupconf):
ir_path = varReplace(ir_path, yumvars)
setattr(yumconf, option, ir_path)
- # Read the FS yumvars
- try:
- dir_fsvars = yumconf.installroot + "/etc/yum/vars/"
- fsvars = os.listdir(dir_fsvars)
- except OSError:
- fsvars = []
- for fsvar in fsvars:
- if os.path.islink(dir_fsvars + fsvar):
- continue
- try:
- val = open(dir_fsvars + fsvar).readline()
- if val and val[-1] == '\n':
- val = val[:-1]
- except (OSError, IOError):
- continue
- yumvars[fsvar] = val
+ if StartupConf.installroot.default != yumconf.installroot:
+ # Note that this isn't perfect, in that if the initial installroot has
+ # X=Y, and X doesn't exist in the new installroot ... then we'll still
+ # have X afterwards (but if the new installroot has X=Z, that will be
+ # the value after this).
+ _read_yumvars(yumvars, yumconf.installroot)
# These can use the above FS yumvars
for option in ('cachedir', 'logfile', 'persistdir'):
commit 1ccd91f4b195737d6bb1bdfabcbf3714de1d9b85
Author: James Antill <james@and.org>
Date: Mon Jun 16 15:16:25 2014 -0400

Fix merge typo. with FS vars. before yum.conf

diff --git a/yum/config.py b/yum/config.py
index 1b5a11d..8eab5bc 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1061,7 +1061,7 @@ def readStartupConfig(configfile, root, releasever=None):
confpp_obj = ConfigPreProcessor(configfile)
yumvars = _getEnvVar()
- _read_yumvars(yumvars, yumconf.installroot)
+ _read_yumvars(yumvars, startupconf.installroot)
confpp_obj._vars = yumvars
startupconf.yumvars = yumvars
commit 6148c8a10b22763592c141ce9ee6d85dce5816f7
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Thu Apr 21 16:08:19 2016 +0200

Honor FS yumvars over defaults for special vars. BZ 1327561
This fixes up commit 22271bf, which caused FS yumvars like $releasever
to be unintentionally replaced by the default values (unless the
installroot was redefined by yumconf, which caused us to reread them).

diff --git a/yum/config.py b/yum/config.py
index 954700b..2ef5fa4 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1114,12 +1114,12 @@ def readMainConfig(startupconf):
# ' xemacs syntax hack
- # Set up substitution vars
+ # Set up substitution vars but make sure we always prefer FS yumvars
yumvars = startupconf.yumvars
- yumvars['basearch'] = startupconf.basearch
- yumvars['arch'] = startupconf.arch
- yumvars['releasever'] = startupconf.releasever
- yumvars['uuid'] = startupconf.uuid
+ yumvars.setdefault('basearch', startupconf.basearch)
+ yumvars.setdefault('arch', startupconf.arch)
+ yumvars.setdefault('releasever', startupconf.releasever)
+ yumvars.setdefault('uuid', startupconf.uuid)
# Note: We don't setup the FS yumvars here, because we want to be able to
# use the core yumvars in persistdir. Which is the base of FS yumvars.
commit 1897df3c1477afd8f221833120092f35c26f5a9d
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Thu Apr 21 16:23:47 2016 +0200

Cosmetic: remove outdated comment
It was no longer true after commit ade6d16.

diff --git a/yum/config.py b/yum/config.py
index 2ef5fa4..84be564 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -1120,8 +1120,6 @@ def readMainConfig(startupconf):
yumvars.setdefault('arch', startupconf.arch)
yumvars.setdefault('releasever', startupconf.releasever)
yumvars.setdefault('uuid', startupconf.uuid)
- # Note: We don't setup the FS yumvars here, because we want to be able to
- # use the core yumvars in persistdir. Which is the base of FS yumvars.
# Read [main] section
yumconf = YumConf()

83
SOURCES/BZ-1287610-fips-dont-pollute-stderr.patch

@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
diff -up yum-3.4.3/yum/Errors.py.orig yum-3.4.3/yum/Errors.py
--- yum-3.4.3/yum/Errors.py.orig 2017-09-14 18:42:26.740558383 +0200
+++ yum-3.4.3/yum/Errors.py 2017-09-14 18:42:30.371541754 +0200
@@ -99,6 +99,11 @@ class ConfigError(YumBaseError):
class MiscError(YumBaseError):
pass
+class FIPSNonCompliantError(MiscError):
+ def __init__(self, sumtype):
+ MiscError.__init__(
+ self, '%s algorithm is not FIPS compliant' % sumtype)
+
class GroupsError(YumBaseError):
pass
diff -up yum-3.4.3/yum/misc.py.orig yum-3.4.3/yum/misc.py
--- yum-3.4.3/yum/misc.py.orig 2017-09-14 18:42:26.794558135 +0200
+++ yum-3.4.3/yum/misc.py 2017-09-14 18:42:30.372541749 +0200
@@ -58,11 +58,20 @@ except ImportError:
raise ValueError, "Bad checksum type"
# some checksum types might be disabled
+_fips_noncompliant = set()
for ctype in list(_available_checksums):
try:
hashlib.new(ctype)
- except:
- print >> sys.stderr, 'Checksum type %s disabled' % repr(ctype)
+ except Exception as e:
+ # Print an error unless this is due to FIPS mode (in which case it's
+ # not really an error and we don't want to pollute the output
+ # needlessly; if someone actually tries to instantiate a Checksum with
+ # a FIPS non-compliant ctype, we'll raise an explanatory exception
+ # anyway).
+ if isinstance(e, ValueError) and str(e).endswith('disabled for fips'):
+ _fips_noncompliant.add(ctype)
+ else:
+ print >> sys.stderr, 'Checksum type %s disabled' % repr(ctype)
_available_checksums.remove(ctype)
for ctype in 'sha256', 'sha1':
if ctype in _available_checksums:
@@ -71,7 +80,7 @@ for ctype in 'sha256', 'sha1':
else:
raise ImportError, 'broken hashlib'
-from Errors import MiscError
+from Errors import MiscError, FIPSNonCompliantError
# These are API things, so we can't remove them even if they aren't used here.
# pylint: disable-msg=W0611
from i18n import to_utf8, to_unicode
@@ -271,6 +280,8 @@ class Checksums:
sumalgo = hashlib.new(sumtype)
elif ignore_missing:
continue
+ elif sumtype in _fips_noncompliant:
+ raise FIPSNonCompliantError(sumtype)
else:
raise MiscError, 'Error Checksumming, bad checksum type %s' % sumtype
done.add(sumtype)
diff -up yum-3.4.3/yum/yumRepo.py.orig yum-3.4.3/yum/yumRepo.py
--- yum-3.4.3/yum/yumRepo.py.orig 2017-09-14 18:42:26.879557746 +0200
+++ yum-3.4.3/yum/yumRepo.py 2017-09-14 18:43:23.422298802 +0200
@@ -497,7 +497,10 @@ class YumRepository(Repository, config.R
except (Errors.MiscError, EnvironmentError), e:
if checksum_can_fail:
return None
- raise Errors.RepoError, 'Error opening file for checksum: %s' % e
+ msg = 'Error opening file for checksum: %s' % e
+ if isinstance(e, Errors.FIPSNonCompliantError):
+ msg = str(e)
+ raise Errors.RepoError(msg)
def dump(self):
output = '[%s]\n' % self.id
@@ -1799,7 +1802,7 @@ Insufficient space in download directory
except Errors.RepoError, e:
if check_can_fail:
return None
- raise URLGrabError(-3, 'Error performing checksum')
+ raise URLGrabError(-3, 'Error performing checksum: %s' % e)
if l_csum == r_csum:
_xattr_set_chksum(file, r_ctype, l_csum)

32
SOURCES/BZ-1291745-query-install-excludes.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
commit cc08cae08365d473d2ab5b29cd1ab4fedc8d0f75
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Tue Dec 15 15:01:23 2015 +0100

Fix the default value for query_install_excludes config option.

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 0548860..27620b8 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -174,7 +174,7 @@ A way to permanently set the --disableexcludes command line option.
\fBquery_install_excludes\fR
This applies the command line exclude option (only, not the configuration
exclude above) to installed packages being shown in some query commands
-(currently: list/info/search/provides).
+(currently: list/info/search/provides). Default is '0'.
.IP
\fBinstallonlypkgs \fR
diff --git a/yum/config.py b/yum/config.py
index 0dcbc6a..77a1003 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -826,7 +826,7 @@ class YumConf(StartupConf):
# XXX rpm_check_debug is unused, left around for API compatibility for now
rpm_check_debug = BoolOption(True)
disable_excludes = ListOption()
- query_install_excludes = BoolOption(True)
+ query_install_excludes = BoolOption(False)
skip_broken = BoolOption(False)
# Note that "instant" is the old behaviour, but group:primary is very
# similar but better :).

23
SOURCES/BZ-1292087-history-hash-crash.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
commit 8ae3ad9a8bb297c39bc287802b3220e497dfbbcc
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Thu Apr 14 13:36:02 2016 +0200

Make YumHistoryRpmdbProblem objects hashable. BZ 1292087
Let's use rpid for that to ensure we get the same hash value for objects
that compare equal (which is iff their rpid's match, see __cmp__).

diff --git a/yum/history.py b/yum/history.py
index d08837c..f1295de 100644
--- a/yum/history.py
+++ b/yum/history.py
@@ -244,6 +244,9 @@ class YumHistoryRpmdbProblem:
ret = cmp(self.rpid, other.rpid)
return ret
+ def __hash__(self):
+ return hash(self.rpid)
+
def _getProbPkgs(self):
if self._loaded_P is None:
self._loaded_P = sorted(self._history._old_prob_pkgs(self.rpid))

82
SOURCES/BZ-1292150-updateinfo-list-available.patch

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
commit 8ccc79d82bf0894def61cd2643d63e4adf3dcd02
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Dec 16 15:31:15 2015 +0100

Fix 'updateinfo list available' logic and make 'updates' the default

diff --git a/docs/yum.8 b/docs/yum.8
index 99862fa..e428148 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -630,20 +630,19 @@ to your machine (including anything installed, if you supply "all").
.br
.br
-.I \fR "\fB* all\fP"
-Is used to display information about both install and available advisories.
-.br
-.I \fR "\fB* available\fP"
-Is used to display information about just available advisories. This is the
-default.
+.I \fR "\fB* updates\fP"
+Is used to display information about advisories for packages that can be
+updated. This is the default.
.br
.I \fR "\fB* installed\fP"
-Is used to display information about just install advisories.
+Is used to display information only about installed advisories.
.br
-.I \fR "\fB* updates\fP"
-This is mostly the same as "available" but it only shows advisory information
-for packages that can be updated to.
-
+.I \fR "\fB* available\fP"
+Is used to display information about advisories for packages available
+for updating or installation.
+.br
+.I \fR "\fB* all\fP"
+Is used to display information about both installed and available advisories.
.br
They all take as arguments:
diff -up yum-3.4.3/yumcommands.py.old yum-3.4.3/yumcommands.py
--- yum-3.4.3/yumcommands.py.old 2016-03-22 12:22:54.398569730 +0100
+++ yum-3.4.3/yumcommands.py 2016-03-22 12:27:30.261523615 +0100
@@ -4072,6 +4072,7 @@ class UpdateinfoCommand(YumCommand):
extcmds, show_type, filt_type = self._parse_extcmds(extcmds)
list_type = "available"
+ list_type = "updates"
if extcmds and extcmds[0] in ("updates","available","installed", "all"):
list_type = extcmds.pop(0)
if filt_type is None:
@@ -4087,13 +4088,15 @@ class UpdateinfoCommand(YumCommand):
used_map = _upi._ysp_gen_used_map(base.updateinfo_filters)
iname2tup = {}
if False: pass
- elif list_type in ('installed', 'all'):
+ elif list_type == 'installed':
name2tup = _upi._get_name2allpkgtup(base)
iname2tup = _upi._get_name2instpkgtup(base)
elif list_type == 'updates':
name2tup = _upi._get_name2oldpkgtup(base)
- elif list_type == 'available':
- name2tup = _upi._get_name2instpkgtup(base)
+ elif list_type in ('available', 'all'):
+ name2tup = _upi._get_name2aallpkgtup(base)
+ iname2tup = _upi._get_name2instpkgtup(base)
+
def _show_pkgtup(pkgtup):
name = pkgtup[0]
@@ -4106,6 +4109,10 @@ class UpdateinfoCommand(YumCommand):
# Remove any that are newer than what we have installed
if _upi._rpm_tup_vercmp(iname2tup[name], pkgtup) < 0:
continue
+ if list_type == 'available':
+ # Remove any that are installed
+ if name in iname2tup and _upi._rpm_tup_vercmp(iname2tup[name], pkgtup) >= 0:
+ continue
if _upi._ysp_should_filter_pkg(opts, name, notice, used_map):
yield (pkgtup, notice)

38
SOURCES/BZ-1292160-security-lists-wrong-arch-updates.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
commit 6b25184fcd5634d0abcdda0ed77e75a38a0d5186
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Dec 16 16:28:48 2015 +0100

Fix updateinfo to exclude wrong arch updates

diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index 59374af..3e6395e 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -401,24 +401,17 @@ def exclude_updates(base, filters=None):
used_map = _ysp_gen_used_map(opts)
- # In theory the official API is:
- #
- # pkgs = base.pkgSack.returnPackages()
- #
- # ...however that is _extremely_ slow, deleting all packages. So we ask
- # for the list of update packages, which is all we care about.
upds = base.doPackageLists(pkgnarrow='updates')
- pkgs = upds.updates
+ tot = len(upds.updates)
# In theory we don't need to do this in some cases, but meh.
upds = base.doPackageLists(pkgnarrow='obsoletes')
- pkgs += upds.obsoletes
+ tot += len(upds.obsoletes)
+ pkgs = conduit.getPackages()
name2tup = _get_name2oldpkgtup(base)
- tot = 0
cnt = 0
for pkg in pkgs:
- tot += 1
name = pkg.name
if (name not in name2tup or
not _ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):

66
SOURCES/BZ-1293378-ftp-disable-epsv.patch

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
commit 8b41b097716abde0b4ad9af4e813da9e3ed6620b
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Dec 21 16:29:34 2015 +0100

Add ftp_disable_epsv config option

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index 27620b8..116829a 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -439,6 +439,11 @@ default of 5 connections. Note that there are also implicit per-mirror limits
and the downloader honors these too.
.IP
+\fBftp_disable_epsv \fR
+This options disables Extended Passive Mode (the EPSV command) which does not
+work correctly on some buggy ftp servers. Default is `0' (EPSV enabled).
+
+.IP
\fBdeltarpm\fR
When non-zero, delta-RPM files are used if available. The value specifies
@@ -1114,6 +1119,11 @@ Overrides the \fBip_resolve\fR option from the [main] section for this
repository.
.IP
+\fBftp_disable_epsv\fR
+Overrides the \fBftp_disable_epsv\fR option from the [main] section
+for this repository.
+
+.IP
\fBdeltarpm_percentage\fR
Overrides the \fBdeltarpm_percentage\fR option from the [main] section
for this repository.
diff --git a/yum/config.py b/yum/config.py
index 77a1003..6bd8d24 100644
--- a/yum/config.py
+++ b/yum/config.py
@@ -811,6 +811,7 @@ class YumConf(StartupConf):
allowed = ('ipv4', 'ipv6', 'whatever'),
mapper = {'4': 'ipv4', '6': 'ipv6'})
max_connections = IntOption(0, range_min=0)
+ ftp_disable_epsv = BoolOption(False)
deltarpm = IntOption(2, range_min=-16, range_max=128)
deltarpm_percentage = IntOption(75, range_min=0, range_max=100)
deltarpm_metadata_percentage = IntOption(100, range_min=0)
@@ -1003,6 +1004,7 @@ class RepoConf(BaseConfig):
# Rely on the above config. to do automatic disabling, and thus. no hack
# needed here.
deltarpm_metadata_percentage = Inherit(YumConf.deltarpm_metadata_percentage)
+ ftp_disable_epsv = Inherit(YumConf.ftp_disable_epsv)
http_caching = Inherit(YumConf.http_caching)
metadata_expire = Inherit(YumConf.metadata_expire)
diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index 3dd0646..fc5d538 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -675,6 +675,7 @@ class YumRepository(Repository, config.RepoConf):
'user_agent': default_grabber.opts.user_agent,
'username': self.username,
'password': self.password,
+ 'ftp_disable_epsv': self.ftp_disable_epsv,
}
if self.proxy == 'libproxy':
opts['libproxy'] = True

11
SOURCES/BZ-1293513-compdir.patch

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
diff -up yum-3.4.3/etc/Makefile.old yum-3.4.3/etc/Makefile
--- yum-3.4.3/etc/Makefile.old 2016-05-11 15:13:20.615716472 +0200
+++ yum-3.4.3/etc/Makefile 2016-05-11 15:13:35.308778357 +0200
@@ -1,6 +1,5 @@
YUMETC=$(DESTDIR)/etc/yum
-compdir = $(shell pkg-config --variable=completionsdir bash-completion)
-compdir := $(or $(compdir), "/etc/bash_completion.d")
+compdir := $(or $(COMPDIR), "/etc/bash_completion.d")
all:
echo "Nothing to do"

24
SOURCES/BZ-1293670-proxy.patch

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
diff -up yum-3.2.29/yum/config.py.old yum-3.2.29/yum/config.py
--- yum-3.2.29/yum/config.py.old 2015-12-22 16:33:42.907483221 +0100
+++ yum-3.2.29/yum/config.py 2015-12-22 16:34:15.329584138 +0100
@@ -202,7 +202,7 @@ class UrlOption(Option):
# Handle the "_none_" special case
if url.lower() == '_none_':
if self.allow_none:
- return None
+ return '_none_'
else:
raise ValueError('"_none_" is not a valid value')
diff -up yum-3.2.29/yum/yumRepo.py.old yum-3.2.29/yum/yumRepo.py
--- yum-3.2.29/yum/yumRepo.py.old 2015-12-22 16:35:08.330749108 +0100
+++ yum-3.2.29/yum/yumRepo.py 2015-12-22 16:36:37.668027178 +0100
@@ -432,7 +432,7 @@ class YumRepository(Repository, config.R
self._proxy_dict = {} # zap it
proxy_string = None
empty = (None, '_none_', '')
- if self.proxy is None: # got 'proxy=_none_'
+ if self.proxy in empty: # got 'proxy=_none_'
proxy_string = '' # this disables default proxies
elif self.proxy:
proxy_string = '%s' % self.proxy

49
SOURCES/BZ-1294789-yum-cron-fix-update_cmd.patch

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
From ec2269ad7cbdbbd674d4fdbf5c670e43c937c2a6 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Tue, 2 Feb 2016 10:44:04 +0100
Subject: [PATCH] yum-cron: fix the parsing of update_cmd. BZ 1294789

This fixes the case when {minimal-}security-severity is used as
update_cmd in the conf file. Previously, the method would incorrectly
handle those two cases the same way as "default".
---
yum-cron/yum-cron.py | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 20911af..039f537 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -427,24 +427,23 @@ class YumCronBase(yum.YumBase, YumOutput):
self.updateinfo_filters['sevs'] = sevs.split(",")
- if self.opts.update_cmd in ('minimal', 'minimal-security'):
+ if update_cmd in ('minimal', 'minimal-security'):
if not yum.updateinfo.update_minimal(self):
return False
self.updateinfo_filters['bugfix'] = True
- elif self.opts.update_cmd in ('default', 'security',
- 'default-security'):
+ elif update_cmd in ('default', 'security', 'default-security'):
if not self.update():
return False
else:
# return False ?
- self.opts.update_cmd = 'default'
+ update_cmd = 'default'
if not self.update():
return False
- if self.opts.update_cmd.endswith("security"):
+ if update_cmd.endswith("security"):
self.updateinfo_filters['security'] = True
yum.updateinfo.remove_txmbrs(self)
- elif self.opts.update_cmd == 'minimal':
+ elif update_cmd == 'minimal':
self.updateinfo_filters['bugfix'] = True
yum.updateinfo.remove_txmbrs(self)
--
2.5.0

86
SOURCES/BZ-1306142-allow-older-installonly-deps.patch

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
commit afac6a760b97b7dd71c06c00a4716d3212f6884c
Author: Masahiro Matsuya <mmatsuya@redhat.com>
Date: Wed Apr 20 10:16:10 2016 +0200

Cope with older installonly packages from deps. BZ 1306142
We have been doing this with explicitly installed packages but not for
their dependencies, so let's do it after depsolving again to cover those
too.

diff --git a/test/operationstests.py b/test/operationstests.py
index 5a50439..bd999e6 100644
--- a/test/operationstests.py
+++ b/test/operationstests.py
@@ -1,3 +1,4 @@
+import rpm
from testbase import *
import simpleobsoletestests
@@ -142,6 +143,17 @@ class KernelTests(OperationsTests):
res, msg = self.runOperation(['install','kernel-2.6.23.8'], p.inst, p.avail)
self.assertResult(p.inst)
+ def testRequireOlderKernel(self):
+ p = self.pkgs
+
+ foo = FakePackage('foo', '1.0', '1', arch='i686')
+ foo.addRequires('kernel', 'EQ', (None, '2.6.23.5', '1'))
+ navail = [foo, FakePackage('kernel', '2.6.23.5', '1',arch='i686')]
+
+ res, msg = self.runOperation(['install', 'foo'], p.inst, navail)
+ self.assertResult(p.inst + navail)
+ self.assertEquals(self.tsInfo.probFilterFlags, [rpm.RPMPROB_FILTER_OLDPACKAGE])
+
class MultiLibTests(OperationsTests):
@staticmethod
diff --git a/yum/__init__.py b/yum/__init__.py
index acaa973..c896fff 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1356,6 +1356,17 @@ much more problems).
if rescode == 2:
self.save_ts(auto=True)
+
+ # Make sure we don't fail in rpm if we're installing a package that is
+ # allowed multiple installs but has a newer version already installed.
+ # Note that we already have a similar check in install(), but here we
+ # do it to cover anything that was pulled in as a dependency.
+ if rpm.RPMPROB_FILTER_OLDPACKAGE not in self.tsInfo.probFilterFlags:
+ for m in self.tsInfo.getMembers():
+ if m.ts_state == 'i' and self.allowedMultipleInstalls(m.po):
+ if self._enable_oldpackage_flag(m.po):
+ break
+
self.verbose_logger.debug('Depsolve time: %0.3f' % (time.time() - ds_st))
return rescode, restring
@@ -4674,6 +4685,14 @@ much more problems).
if flag not in self.tsInfo.probFilterFlags:
self.tsInfo.probFilterFlags.append(flag)
+ def _enable_oldpackage_flag(self, po):
+ """Add RPMPROB_FILTER_OLDPACKAGE if the package requires it."""
+ for ipkg in self.rpmdb.searchNevra(name=po.name):
+ if ipkg.verGT(po) and not canCoinstall(ipkg.arch, po.arch):
+ self._add_prob_flags(rpm.RPMPROB_FILTER_OLDPACKAGE)
+ return True
+ return False
+
def _install_is_upgrade(self, po, ipkgs):
""" See if po is an upgradeable version of an installed pkg.
Non-compat. arch differences mean no. """
@@ -4969,10 +4988,7 @@ much more problems).
# and a remove, which also tries to remove the old version.
self.tsInfo.remove(ipkg.pkgtup)
break
- for ipkg in self.rpmdb.searchNevra(name=po.name):
- if ipkg.verGT(po) and not canCoinstall(ipkg.arch, po.arch):
- self._add_prob_flags(rpm.RPMPROB_FILTER_OLDPACKAGE)
- break
+ self._enable_oldpackage_flag(po)
# it doesn't obsolete anything. If it does, mark that in the tsInfo, too
obs_pkgs = list(self._find_obsoletees_direct(po))

19
SOURCES/BZ-1309676-fs-command-help-fix.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
commit f1766901d3192df6af77de0d0aee027cd9ebae3b
Author: James Antill <james@and.org>
Date: Fri Apr 11 01:23:31 2014 -0400

Fix summary for yum fs command. BZ 1086461.

diff --git a/yumcommands.py b/yumcommands.py
index 8ee2650..74e4d86 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -4324,7 +4324,7 @@ class FSCommand(YumCommand):
return "[]"
def getSummary(self):
- return _("Creates filesystem snapshots, or lists/deletes current snapshots.")
+ return _("Acts on the filesystem data of the host, mainly for removing docs/lanuages for minimal hosts.")
def doCheck(self, base, basecmd, extcmds):
"""Verify that conditions are met so that this command can run.

47
SOURCES/BZ-1321651-repoinfo-add-metadata-expire-filter.patch

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
commit 36a49290d73951bd92dd0b2db877d11db2a3276f
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Mon Apr 25 17:09:25 2016 +0200

Add metadata_expire_filter to repoinfo output. BZ 1321651

diff --git a/yumcommands.py b/yumcommands.py
index 7118f3b..618ae5c 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -2325,7 +2325,10 @@ class RepoListCommand(YumCommand):
num = _num2ui_num(repo.metadata_expire)
num = _("%s second(s) (last: %s)") % (num, last)
- out += [base.fmtKeyValFill(_("Repo-expire : "), num)]
+ out += [base.fmtKeyValFill(_("Repo-expire : "), num),
+ base.fmtKeyValFill(_(" Filter : "),
+ repo.metadata_expire_filter),
+ ]
if repo.exclude:
out += [base.fmtKeyValFill(_("Repo-exclude : "),

commit e2db41de3d19cbd8c94a1c3824b541dbd4b706bb
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Mon Apr 25 15:12:23 2016 +0200

docs: add a freshness note for metadata_expire_filter

diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
index f823c6f..efc6765 100644
--- a/docs/yum.conf.5
+++ b/docs/yum.conf.5
@@ -646,7 +646,12 @@ Eg. yum list yum
`read-only:future' - Commands that are likely to result in running other
commands which will require the latest metadata. Eg. yum check-update
-Note that this option does not override "yum clean expire-cache".
+Note that this option requires that all the enabled repositories be roughly the
+same freshness (meaning the cache age difference from one another is at most 5
+days). Failing that, metadata_expire will always be obeyed, just like with
+`never'.
+
+Also note that this option does not override "yum clean expire-cache".
.IP
\fBmirrorlist_expire \fR

19
SOURCES/BZ-1327962-conduit-typo.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
commit 4474b17efc7acaa57217389cccdc36d706fdfae9
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri May 6 11:08:14 2016 +0200

Fix a typo in exclude_updates().

diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index dad6996..2b39330 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -407,7 +407,7 @@ def exclude_updates(base, filters=None):
upds = base.doPackageLists(pkgnarrow='obsoletes')
tot += len(upds.obsoletes)
- pkgs = conduit.getPackages()
+ pkgs = base.pkgSack.returnPackages()
name2tup = _get_name2oldpkgtup(base)
cnt = 0

75
SOURCES/BZ-1328023-updateinfo-traceback.patch

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
commit f2fc1ef96b0de995e2a61bf219b5d2c1d5a09503
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Mar 5 17:49:02 2014 +0100

Fix 'yum updateinfo list all new-packages' traceback. BZ 1072945
And make 'list' and 'info' indicate if the package is installed.

diff --git a/yumcommands.py b/yumcommands.py
index 74e4333..4e72a71 100644
--- a/yumcommands.py
+++ b/yumcommands.py
@@ -3840,7 +3840,7 @@ class UpdateinfoCommand(YumCommand):
mark = ''
if list_type == 'all':
mark = ' '
- if _upi._rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
+ if pkgtup[0] in iname2tup and _upi._rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
mark = 'i '
tn = notice['type']
if tn == 'security' and notice['severity']:
@@ -3879,7 +3879,7 @@ class UpdateinfoCommand(YumCommand):
obj = notice.__str__()
if list_type == 'all':
- if _upi._rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
+ if pkgtup[0] in iname2tup and _upi._rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
obj = obj + "\n Installed : true"
else:
obj = obj + "\n Installed : false"
@@ -4029,7 +4029,7 @@ class UpdateinfoCommand(YumCommand):
return 0, [basecmd + ' ' + subcommand + ' done']
def doCommand_li_new(self, base, list_type, extcmds, md_info, msg,
- show_pkgs):
+ show_pkgs, iname2tup):
done_pkgs = set()
data = []
for (notice, pkgtup) in sorted(self._get_new_pkgs(md_info),
@@ -4055,7 +4055,7 @@ class UpdateinfoCommand(YumCommand):
continue
done_pkgs.add(n)
data.append((notice, pkgtup, pkgs[0]))
- show_pkgs(base, md_info, list_type, None, {}, data, msg)
+ show_pkgs(base, md_info, list_type, None, iname2tup, data, msg)
def _parse_extcmds(self, extcmds):
filt_type = None
@@ -4086,12 +4086,6 @@ class UpdateinfoCommand(YumCommand):
if filt_type is None:
extcmds, show_type, filt_type = self._parse_extcmds(extcmds)
- if filt_type == "newpackage":
- # No filtering here, as we want what isn't installed...
- self.doCommand_li_new(base, list_type, extcmds, md_info, msg,
- show_pkgs)
- return 0, [basecmd + ' new done']
-
opts.sec_cmds = extcmds
used_map = _upi._ysp_gen_used_map(base.updateinfo_filters)
iname2tup = {}
diff -up yum-3.4.3/yumcommands.py.old yum-3.4.3/yumcommands.py
--- yum-3.4.3/yumcommands.py.old 2016-05-10 17:19:04.007269059 +0200
+++ yum-3.4.3/yumcommands.py 2016-05-10 17:20:11.320698042 +0200
@@ -4094,6 +4094,10 @@ class UpdateinfoCommand(YumCommand):
name2tup = _upi._get_name2aallpkgtup(base)
iname2tup = _upi._get_name2instpkgtup(base)
+ if filt_type == "newpackage":
+ self.doCommand_li_new(base, list_type, extcmds, md_info, msg,
+ show_pkgs, iname2tup)
+ return 0, [basecmd + ' new done']
def _show_pkgtup(pkgtup):
name = pkgtup[0]

59
SOURCES/BZ-1330423-skipbroken-installonly-limit-fix.patch

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
commit 3c89608a67ee9fd35d1860c183951dde76464cd0
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Fri May 6 13:25:25 2016 +0200

skipbroken: don't installonly_limit if new pkg fails. BZ 1330423
This is a fix up for commit f8c1528.
- Add po instead of txmbr to txmbr.depends_on
- Make sure the depending po is not whatever was last stored in m

diff --git a/yum/__init__.py b/yum/__init__.py
index 764e97d..cd66396 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -6459,15 +6459,15 @@ much more problems).
continue
if m.name not in found:
- found[m.name] = 1
+ found[m.name] = [m.po]
else:
- found[m.name] += 1
+ found[m.name].append(m.po)
for name in found:
installed = self.rpmdb.searchNevra(name=name)
installed = _sort_and_filter_installonly(installed)
- total = len(installed) + found[name]
+ total = len(installed) + len(found[name])
if total <= self.conf.installonly_limit:
continue # Not adding enough to trigger.
@@ -6479,14 +6479,20 @@ much more problems).
continue
if numleft == 0:
break
- toremove.append((po,m))
+ toremove.append((po, found[name]))
numleft -= 1
- for po,rel in toremove:
+ for po, newpos in toremove:
txmbr = self.tsInfo.addErase(po)
- # Add a dep relation to the new version of the package, causing this one to be erased
- # this way skipbroken, should clean out the old one, if the new one is skipped
- txmbr.depends_on.append(rel)
+ # Add a dep relation to the new version of the package that causes
+ # this one to be erased. This way skipbroken should drop the old
+ # one from the transaction if the new one is skipped. Note that we
+ # can only do this for one new version, as skipbroken won't drop
+ # deps that are shared with some other packages. For consistency,
+ # let's give up completely if we are installing multiple new
+ # versions (which is rather uncommon anyway).
+ if len(newpos) == 1:
+ txmbr.depends_on.append(newpos[0])
def processTransaction(self, callback=None,rpmTestDisplay=None, rpmDisplay=None):
"""Process the current transaction. This involves the

46
SOURCES/BZ-1330670-system-name-email-from-cron.patch

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
commit 8bc82519a96a26025afcfdb05e5624739440b21c
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Jun 30 17:13:47 2016 +0200

yum-cron: replace 'localhost' with system_name value in email_from. BZ 1330670

diff --git a/etc/yum-cron-hourly.conf b/etc/yum-cron-hourly.conf
index 63c0bb6..5265d03 100644
--- a/etc/yum-cron-hourly.conf
+++ b/etc/yum-cron-hourly.conf
@@ -47,6 +47,7 @@ output_width = 80
[email]
# The address to send email messages from.
+# NOTE: 'localhost' will be replaced with the value of system_name.
email_from = root
# List of addresses to send messages to.
diff --git a/etc/yum-cron.conf b/etc/yum-cron.conf
index 7ab4d04..6a3d5ca 100644
--- a/etc/yum-cron.conf
+++ b/etc/yum-cron.conf
@@ -49,6 +49,7 @@ output_width = 80
[email]
# The address to send email messages from.
+# NOTE: 'localhost' will be replaced with the value of system_name.
email_from = root@localhost
# List of addresses to send messages to.
diff --git a/yum-cron/yum-cron.py b/yum-cron/yum-cron.py
index 12c7720..23f36d3 100755
--- a/yum-cron/yum-cron.py
+++ b/yum-cron/yum-cron.py
@@ -236,7 +236,10 @@ class EmailEmitter(UpdateEmitter):
charset = 'us-ascii'
msg = MIMEText(output, 'plain', charset)
msg['Subject'] = self.subject
- msg['From'] = self.opts.email_from
+ username, at, domain = self.opts.email_from.rpartition('@')
+ if domain == 'localhost':
+ domain = self.opts.system_name
+ msg['From'] = '%s@%s' % (username, domain)
msg['To'] = ",".join(self.opts.email_to)
# Send the email

408
SOURCES/BZ-1335250-fssnapshot-handle-lvm-errors.patch

@ -0,0 +1,408 @@ @@ -0,0 +1,408 @@
diff -up yum-3.4.3/yumcommands.py.orig yum-3.4.3/yumcommands.py
--- yum-3.4.3/yumcommands.py.orig 2016-07-21 11:39:40.422379800 +0200
+++ yum-3.4.3/yumcommands.py 2016-07-21 11:40:42.144992126 +0200
@@ -42,6 +42,7 @@ import errno
import yum.config
from yum import updateinfo
from yum.packages import parsePackages
+from yum.fssnapshots import LibLVMError, lvmerr2str
def _err_mini_usage(base, basecmd):
if basecmd not in base.yum_cli_commands:
@@ -4266,12 +4267,19 @@ class FSSnapshotCommand(YumCommand):
return 1, [basecmd + ' ' + subcommand + ' done']
if subcommand == 'list':
- snaps = base.fssnap.old_snapshots()
+ try:
+ snaps = base.fssnap.old_snapshots()
+ except LibLVMError as e:
+ return 1, [_("Failed to list snapshots: ") + lvmerr2str(e)]
print _("List of %u snapshosts:") % len(snaps)
self._li_snaps(base, snaps)
if subcommand == 'delete':
- snaps = base.fssnap.old_snapshots()
+ msg = _("Failed to delete snapshots: ")
+ try:
+ snaps = base.fssnap.old_snapshots()
+ except LibLVMError as e:
+ return 1, [msg + lvmerr2str(e)]
devs = [x['dev'] for x in snaps]
snaps = set()
for dev in devs:
@@ -4282,13 +4290,20 @@ class FSSnapshotCommand(YumCommand):
if dev == extcmd or fnmatch.fnmatch(dev, extcmd):
snaps.add(dev)
break
- snaps = base.fssnap.del_snapshots(devices=snaps)
+ try:
+ snaps = base.fssnap.del_snapshots(devices=snaps)
+ except LibLVMError as e:
+ return 1, [msg + lvmerr2str(e)]
print _("Deleted %u snapshosts:") % len(snaps)
self._li_snaps(base, snaps)
if subcommand in ('have-space', 'has-space'):
pc = base.conf.fssnap_percentage
- if base.fssnap.has_space(pc):
+ try:
+ has_space = base.fssnap.has_space(pc)
+ except LibLVMError as e:
+ return 1, [_("Could not determine free space on logical volumes: ") + lvmerr2str(e)]
+ if has_space:
print _("Space available to take a snapshot.")
else:
print _("Not enough space available on logical volumes to take a snapshot.")
@@ -4296,14 +4311,22 @@ class FSSnapshotCommand(YumCommand):
if subcommand == 'create':
tags = {'*': ['reason=manual']}
pc = base.conf.fssnap_percentage
- snaps = base.fssnap.snapshot(pc, tags=tags)
+ msg = _("Failed to create snapshots")
+ try:
+ snaps = base.fssnap.snapshot(pc, tags=tags)
+ except LibLVMError as e:
+ msg += ": " + lvmerr2str(e)
+ snaps = []
if not snaps:
- print _("Failed to create snapshots")
+ print msg
for (odev, ndev) in snaps:
print _("Created snapshot from %s, results is: %s") %(odev,ndev)
if subcommand == 'summary':
- snaps = base.fssnap.old_snapshots()
+ try:
+ snaps = base.fssnap.old_snapshots()
+ except LibLVMError as e:
+ return 1, [_("Failed to list snapshots: ") + lvmerr2str(e)]
if not snaps:
print _("No snapshots, LVM version:"), base.fssnap.version
return 0, [basecmd + ' ' + subcommand + ' done']
diff -up yum-3.4.3/yum/fssnapshots.py.orig yum-3.4.3/yum/fssnapshots.py
--- yum-3.4.3/yum/fssnapshots.py.orig 2016-07-21 11:39:40.351380246 +0200
+++ yum-3.4.3/yum/fssnapshots.py 2016-07-21 11:40:02.211242946 +0200
@@ -6,6 +6,7 @@ import time
from datetime import datetime
import subprocess
+from yum import _
try:
import lvm
@@ -24,6 +25,14 @@ except:
lvm = None
_ver = None
+if lvm is not None:
+ from lvm import LibLVMError
+ class _ResultError(LibLVMError):
+ """Exception raised for LVM calls resulting in bad return values."""
+ pass
+else:
+ LibLVMError = None
+
def _is_origin(lv):
snap = lv.getAttr()
@@ -53,14 +62,18 @@ def _vg_name2lv(vg, lvname):
return None
def _list_vg_names():
- names = lvm.listVgNames()
+ try:
+ names = lvm.listVgNames()
+ except LibLVMError:
+ # Try to use the lvm binary instead
+ names = []
if not names: # Could be just broken...
p = subprocess.Popen(["/sbin/lvm", "vgs", "-o", "vg_name"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
err = p.wait()
if err:
- return [] # Meh.
+ raise _ResultError(_("Failed to obtain volume group names"))
output = p.communicate()[0]
output = output.split('\n')
@@ -132,6 +145,25 @@ def _lv_data(vg, lv):
return data
+def _log_traceback(func):
+ """Decorator for _FSSnap methods that logs LVM tracebacks."""
+ def wrap(self, *args, **kwargs):
+ try:
+ return func(self, *args, **kwargs)
+ except LibLVMError as e:
+ if self._logger is not None:
+ self._logger.exception(e)
+ raise
+ return wrap
+
+def lvmerr2str(exc):
+ """Convert a LibLVMError instance to a readable error message."""
+ if type(exc) == LibLVMError and len(exc.args) == 2:
+ # args[0] is the error number so ignore that
+ return exc.args[1]
+ else:
+ return str(exc)
+
class _FSSnap(object):
@@ -139,7 +171,7 @@ class _FSSnap(object):
# New style is: fedora/root fedora/swap
# New style is: redhat/root redhat/swap
def __init__(self, root="/", lookup_mounts=True,
- devices=('!*/swap', '!*/lv_swap')):
+ devices=('!*/swap', '!*/lv_swap'), logger=None):
if not lvm or os.geteuid():
devices = []
@@ -150,12 +182,18 @@ class _FSSnap(object):
self._postfix = None
self._root = root
self._devs = devices
- self._vgnames = []
+ self._vgname_list = None
+ # Logger object to be used for LVM traceback logging
+ self._logger = logger
if not self._devs:
return
- self._vgnames = _list_vg_names() if self.available else []
+ @property
+ def _vgnames(self):
+ if self._vgname_list is None:
+ self._vgname_list = _list_vg_names() if self.available else []
+ return self._vgname_list
def _use_dev(self, vgname, lv=None):
@@ -196,6 +234,7 @@ class _FSSnap(object):
return found_neg
+ @_log_traceback
def has_space(self, percentage=100):
""" See if we have enough space to try a snapshot. """
@@ -207,7 +246,8 @@ class _FSSnap(object):
vg = lvm.vgOpen(vgname, 'r')
if not vg:
- return False
+ raise _ResultError(
+ _("Unknown error when opening volume group ") + vgname)
vgfsize = vg.getFreeSize()
lvssize = 0
@@ -230,6 +270,7 @@ class _FSSnap(object):
return ret
+ @_log_traceback
def snapshot(self, percentage=100, prefix='', postfix=None, tags={}):
""" Attempt to take a snapshot, note that errors can happen after
this function succeeds. """
@@ -245,7 +286,8 @@ class _FSSnap(object):
vg = lvm.vgOpen(vgname, 'w')
if not vg:
- return False
+ raise _ResultError(
+ _("Unknown error when opening volume group ") + vgname)
for lv in vg.listLVs():
lvname = lv.getName()
@@ -257,7 +299,8 @@ class _FSSnap(object):
nlv = lv.snapshot(nlvname, (lv.getSize() * percentage) / 100)
if not nlv: # Failed here ... continuing seems bad.
vg.close()
- return None
+ raise _ResultError(
+ _("Unknown error when creating snapshot ") + nlvname)
odev = "%s/%s" % (vgname, lvname)
ndev = "%s/%s" % (vgname, nlvname)
@@ -280,6 +323,7 @@ class _FSSnap(object):
return ret
+ @_log_traceback
def old_snapshots(self):
""" List data for old snapshots. """
@@ -289,6 +333,9 @@ class _FSSnap(object):
# see stuff after changing config. options.
vg = lvm.vgOpen(vgname, 'w')
+ if not vg:
+ raise _ResultError(
+ _("Unknown error when opening volume group ") + vgname)
for lv in vg.listLVs():
@@ -300,6 +347,7 @@ class _FSSnap(object):
return ret
+ @_log_traceback
def del_snapshots(self, devices=[]):
""" Remove snapshots. """
@@ -318,6 +366,9 @@ class _FSSnap(object):
for vgname in togo:
vg = lvm.vgOpen(vgname, 'w')
+ if not vg:
+ raise _ResultError(
+ _("Unknown error when opening volume group ") + vgname)
for lvname in togo[vgname]:
lv = _vg_name2lv(vg, lvname)
diff -up yum-3.4.3/yum/__init__.py.orig yum-3.4.3/yum/__init__.py
--- yum-3.4.3/yum/__init__.py.orig 2016-07-21 11:39:40.425379782 +0200
+++ yum-3.4.3/yum/__init__.py 2016-07-21 11:40:02.211242946 +0200
@@ -81,6 +81,7 @@ import yumRepo
import callbacks
import yum.history
import yum.fssnapshots
+from yum.fssnapshots import LibLVMError, lvmerr2str
import yum.igroups
import update_md
@@ -204,6 +205,7 @@ class YumBase(depsolve.Depsolve):
self._not_found_i = {}
self.logger = logging.getLogger("yum.YumBase")
self.verbose_logger = logging.getLogger("yum.verbose.YumBase")
+ self.file_logger = logging.getLogger("yum.filelogging.YumBase")
self._override_sigchecks = False
self._repos = RepoStorage(self)
self.repo_setopts = {} # since we have to use repo_setopts in base and
@@ -1048,7 +1050,8 @@ class YumBase(depsolve.Depsolve):
if self._fssnap is None:
devices = self.conf.fssnap_devices
self._fssnap = yum.fssnapshots._FSSnap(root=self.conf.installroot,
- devices=devices)
+ devices=devices,
+ logger=self.file_logger)
return self._fssnap
@@ -1726,6 +1729,37 @@ much more problems).
:raises: :class:`yum.Errors.YumRPMTransError` if there is a
transaction cannot be completed
"""
+
+ def create_snapshot(post=False):
+ """Create the pre or post trans snapshot if we have free space."""
+ msg = _("Not enough space on logical volumes to create %s FS snapshot." %
+ ("post trans" if post else "pre."))
+ try:
+ has_space = self.fssnap.has_space(self.conf.fssnap_percentage)
+ except LibLVMError as e:
+ msg = _("Could not determine free space on logical volumes: ") + lvmerr2str(e)
+ has_space = False
+ if not has_space:
+ if not post and self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
+ raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
+ else:
+ self.verbose_logger.critical(msg)
+ else:
+ tags = {'*': ['reason=automatic']} # FIXME: pre. and post tags
+ msg = _("Failed to create snapshot")
+ try:
+ snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
+ except LibLVMError as e:
+ msg += ": " + lvmerr2str(e)
+ snaps = []
+ if not snaps:
+ if not post and self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
+ raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
+ else:
+ self.verbose_logger.critical(msg)
+ for (odev, ndev) in snaps:
+ self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
+
if (self.conf.fssnap_automatic_pre or self.conf.fssnap_automatic_post) and not self.fssnap.available:
msg = _("Snapshot support not available.")
if self.conf.fssnap_abort_on_errors in ('broken-setup', 'any'):
@@ -1737,7 +1771,13 @@ much more problems).
self.conf.fssnap_automatic_post) and
self.conf.fssnap_automatic_keep):
# Automatically kill old snapshots...
- snaps = self.fssnap.old_snapshots()
+ cleanup_fail = False
+ try:
+ snaps = self.fssnap.old_snapshots()
+ except LibLVMError as e:
+ self.verbose_logger.debug(lvmerr2str(e))
+ cleanup_fail = True
+ snaps = []
snaps = sorted(snaps, key=lambda x: (x['ctime'], x['origin_dev']),
reverse=True)
last = '<n/a>'
@@ -1754,30 +1794,22 @@ much more problems).
if num > self.conf.fssnap_automatic_keep:
todel.append(snap['dev'])
# Display something to the user?
- snaps = self.fssnap.del_snapshots(devices=todel)
+ try:
+ snaps = self.fssnap.del_snapshots(devices=todel)
+ except LibLVMError as e:
+ self.verbose_logger.debug(lvmerr2str(e))
+ cleanup_fail = True
+ snaps = []
if len(snaps):
self.verbose_logger.info(_("Deleted %u snapshots.") % len(snaps))
+ elif cleanup_fail:
+ self.verbose_logger.warning(_("Skipping the cleanup of old "
+ "snapshots due to errors"))
if (self.fssnap.available and
(not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
self.conf.fssnap_automatic_pre)):
- if not self.fssnap.has_space(self.conf.fssnap_percentage):
- msg = _("Not enough space on logical volumes to create pre. FS snapshot.")
- if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
- raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
- else:
- self.verbose_logger.critical(msg)
- else:
- tags = {'*': ['reason=automatic']} # FIXME: pre. tags
- snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
- if not snaps:
- msg = _("Failed to create snapshot")
- if self.conf.fssnap_abort_on_errors in ('snapshot-failure', 'any'):
- raise Errors.YumRPMTransError(msg="Aborting transaction", errors=msg)
- else:
- self.verbose_logger.critical(msg)
- for (odev, ndev) in snaps:
- self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
+ create_snapshot()
self.plugins.run('pretrans')
@@ -1912,16 +1944,7 @@ much more problems).
if (self.fssnap.available and
(not self.ts.isTsFlagSet(rpm.RPMTRANS_FLAG_TEST) and
self.conf.fssnap_automatic_post)):
- if not self.fssnap.has_space(self.conf.fssnap_percentage):
- msg = _("Not enough space on logical volumes to create post trans FS snapshot.")
- self.verbose_logger.critical(msg)
- else:
- tags = {'*': ['reason=automatic']} # FIXME: post tags
- snaps = self.fssnap.snapshot(self.conf.fssnap_percentage, tags=tags)
- if not snaps:
- self.verbose_logger.critical(_("Failed to create snapshot"))
- for (odev, ndev) in snaps:
- self.verbose_logger.info(_("Created snapshot from %s, results is: %s") % (odev, ndev))
+ create_snapshot(post=True)
return resultobject
def verifyTransaction(self, resultobject=None, txmbr_cb=None):

128
SOURCES/BZ-1337105-add-lazy-packages-caching-opt.patch

@ -0,0 +1,128 @@ @@ -0,0 +1,128 @@
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2016-08-02 15:08:10.160947580 +0200
+++ yum-3.4.3/docs/yum.conf.5 2016-08-02 15:08:30.046853379 +0200
@@ -381,6 +381,13 @@ that Yum does. This option can take the
`packages' means that only RPM package downloads should be cached (but not
repository metadata downloads).
+`lazy:packages' means that act like `packages' unless package verification
+fails (e.g. the package download doesn't match the expected checksum), in which
+case try re-downloading the package as if `none' was set. This value is a good
+compromise if you want to avoid issues caused by stale proxy cache after remote
+RPMs change contents without changing filenames (e.g. are pushed unsigned and
+later signed) but still want the benefits of package caching whenever possible.
+
`none' means that no HTTP downloads should be cached.
The default is `all'. This is recommended unless you are experiencing caching
diff -up yum-3.4.3/output.py.orig yum-3.4.3/output.py
--- yum-3.4.3/output.py.orig 2016-08-02 15:08:10.074947988 +0200
+++ yum-3.4.3/output.py 2016-08-02 15:08:30.053853346 +0200
@@ -472,6 +472,13 @@ class YumOutput:
:raises: *errobj*.exception
"""
self.logger.error('%s: %s', errobj.url, errobj.exception)
+ if hasattr(errobj, 'retry_no_cache') and errobj.retry_no_cache and \
+ errobj.exception.errno < 0:
+ self.logger.error(_('Trying again, now avoiding proxy cache.'))
+ # Raising an exception would cause urlgrabber to jump to the next
+ # mirror and what we want here is to retry with the same, so just
+ # return.
+ return
self.logger.error(_('Trying other mirror.'))
self.suggestKBaseArticle(errobj)
raise errobj.exception
diff -up yum-3.4.3/yum/config.py.orig yum-3.4.3/yum/config.py
--- yum-3.4.3/yum/config.py.orig 2016-08-02 15:08:10.159947585 +0200
+++ yum-3.4.3/yum/config.py 2016-08-02 15:08:30.048853370 +0200
@@ -810,7 +810,8 @@ class YumConf(StartupConf):
deltarpm_percentage = IntOption(75, range_min=0, range_max=100)
deltarpm_metadata_percentage = IntOption(100, range_min=0)
- http_caching = SelectionOption('all', ('none', 'packages', 'all'))
+ http_caching = SelectionOption('all', ('none', 'packages', 'all',
+ 'lazy:packages'))
metadata_expire = SecondsOption(60 * 60 * 6) # Time in seconds (6h).
metadata_expire_filter = SelectionOption('read-only:present',
('never', 'read-only:future',
diff -up yum-3.4.3/yum/__init__.py.orig yum-3.4.3/yum/__init__.py
diff -up yum-3.4.3/yum.spec.orig yum-3.4.3/yum.spec
--- yum-3.4.3/yum.spec.orig 2016-08-02 15:08:10.150947628 +0200
+++ yum-3.4.3/yum.spec 2016-08-02 15:08:30.047853374 +0200
@@ -63,7 +63,7 @@ BuildRequires: python >= 2.4
BuildRequires: rpm-python, rpm >= 0:4.4.2
BuildRequires: python-iniparse
BuildRequires: python-sqlite
-BuildRequires: python-urlgrabber >= 3.9.0-8
+BuildRequires: python-urlgrabber >= 3.10-8
BuildRequires: yum-metadata-parser >= 1.1.0
BuildRequires: pygpgme
# End of CheckRequires
@@ -72,7 +72,7 @@ Requires: python >= 2.4
Requires: rpm-python, rpm >= 0:4.4.2
Requires: python-iniparse
Requires: python-sqlite
-Requires: python-urlgrabber >= 3.9.0-8
+Requires: python-urlgrabber >= 3.10-8
Requires: yum-metadata-parser >= 1.1.0
Requires: pygpgme
# rawhide is >= 0.5.3-7.fc18 ... as this is added.
diff -up yum-3.4.3/yum/yumRepo.py.orig yum-3.4.3/yum/yumRepo.py
--- yum-3.4.3/yum/yumRepo.py.orig 2016-08-02 15:08:10.104947846 +0200
+++ yum-3.4.3/yum/yumRepo.py 2016-08-02 15:08:30.052853351 +0200
@@ -336,6 +336,7 @@ class YumRepository(Repository, config.R
self._repoXML = None
self._oldRepoMDData = {}
self.cache = 0
+ self._retry_no_cache = False
self.mirrorlistparsed = 0
self.yumvar = {} # empty dict of yumvariables for $string replacement
self._proxy_dict = {}
@@ -993,6 +994,7 @@ Insufficient space in download directory
interrupt_callback=self.interrupt_callback,
checkfunc=checkfunc,
size=size,
+ retry_no_cache=self._retry_no_cache,
**ugopts)
remote = url + '/' + relative
@@ -1020,6 +1022,7 @@ Insufficient space in download directory
checkfunc=checkfunc,
http_headers=headers,
size=size,
+ retry_no_cache=self._retry_no_cache,
**kwargs
)
except URLGrabError, e:
@@ -1049,15 +1052,22 @@ Insufficient space in download directory
misc.unlink_f(local)
raise URLGrabError(-1, _('Package does not match intended download.'))
- ret = self._getFile(url=basepath,
- relative=remote,
- local=local,
- checkfunc=checkfunc,
- text=text,
- cache=cache,
- size=package.size,
- **kwargs
- )
+ # We would normally pass this to _getFile() directly but that could
+ # break backward compatibility with plugins that override _getFile()
+ # (BZ 1360532).
+ self._retry_no_cache = self.http_caching == 'lazy:packages'
+ try:
+ ret = self._getFile(url=basepath,
+ relative=remote,
+ local=local,
+ checkfunc=checkfunc,
+ text=text,
+ cache=cache,
+ size=package.size,
+ **kwargs
+ )
+ finally:
+ self._retry_no_cache = False
if not kwargs.get('async') and not package.verifyLocalPkg():
# Don't return as "success" when bad.

58
SOURCES/BZ-1339168-yum-cron-conf-typo.patch

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
commit 4596a105fefc769d1d6df547f3bd172a53bf7a53
Author: Ville Skyttä <ville.skytta@iki.fi>
Date: Fri Jan 24 16:34:35 2014 +0200

s/ouput/output/ typo fixes

diff --git a/docs/sphinxdocs/rstgenerator.py b/docs/sphinxdocs/rstgenerator.py
index ad24788..4a0bca0 100755
--- a/docs/sphinxdocs/rstgenerator.py
+++ b/docs/sphinxdocs/rstgenerator.py
@@ -12,7 +12,7 @@ def generateFile(input_directory, file_name, output_directory,
source code file
:param file_name: the name of the python source code file to generate
a sphinx rst file describing
- :param ouput_directory: a string specifying the directory where
+ :param output_directory: a string specifying the directory where
the generated rst file should be placed. If *output_directory* does
not already exist, it will be created
:param package_heirarchy: a list of strings, where each name is
diff --git a/etc/yum-cron-hourly.conf b/etc/yum-cron-hourly.conf
index 7871a46..2a588cd 100644
--- a/etc/yum-cron-hourly.conf
+++ b/etc/yum-cron-hourly.conf
@@ -42,7 +42,7 @@ emit_via = stdio
# The width, in characters, that messages that are emitted should be
# formatted to.
-ouput_width = 80
+output_width = 80
[email]
diff --git a/etc/yum-cron.conf b/etc/yum-cron.conf
index b0f7839..7314fae 100644
--- a/etc/yum-cron.conf
+++ b/etc/yum-cron.conf
@@ -42,7 +42,7 @@ emit_via = stdio
# The width, in characters, that messages that are emitted should be
# formatted to.
-ouput_width = 80
+output_width = 80
[email]
diff --git a/shell.py b/shell.py
index 2232b03..00b6896 100644
--- a/shell.py
+++ b/shell.py
@@ -171,7 +171,7 @@ class YumShell(cmd.Cmd):
def do_help(self, arg):
"""Output help information.
- :param arg: the command to ouput help information about. If
+ :param arg: the command to output help information about. If
*arg* is an empty string, general help will be output.
"""
msg = """

129
SOURCES/BZ-1343690-add-payload-gpgcheck-opt.patch

@ -0,0 +1,129 @@ @@ -0,0 +1,129 @@
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2017-03-23 13:48:19.700471026 +0100
+++ yum-3.4.3/docs/yum.conf.5 2017-03-23 13:48:21.455461060 +0100
@@ -105,6 +105,31 @@ signature check on the repodata. When th
default for all repositories. The default is `0'.
.IP
+\fBpayload_gpgcheck\fR
+Either `1' or `0'. This tells yum whether or not it should also perform a GPG
+signature check on the payload (part of a package holding the actual files that
+comprise the package).
+
+By default, yum only performs GPG signature checks on package headers.
+Thus, if the payload data has been tampered with or corrupted, yum will fail in
+the middle of the transaction due to an RPM unpacking error, after some
+unverified scriptlets might have already run, and possibly leave the package in
+question partly installed.
+
+To prevent all of that, you can enable this option to extend the signature
+check to also include the payload, so that yum can avoid running the
+transaction in case of payload corruption.
+This slightly improves security, however at the expense of significantly
+increased transaction time, so you may want to only use this option when
+package corruption is a concern.
+
+For this option to have effect, make sure to also enable gpgcheck (or
+localpkg_gpgcheck for local packages).
+
+When this option is set in the [main] section it sets the default for all
+repositories. The default is `0'.
+
+.IP
\fBskip_broken\fR
Either `1' or `0'. Resolve depsolve problems by removing packages that
are causing problems from the transaction.
diff -up yum-3.4.3/rpmUtils/miscutils.py.orig yum-3.4.3/rpmUtils/miscutils.py
--- yum-3.4.3/rpmUtils/miscutils.py.orig 2011-06-28 22:27:22.000000000 +0200
+++ yum-3.4.3/rpmUtils/miscutils.py 2017-03-23 13:48:21.455461060 +0100
@@ -58,11 +58,16 @@ def compareVerOnly(v1, v2):
"""compare version strings only using rpm vercmp"""
return compareEVR(('', v1, ''), ('', v2, ''))
-def checkSig(ts, package):
- """Takes a transaction set and a package, check it's sigs,
+def checkSig(ts, package, payload=False):
+ """Takes a transaction set and a package, check it's sigs.
+
+ By default, only RPMv4 sigs (header-only) will be verified (faster). By
+ setting payload to True, RPMv3 sigs (header+payload) will also be verified
+ (slower).
+
return 0 if they are all fine
return 1 if the gpg key can't be found
- return 2 if the header is in someway damaged
+ return 2 if the header or payload is in someway damaged
return 3 if the key is not trusted
return 4 if the pkg is not gpg or pgp signed"""
@@ -89,6 +94,24 @@ def checkSig(ts, package):
else:
del hdr
+ # Don't perform the payload check if the header check failed, otherwise we
+ # could mask the reason stored in "value" (we only return one integer from
+ # this function and shouldn't change that).
+ if payload and value == 0:
+ os.lseek(fdno, 0, 0)
+ # We don't want the OK message to pollute the output but we do want the
+ # BAD message (verbose version) in case of a failure, which is only
+ # possible by running _verifySigs() twice (temporary hack until we have
+ # the proper API for payload verification in RPM).
+ rpm.setVerbosity(rpm.RPMLOG_WARNING)
+ valid = ts._verifySigs(fdno, package)
+ if not valid:
+ value = 2
+ os.lseek(fdno, 0, 0)
+ rpm.setVerbosity(rpm.RPMLOG_INFO)
+ ts._verifySigs(fdno, package)
+ rpm.setVerbosity(rpm.RPMLOG_NOTICE)
+
try:
os.close(fdno)
except OSError, e: # if we're not opened, don't scream about it
diff -up yum-3.4.3/rpmUtils/transaction.py.orig yum-3.4.3/rpmUtils/transaction.py
--- yum-3.4.3/rpmUtils/transaction.py.orig 2017-03-23 13:48:19.441472497 +0100
+++ yum-3.4.3/rpmUtils/transaction.py 2017-03-23 13:48:21.455461060 +0100
@@ -35,7 +35,8 @@ class TransactionWrapper:
'setProbFilter',
'hdrFromFdno',
'next',
- 'clean']
+ 'clean',
+ '_verifySigs']
self.tsflags = []
self.open = True
diff -up yum-3.4.3/yum/config.py.orig yum-3.4.3/yum/config.py
--- yum-3.4.3/yum/config.py.orig 2017-03-23 13:48:19.701471020 +0100
+++ yum-3.4.3/yum/config.py 2017-03-23 13:48:21.456461055 +0100
@@ -46,6 +46,7 @@ from misc import get_uuid, read_in_items
# Alter/patch these to change the default checking...
__pkgs_gpgcheck_default__ = False
__repo_gpgcheck_default__ = False
+__payload_gpgcheck_default__ = False
__main_multilib_policy_default__ = 'all'
__main_failovermethod_default__ = 'roundrobin'
__main_installonly_limit_default__ = 0
@@ -786,6 +787,7 @@ class YumConf(StartupConf):
gpgcheck = BoolOption(__pkgs_gpgcheck_default__)
repo_gpgcheck = BoolOption(__repo_gpgcheck_default__)
localpkg_gpgcheck = BoolOption(__pkgs_gpgcheck_default__)
+ payload_gpgcheck = BoolOption(__payload_gpgcheck_default__)
obsoletes = BoolOption(True)
showdupesfromrepos = BoolOption(False)
enabled = BoolOption(True)
diff -up yum-3.4.3/yum/__init__.py.orig yum-3.4.3/yum/__init__.py
--- yum-3.4.3/yum/__init__.py.orig 2017-03-23 13:48:19.731470850 +0100
+++ yum-3.4.3/yum/__init__.py 2017-03-23 13:48:21.456461055 +0100
@@ -2755,7 +2755,9 @@ much more problems).
if check:
ts = self.rpmdb.readOnlyTS()
- sigresult = rpmUtils.miscutils.checkSig(ts, po.localPkg())
+ sigresult = rpmUtils.miscutils.checkSig(
+ ts, po.localPkg(), payload=self.conf.payload_gpgcheck,
+ )
localfn = os.path.basename(po.localPkg())
if sigresult == 0:

33
SOURCES/BZ-1347813-security-updates-count.patch

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
commit 5820dcdc3e6f9bf16e2c42d2bf37d4cbd16064dc
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Thu Jul 21 20:38:28 2016 +0200

Fix count of applicable security updates. BZ 1347813

diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index 7abe332..5dcd7df 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -445,7 +445,6 @@ def exclude_updates(base, filters=None):
pkgs = base.pkgSack.returnPackages()
name2tup = _get_name2oldpkgtup(base)
- cnt = 0
pkgs_to_del = []
for pkg in pkgs:
name = pkg.name
@@ -453,11 +452,13 @@ def exclude_updates(base, filters=None):
not _ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
pkgs_to_del.append(pkg.name)
continue
- cnt += 1
if pkgs_to_del:
for p in base.doPackageLists(pkgnarrow='available', patterns=pkgs_to_del, showdups=True).available:
ysp_del_pkg(p)
+ cnt = len(base.doPackageLists(pkgnarrow='updates').updates) + \
+ len(base.doPackageLists(pkgnarrow='obsoletes').obsoletes)
+
_ysp_chk_used_map(used_map, lambda x: base.verbose_logger.warn("%s", x))
if cnt:

220
SOURCES/BZ-1348995-ship-comps-rng-schema.patch

@ -0,0 +1,220 @@ @@ -0,0 +1,220 @@
diff -up yum-3.4.3/docs/comps.rng.orig yum-3.4.3/docs/comps.rng
--- yum-3.4.3/docs/comps.rng.orig 2011-06-28 22:27:22.000000000 +0200
+++ yum-3.4.3/docs/comps.rng 2016-06-30 14:30:03.980476903 +0200
@@ -21,14 +21,22 @@
<ref name="group"/>
</oneOrMore>
<zeroOrMore>
+ <ref name="environment"/>
+ </zeroOrMore>
+ <zeroOrMore>
<ref name="category"/>
</zeroOrMore>
- <optional>
- <interleave><!-- We don't care what order these are in -->
+ <interleave><!-- We don't care what order these are in -->
+ <optional>
<ref name="whiteout"/>
+ </optional>
+ <optional>
<ref name="blacklist"/>
- </interleave>
- </optional>
+ </optional>
+ <optional>
+ <ref name="langpacks"/>
+ </optional>
+ </interleave>
</element>
</define>
<define name="group">
@@ -37,14 +45,18 @@
<a:documentation>This defines a package group.</a:documentation>
<interleave>
<ref name="id"/>
- <element name="default" a:defaultValue="true">
- <a:documentation>Should the group be enabled by default?</a:documentation>
- <ref name="boolean"/>
- </element>
- <element name="uservisible" a:defaultValue="true">
- <a:documentation>Should the group be visible to users?</a:documentation>
- <ref name="boolean"/>
- </element>
+ <optional>
+ <element name="default" a:defaultValue="true">
+ <a:documentation>Should the group be enabled by default?</a:documentation>
+ <ref name="boolean"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="uservisible" a:defaultValue="true">
+ <a:documentation>Should the group be visible to users?</a:documentation>
+ <ref name="boolean"/>
+ </element>
+ </optional>
<optional>
<element name="display_order">
<ref name="positiveInteger"/>
@@ -72,6 +84,9 @@
<oneOrMore>
<ref name="groupreq"/>
</oneOrMore>
+ <zeroOrMore>
+ <ref name="metapkg"/>
+ </zeroOrMore>
</element>
</define>
<define name="groupreq">
@@ -79,23 +94,39 @@
<ref name="groupname"/>
</element>
</define>
+ <define name="metapkg">
+ <element name="metapkg">
+ <ref name="packagename"/>
+ <optional>
+ <attribute name="type">
+ <choice>
+ <value>mandatory</value>
+ <value>default</value>
+ <value>optional</value>
+ </choice>
+ </attribute>
+ </optional>
+ </element>
+ </define>
<define name="packagelist">
<element name="packagelist">
- <oneOrMore>
+ <zeroOrMore>
<ref name="packagereq"/>
- </oneOrMore>
+ </zeroOrMore>
</element>
</define>
<define name="packagereq">
<element name="packagereq">
<choice>
- <attribute name="type" a:defaultValue="optional">
- <choice>
- <value>mandatory</value>
- <value>default</value>
- <value>optional</value>
- </choice>
- </attribute>
+ <optional>
+ <attribute name="type" a:defaultValue="optional">
+ <choice>
+ <value>mandatory</value>
+ <value>default</value>
+ <value>optional</value>
+ </choice>
+ </attribute>
+ </optional>
<group>
<attribute name="type" a:defaultValue="conditional">
<choice>
@@ -112,9 +143,30 @@
<ref name="boolean"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="arch">
+ <ref name="string"/>
+ </attribute>
+ </optional>
<ref name="packagename"/>
</element>
</define>
+ <define name="environment">
+ <element name="environment">
+ <interleave>
+ <ref name="id"/>
+ <optional>
+ <element name="display_order">
+ <ref name="positiveInteger"/>
+ </element>
+ </optional>
+ <ref name="grouplist"/>
+ <optional>
+ <ref name="optionlist"/>
+ </optional>
+ </interleave>
+ </element>
+ </define>
<define name="category">
<element name="category">
<interleave>
@@ -135,9 +187,21 @@
</oneOrMore>
</element>
</define>
+ <define name="optionlist">
+ <element name="optionlist">
+ <oneOrMore>
+ <ref name="groupid"/>
+ </oneOrMore>
+ </element>
+ </define>
<define name="groupid">
<element name="groupid">
<ref name="string"/>
+ <optional>
+ <attribute name="default" a:defaultValue="false">
+ <ref name="boolean"/>
+ </attribute>
+ </optional>
</element>
</define>
<define name="id">
@@ -182,6 +246,29 @@
</group>
</choice>
</define>
+ <define name="langpacks">
+ <a:documentation>
+ The "langpacks" item is a list of package-to-langpack mappings used
+ by the yum-langpacks plugin.
+
+ An example is:
+ &lt;match name="foo" install="foo-lang-%s"&gt;
+ When the 'foo' package is installed, the 'foo-lang-(language code)' package
+ will be installed for any configured languages.
+ </a:documentation>
+ <element name="langpacks">
+ <zeroOrMore>
+ <element name="match">
+ <attribute name="name">
+ <ref name="string"/>
+ </attribute>
+ <attribute name="install">
+ <ref name="string"/>
+ </attribute>
+ </element>
+ </zeroOrMore>
+ </element>
+ </define>
<define name="blacklist">
<a:documentation>
The "blacklist" is a list of packages that will be *removed* if found
@@ -257,7 +344,7 @@
<data type="string"/>
</define>
<define name="ID">
- <data type="ID"/>
+ <data type="string"/>
</define>
<!-- Should be a regexp -->
<define name="locale">
diff -up yum-3.4.3/yum.spec.orig yum-3.4.3/yum.spec
--- yum-3.4.3/yum.spec.orig 2016-06-30 14:30:03.980476903 +0200
+++ yum-3.4.3/yum.spec 2016-06-30 14:30:35.545325463 +0200
@@ -347,7 +347,7 @@ exit 0
%files -f %{name}.lang
%defattr(-, root, root, -)
-%doc README AUTHORS COPYING TODO INSTALL ChangeLog PLUGINS
+%doc README AUTHORS COPYING TODO INSTALL ChangeLog PLUGINS docs/comps.rng
%if %{move_yum_conf_back}
%config(noreplace) %{_sysconfdir}/yum.conf
%dir %{_sysconfdir}/yum.repos.d

48
SOURCES/BZ-1352585-detect-installed-provide.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
commit ed2a41fe646a1dcfc4f216f8babf25f93fde40e3
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Fri Feb 3 18:24:37 2017 +0100

Detect installed virtual provide in install(). BZ 1352585
Normally, when the user tries to install something that's already
installed, we exit gracefully with 0. However, that's not the case if
what we're looking for is a provide that, despite being installed, is
not available in any of the enabled repos, in which case we error out.
This commit makes sure we exit gracefully in that case too.
The old code path for "yum install foo" looks like this:
1) Look for foo in pkgSack
2) If no success, look for a package in pkgSack providing foo
3) If no success, look for foo in rpmdb
4) If no success, error out with "No package foo available." and exit
code 1
What we're adding with this commit is the following in between 3 and 4:
- If no success, look for a package in rpmdb providing foo
Note that we only search for the provide in pkgSack if the kwarg
'pattern' is set, so let's adhere to this with the newly added rpmdb
search too.

diff --git a/yum/__init__.py b/yum/__init__.py
index 9780d96..451b2b8 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -4910,8 +4910,14 @@ much more problems).
# Do we still want to return errors here?
# We don't in the cases below, so I didn't here...
if 'pattern' in kwargs:
- pkgs = self.rpmdb.returnPackages(patterns=[kwargs['pattern']],
+ arg = kwargs['pattern']
+ pkgs = self.rpmdb.returnPackages(patterns=[arg],
ignore_case=False)
+ if not pkgs:
+ self.verbose_logger.debug(
+ _('Checking for installed virtual provide or file-provide for %s'),
+ arg)
+ pkgs = self.returnInstalledPackagesByDep(arg)
if 'name' in kwargs:
pkgs = self.rpmdb.searchNevra(name=kwargs['name'])
if 'pkgtup' in kwargs:

78
SOURCES/BZ-1356797-silent-exception.patch

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
commit c8c4065931bec55e9b2eb0f16a97376e8650846b
Author: Radek Vykydal <rvykydal@redhat.com>
Date: Wed Aug 10 11:10:58 2016 +0200

Report __del__ RepoError exceptions into log instead of stderr (#1356797)
Resolves: rhbz#1356797
So it does not clutter text UI of clients like Anaconda.

diff --git a/yum/__init__.py b/yum/__init__.py
index 57e1dfe..9e38320 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -234,11 +234,14 @@ class YumBase(depsolve.Depsolve):
self.updateinfo_filters = {}
def __del__(self):
- self.close()
- self.closeRpmDB()
- self.doUnlock()
- # call cleanup callbacks
- for cb in self._cleanup: cb()
+ try:
+ self.close()
+ self.closeRpmDB()
+ self.doUnlock()
+ # call cleanup callbacks
+ for cb in self._cleanup: cb()
+ except Errors.RepoError, e:
+ self.verbose_logger.debug("Exception %s %s in %s ignored" % (repr(e), str(e), self.__del__))
def close(self):
"""Close the history and repo objects."""
diff --git a/yum/repos.py b/yum/repos.py
index a0ef28c..017527a 100644
--- a/yum/repos.py
+++ b/yum/repos.py
@@ -161,7 +161,10 @@ class RepoStorage:
return str(self.repos.keys())
def __del__(self):
- self.close()
+ try:
+ self.close()
+ except Errors.RepoError, e:
+ self.logger.debug("Exception %s %s in %s ignored" % (repr(e), str(e), self.__del__))
def close(self):
for repo in self.repos.values():
@@ -423,7 +426,10 @@ class Repository:
return hash(self.id)
def __del__(self):
- self.close()
+ try:
+ self.close()
+ except Errors.RepoError, e:
+ self.logger.debug("Exception %s %s in %s ignored" % (repr(e), str(e), self.__del__))
def _ui_id(self):
""" Show self.id, so we can use it and override it. """
diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index 9c3d274..2db8faf 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -114,7 +114,10 @@ class YumPackageSack(packageSack.PackageSack):
self.added = {}
def __del__(self):
- self.close()
+ try:
+ self.close()
+ except Errors.RepoError, e:
+ verbose_logger.debug("Exception %s %s in %s ignored" % (repr(e), str(e), self.__del__))
def close(self):
self.added = {}

34
SOURCES/BZ-1357083-clean-all-add-hint-rm-rf.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
commit 01a6780fd310cbf0027e98fad97aca324f952196
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Thu Mar 9 14:02:25 2017 +0100

Add hint about rm -rf for yum clean all. BZ 1357083

diff --git a/cli.py b/cli.py
index 862992b..5f7c4ae 100755
--- a/cli.py
+++ b/cli.py
@@ -1718,6 +1718,23 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
if 'all' in userlist:
self.verbose_logger.log(yum.logginglevels.INFO_2,
_('Cleaning up everything'))
+
+ # Print a "maybe you want rm -rf" hint to compensate for the fact
+ # that yum clean all is often misunderstood. Don't do that,
+ # however, if cachedir is non-default as we would have to replace
+ # arbitrary yum vars with * and that could produce a harmful
+ # command, e.g. for /mydata/$myvar we would say rm -rf /mydata/*
+ cachedir = self.conf.cachedir
+ if cachedir.startswith(('/var/cache/yum', '/var/tmp/yum-')):
+ # Take just the first 3 path components
+ rmdir = '/'.join(cachedir.split('/')[:4])
+ self.verbose_logger.log(
+ yum.logginglevels.INFO_2,
+ _('Maybe you want: rm -rf %s, to also free up space taken '
+ 'by orphaned data from disabled or removed repos'
+ % rmdir),
+ )
+
pkgcode, pkgresults = self.cleanPackages()
hdrcode, hdrresults = self.cleanHeaders()
xmlcode, xmlresults = self.cleanMetadata()

11
SOURCES/BZ-1358492-installonly-kernel.patch

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
diff -up yum-3.4.3/yum/config.py.old yum-3.4.3/yum/config.py
--- yum-3.4.3/yum/config.py.old 2017-10-06 13:24:25.014855429 +0200
+++ yum-3.4.3/yum/config.py 2017-10-06 13:36:38.602637131 +0200
@@ -755,6 +755,7 @@ class YumConf(StartupConf):
username = Option()
password = Option()
installonlypkgs = ListOption(['kernel', 'kernel-bigmem',
+ 'installonlypkg(kernel)',
'installonlypkg(kernel-module)',
'installonlypkg(vm)',
'kernel-enterprise','kernel-smp', 'kernel-debug',

63
SOURCES/BZ-1361609-improve-exactarchlist-opt.patch

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2017-10-31 17:11:01.730922455 +0100
+++ yum-3.4.3/docs/yum.conf.5 2017-10-31 17:14:00.544379686 +0100
@@ -221,6 +221,18 @@ List of package names that are kernels.
updating of kernel packages and should be removed out in the yum 2.1 series.
.IP
+\fBexactarchlist\fR
+List of packages that should never change archs in an update.
+That means, if a package has a newer version available which is for a different
+compatible arch, yum will not consider that version an update if the package
+name is in this list.
+For example, on x86_64, foo-1.x86_64 won't be updated to foo-2.i686 if foo is
+in this list.
+Kernels in particular fall into this category.
+Shell globs using wildcards (eg. * and ?) are allowed.
+Default is an empty list.
+
+.IP
\fBshowdupesfromrepos\fR
Either `0' or `1'. Set to `1' if you wish to show any duplicate packages from
any repository, from package listings like the info or list commands. Set
diff -up yum-3.4.3/yum/config.py.orig yum-3.4.3/yum/config.py
--- yum-3.4.3/yum/config.py.orig 2017-10-31 17:11:01.729922458 +0100
+++ yum-3.4.3/yum/config.py 2017-10-31 17:12:46.513604398 +0100
@@ -42,6 +42,7 @@ import rpmUtils.miscutils
import Errors
import types
from misc import get_uuid, read_in_items_from_dot_dir
+import fnmatch
# Alter/patch these to change the default checking...
__pkgs_gpgcheck_default__ = False
@@ -284,6 +285,20 @@ class UrlListOption(ListOption):
return out
+class WildListOption(ListOption):
+ """An option containing a list of strings that supports shell-style
+ wildcard matching in membership test operations."""
+
+ def parse(self, s):
+ class WildList(list):
+ def __contains__(self, item):
+ if not isinstance(item, basestring):
+ return False
+ return any(fnmatch.fnmatch(item, p) for p in self)
+ patterns = super(WildListOption, self).parse(s)
+ return WildList(patterns)
+
+
class IntOption(Option):
"""An option representing an integer value."""
@@ -769,7 +784,7 @@ class YumConf(StartupConf):
names_of_0=["0", "<off>"])
kernelpkgnames = ListOption(['kernel','kernel-smp', 'kernel-enterprise',
'kernel-bigmem', 'kernel-BOOT', 'kernel-PAE', 'kernel-PAE-debug'])
- exactarchlist = ListOption(__exactarchlist_default__)
+ exactarchlist = WildListOption(__exactarchlist_default__)
tsflags = ListOption()
override_install_langs = Option()

98
SOURCES/BZ-1369389-dont-recommend-makecache-if-running.patch

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
commit 79591f49db4faec56a846ddf16a77004b8579ee7
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Thu Dec 15 16:23:10 2016 +0100

Don't recommend makecache if just running. BZ 1369389
Also includes any other commands that would result in all repos obeying
metadata_expire such as "yum install" (depending on the actual value of
metadata_expire_filter).

diff --git a/cli.py b/cli.py
index 54a2e81..862992b 100755
--- a/cli.py
+++ b/cli.py
@@ -450,11 +450,21 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
if not ts_min:
cacheReq = 'write'
- elif warning and (time.time() - ts_max) > (60 * 60 * 24 * 14):
- self.logger.warning(_("Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast"))
+ all_obey = True
for repo in self.repos.sort():
repo._metadata_cache_req = cacheReq
+ if repo._matchExpireFilter():
+ all_obey = False
+
+ if warning and ts_min and (time.time() - ts_max) > (60 * 60 * 24 * 14):
+ # The warning makes no sense if we're already running a command
+ # that requires current repodata across all repos (such as "yum
+ # makecache" or others, depending on metadata_expire_filter), so
+ # don't give it if that's the case.
+ if all_obey:
+ return
+ self.logger.warning(_("Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast"))
def _shell_history_write(self):
if not hasattr(self, '_shell_history_cmds'):
diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index c6bed82..0c63de3 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -1145,33 +1145,39 @@ Insufficient space in download directory %s
self._metadataCurrent = False
return self._metadataCurrent
- def withinCacheAge(self, myfile, expiration_time, expire_req_filter=True):
- """check if any file is older than a certain amount of time. Used for
- the cachecookie and the mirrorlist
- return True if w/i the expiration time limit
- false if the time limit has expired
-
- Additionally compare the file to age of the newest .repo or yum.conf
- file. If any of them are newer then invalidate the cache
- """
-
+ def _matchExpireFilter(self):
+ """Return whether cache_req matches metadata_expire_filter."""
# Never/write means we just skip this...
- if (expire_req_filter and hasattr(self, '_metadata_cache_req') and
- self._metadata_cache_req.startswith("read-only:") and
- self.metadata_expire_filter.startswith("read-only:")):
+ if (hasattr(self, '_metadata_cache_req') and
+ self._metadata_cache_req.startswith("read-only:") and
+ self.metadata_expire_filter.startswith("read-only:")):
cache_filt = self.metadata_expire_filter[len("read-only:"):]
cache_req = self._metadata_cache_req[len("read-only:"):]
if cache_filt == 'future':
assert cache_req in ('past', 'present', 'future')
- expiration_time = -1
+ return True
if cache_filt == 'present':
if cache_req in ('past', 'present'):
- expiration_time = -1
+ return True
if cache_filt == 'past':
if cache_req == 'past':
- expiration_time = -1
+ return True
+ return False
+
+ def withinCacheAge(self, myfile, expiration_time, expire_req_filter=True):
+ """check if any file is older than a certain amount of time. Used for
+ the cachecookie and the mirrorlist
+ return True if w/i the expiration time limit
+ false if the time limit has expired
+
+ Additionally compare the file to age of the newest .repo or yum.conf
+ file. If any of them are newer then invalidate the cache
+ """
+
+ if expire_req_filter and self._matchExpireFilter():
+ expiration_time = -1
# -1 is special and should never get refreshed
if expiration_time == -1 and os.path.exists(myfile):

26
SOURCES/BZ-1370134-yum-check-ignore-self-conflicts.patch

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
commit 1ff69afbb78e9303a0d9859d941371eaedbb6842
Author: James Antill <james@and.org>
Date: Mon Sep 22 16:22:42 2014 -0400

Have "yum check" ignore self conflicts.

diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 2d718c1..229e1a1 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -1576,6 +1576,15 @@ class RPMDBPackageSack(PackageSackBase):
(req, flags, ver) = creq
res = self.getProvides(req, flags, ver)
+
+ # Filter this pkg out, as self conflicts are allowed.
+ nres = {}
+ for conflicting_po in res:
+ if conflicting_po.pkgtup[0] == pkg.pkgtup[0] and conflicting_po.pkgtup[2:] == pkg.pkgtup[2:]:
+ continue
+ nres[conflicting_po] = res[conflicting_po]
+ res = nres
+
if not res:
continue
flags = yum.depsolve.flags.get(flags, flags)

20
SOURCES/BZ-1377328-_metadata_cache_req.patch

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
commit 673ceee5f3d32fc6397e9a280ac18926e82ac152
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Sep 19 17:38:08 2016 +0200

Check for _metadata_cache_req properly.

diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index 2db8faf..47f950b 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -1473,7 +1473,8 @@ Insufficient space in download directory %s
else:
result = self._getFileRepoXML(local, text)
if result is None:
- if self.skip_if_unavailable and self._metadata_cache_req in ('write', 'read-only:future'):
+ if (self.skip_if_unavailable and hasattr(self, '_metadata_cache_req')
+ and self._metadata_cache_req in ('write', 'read-only:future')):
# Since skip_if_unavailable=True, we can just disable this repo
raise Errors.RepoError, "Can't download repomd.xml for %s" % self.ui_id

19
SOURCES/BZ-1386597-obsoletes-man-page.patch

@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
commit e9c88f76e0594d5c52ebb08f4c68003cad2c6e67
Author: Jaroslav Mracek <jmracek@redhat.com>
Date: Wed Oct 19 11:28:01 2016 +0200

Minor fix in doc of check command

diff --git a/docs/yum.8 b/docs/yum.8
index efaa061..a4b953d 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -784,7 +784,7 @@ included so you can easily see the space used/saved and any other changes.
.IP
.IP "\fBcheck\fP"
Checks the local rpmdb and produces information on any problems it finds. You
-can pass the check command the arguments "dependencies", "duplicates", "obsoletes" or "provides",
+can pass the check command the arguments "dependencies", "duplicates", "obsoleted" or "provides",
to limit the checking that is performed (the default is "all" which does all).
.IP

24
SOURCES/BZ-1389816-include-repoid-in-timestamp-error.patch

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
commit 5a836edd592fc0adf2e1bb3883387e48cf77f548
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Mon Jan 2 12:40:46 2017 +0100

Include repo-id in repomd.xml timestamp error. BZ 1389816

diff --git a/yum/yumRepo.py b/yum/yumRepo.py
index c6bed82..419545d 100644
--- a/yum/yumRepo.py
+++ b/yum/yumRepo.py
@@ -1378,10 +1378,11 @@ Insufficient space in download directory %s
if (self.timestamp_check and
old_repo_XML.timestamp > self.repoXML.timestamp):
- logger.warning("Not using downloaded repomd.xml because it is "
+ logger.warning("Not using downloaded %s/repomd.xml because it is "
"older than what we have:\n"
" Current : %s\n Downloaded: %s" %
- (time.ctime(old_repo_XML.timestamp),
+ (self.id,
+ time.ctime(old_repo_XML.timestamp),
time.ctime(self.repoXML.timestamp)))
return False
return True

69
SOURCES/BZ-1391507-fix-filelist-queries-for-dup-pkgs.patch

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
diff -up yum-3.4.3/yum/sqlitesack.py.orig yum-3.4.3/yum/sqlitesack.py
--- yum-3.4.3/yum/sqlitesack.py.orig 2017-02-08 18:13:03.646086042 +0100
+++ yum-3.4.3/yum/sqlitesack.py 2017-02-08 18:13:16.270073910 +0100
@@ -173,6 +173,21 @@ def _excluder_match(excluder, match, reg
return False
+def _deduplicate(cur, field):
+ """Eliminate duplicate rows from cursor based on field.
+
+ Assuming the result set can be divided into one or more equivalent groups
+ of rows based on the given field, this wrapper will yield rows from only
+ one of the groups, avoiding duplicates.
+ """
+ first_val = None
+ for ob in cur:
+ if first_val is None:
+ first_val = ob[field]
+ elif ob[field] != first_val:
+ continue
+ yield ob
+
class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
def __init__(self, repo, db_obj):
@@ -283,6 +298,14 @@ class YumAvailablePackageSqlite(YumAvail
setattr(self, varname, value)
return value
+
+ # Note that we use pkgId instead of pkgKey to filter the files and
+ # changelog entries since we can't guarantee that pkgKeys in primarydb and
+ # filelistsdb are in sync (since self.pkgKey is obtained from primarydb).
+ #
+ # Also, because of that, we must make sure not to return duplicate entries
+ # in case we have some duplicate packages (i.e. same checksums), so we use
+ # _deduplicate().
def _loadFiles(self):
if self._loadedfiles:
@@ -293,10 +316,10 @@ class YumAvailablePackageSqlite(YumAvail
#FIXME - this should be try, excepting
self.sack.populate(self.repo, mdtype='filelists')
cur = self._sql_MD('filelists',
- "SELECT dirname, filetypes, filenames " \
+ "SELECT pkgKey, dirname, filetypes, filenames " \
"FROM filelist JOIN packages USING(pkgKey) " \
"WHERE packages.pkgId = ?", (self.pkgId,))
- for ob in cur:
+ for ob in _deduplicate(cur, 'pkgKey'):
dirname = ob['dirname']
if dirname == '.':
dirname = ''
@@ -323,13 +346,13 @@ class YumAvailablePackageSqlite(YumAvail
self._changelog = result
return
cur = self._sql_MD('other',
- "SELECT date, author, changelog " \
+ "SELECT pkgKey, date, author, changelog " \
"FROM changelog JOIN packages USING(pkgKey) " \
"WHERE pkgId = ? ORDER BY date DESC",
(self.pkgId,))
# Check count(pkgId) here, the same way we do in searchFiles()?
# Failure mode is much less of a problem.
- for ob in cur:
+ for ob in _deduplicate(cur, 'pkgKey'):
# Note: Atm. rpm only does days, where (60 * 60 * 24) == 86400
# and we have the hack in _dump_changelog() to keep the
# order the same, so this is a quick way to get rid of

64
SOURCES/BZ-1397829-fix-reget-simple-md-fnames.patch

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
diff -up yum-3.4.3/yum/yumRepo.py.orig yum-3.4.3/yum/yumRepo.py
--- yum-3.4.3/yum/yumRepo.py.orig 2017-03-10 14:16:36.769105433 +0100
+++ yum-3.4.3/yum/yumRepo.py 2017-03-10 14:16:39.457093071 +0100
@@ -358,6 +358,7 @@ class YumRepository(Repository, config.R
# holder for stuff we've grabbed
self.retrieved = { 'primary':0, 'filelists':0, 'other':0, 'group':0,
'updateinfo':0, 'prestodelta':0}
+ self._preloaded_repomd = False
# callbacks
self.callback = None # for the grabber
@@ -743,7 +744,8 @@ class YumRepository(Repository, config.R
# if we're using a cachedir that's not the system one, copy over these
# basic items from the system one
- self._preload_md_from_system_cache('repomd.xml')
+ if self._preload_md_from_system_cache('repomd.xml'):
+ self._preloaded_repomd = True
self._preload_md_from_system_cache('cachecookie')
self._preload_md_from_system_cache('mirrorlist.txt')
self._preload_md_from_system_cache('metalink.xml')
@@ -1829,6 +1831,12 @@ Insufficient space in download directory
# got it, move along
return local
+ # Having preloaded the repomd means we should first try preloading this
+ # file as well (forcing it this way is only needed when dealing with
+ # simple filenames).
+ if self._preloaded_repomd:
+ misc.unlink_f(local)
+
if (os.path.exists(local) or
self._preload_md_from_system_cache(os.path.basename(local))):
if self._checkMD(local, mdtype, check_can_fail=True):
@@ -1844,6 +1852,20 @@ Insufficient space in download directory
msg = "Caching enabled but no local cache of %s from %s" % (local, self.ui_id)
raise Errors.RepoError, msg
+ # Given the file already exists, is it a partial download of thisdata
+ # that we can try to reget? With unique filenames, that's always.
+ # With simple filenames, use the old expected checksum to verify
+ # (assuming the existing file or part represents the old data but it
+ # usually does).
+ partial = True
+ orepomd = self._oldRepoMDData.get('old_repo_XML')
+ if orepomd is not None:
+ odata = orepomd.repoData.get(mdtype)
+ if odata is not None:
+ ofname = os.path.basename(odata.location[1])
+ partial = (fname != ofname or
+ thisdata.checksum == odata.checksum)
+
try:
def checkfunc(obj):
try:
@@ -1856,7 +1878,7 @@ Insufficient space in download directory
raise
self.retrieved[mdtype] = 1
text = "%s/%s" % (self.ui_id, mdtype)
- if thisdata.size is None:
+ if thisdata.size is None or not partial:
reget = None
else:
reget = 'simple'

76
SOURCES/BZ-1399628-updateinfo-fix-wrong-pkg-count.patch

@ -0,0 +1,76 @@ @@ -0,0 +1,76 @@
commit 9474b6a7be57cd1c83da4a5db3fc0f48c61f6056
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Wed Oct 26 13:42:04 2016 +0200

Filter duplicate packages from different repos in doPackageLists(pkgnarrow='obsoletes').

diff --git a/yum/__init__.py b/yum/__init__.py
index 9e38320..9780d96 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -3109,9 +3109,13 @@ much more problems).
pkgs = self.pkgSack.searchNevra(name=n, arch=a, ver=v, rel=r, epoch=e)
pkgs = misc.filter_pkgs_repoid(pkgs, repoid)
instpo = self.getInstalledPackageObject(instTup)
- for po in pkgs:
- obsoletes.append(po)
- obsoletesTuples.append((po, instpo))
+ if len(pkgs) > 1:
+ self.verbose_logger.log(logginglevels.DEBUG_1,
+ _('More than one identical match in sack for %s'),
+ pkgs[0])
+ if len(pkgs) >= 1:
+ obsoletes.append(pkgs[0])
+ obsoletesTuples.append((pkgs[0], instpo))
if patterns:
exactmatch, matched, unmatched = \
parsePackages(obsoletes, patterns, casematch=not ignore_case)

commit 400e248d3334d54fcf98d106d1cd84acae2e6e15
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Mon Oct 31 10:28:04 2016 +0100

Filter duplicates when counting security updates.

diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index 5dcd7df..35e4c0f 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -456,8 +456,8 @@ def exclude_updates(base, filters=None):
for p in base.doPackageLists(pkgnarrow='available', patterns=pkgs_to_del, showdups=True).available:
ysp_del_pkg(p)
- cnt = len(base.doPackageLists(pkgnarrow='updates').updates) + \
- len(base.doPackageLists(pkgnarrow='obsoletes').obsoletes)
+ cnt = len(set(base.doPackageLists(pkgnarrow='updates').updates + \
+ base.doPackageLists(pkgnarrow='obsoletes').obsoletes))
_ysp_chk_used_map(used_map, lambda x: base.verbose_logger.warn("%s", x))

commit 02753215c8e28dbc75aacff678c33343d0539b33
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Wed Feb 15 16:51:57 2017 +0100

updateinfo: filter pkg dupes from total count. BZ 1399628
This complements commit 400e248.

diff --git a/yum/updateinfo.py b/yum/updateinfo.py
index 35e4c0f..b6a42ea 100644
--- a/yum/updateinfo.py
+++ b/yum/updateinfo.py
@@ -436,11 +436,8 @@ def exclude_updates(base, filters=None):
used_map = _ysp_gen_used_map(opts)
- upds = base.doPackageLists(pkgnarrow='updates')
- tot = len(upds.updates)
- # In theory we don't need to do this in some cases, but meh.
- upds = base.doPackageLists(pkgnarrow='obsoletes')
- tot += len(upds.obsoletes)
+ tot = len(set(base.doPackageLists(pkgnarrow='updates').updates + \
+ base.doPackageLists(pkgnarrow='obsoletes').obsoletes))
pkgs = base.pkgSack.returnPackages()
name2tup = _get_name2oldpkgtup(base)

28
SOURCES/BZ-1411575-manpage-typo.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
commit cee73706e91911c74df7bdc57d822a3b993ecb71
Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
Date: Fri Oct 6 14:04:01 2017 +0200

Fix some typos in the manpage.

diff --git a/docs/yum.8 b/docs/yum.8
index a4b953d..b6961e7 100644
--- a/docs/yum.8
+++ b/docs/yum.8
@@ -247,7 +247,7 @@ the \fIClean Options\fP section below\&.
.IP "\fBmakecache\fP"
Is used to download and make usable all the metadata for the currently enabled
\fByum\fP repos. If the argument "fast" is passed, then we just try to make
-sure the repos. are current (much like "yum clean expire-cache").
+sure the repos are current (much like "yum clean expire-cache").
.IP
.IP "\fBgroups\fP"
A command, new in 3.4.2, that collects all the subcommands that act on groups
@@ -430,7 +430,7 @@ or \'all\' then the command will list those types of repos.
You can pass repo id or name arguments, or wildcards which to match against
both of those. However if the id or name matches exactly then the repo will
-be listed even if you are listing enabled repos. and it is disabled.
+be listed even if you are listing enabled repos and it is disabled.
In non-verbose mode the first column will start with a \'*\' if the repo. has
metalink data and the latest metadata is not local and will start with a

23
SOURCES/BZ-1411692-docs-conf-var-naming-rules.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2017-11-01 14:58:28.259740017 +0100
+++ yum-3.4.3/docs/yum.conf.5 2017-11-01 14:58:48.528648100 +0100
@@ -1356,8 +1356,17 @@ the same name. If the shell environment
configuration file variable will not be replaced.
.LP
-As of 3.2.28, any file in /etc/yum/vars is turned into a variable named after
-the filename (or overrides any of the above variables).
+When variable names are parsed in a string, all alphanumeric characters and
+underscores immediately following a $ sign are interpreted as part of a name.
+If a variable is undefined, it will not be replaced.
+For example, the strings $releasever-foo or $releasever/foo will be expanded
+with the $releasever value accordingly, whereas $releaseverfoo or
+$releasever_foo will not be expanded.
+
+As of 3.2.28, any properly named file in /etc/yum/vars is turned into
+a variable named after the filename (or overrides any of the above variables).
+Filenames may contain only alphanumeric characters and underscores
+and be in lowercase.
Note that no warnings/errors are given if the files are unreadable, so creating
files that only root can read may be confusing for users.

84
SOURCES/BZ-1432319-add-usercache-opt.patch

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
diff -up yum-3.4.3/cli.py.orig yum-3.4.3/cli.py
--- yum-3.4.3/cli.py.orig 2017-10-20 18:27:45.114593690 +0200
+++ yum-3.4.3/cli.py 2017-10-20 18:27:48.367578901 +0200
@@ -2275,8 +2275,10 @@ class YumOptionParser(OptionParser):
self.base.updateinfo_filters['cves'] = self._splitArg(opts.cves)
self.base.updateinfo_filters['sevs'] = self._splitArg(opts.sevs)
+ if not self.base.conf.usercache and os.geteuid() != 0:
+ self.base.conf.cache = 1
# Treat users like root as much as possible:
- if not self.base.setCacheDir():
+ elif not self.base.setCacheDir():
self.base.conf.cache = 1
if opts.cacheonly:
self.base.conf.cache = 1
diff -up yum-3.4.3/docs/yum.8.orig yum-3.4.3/docs/yum.8
--- yum-3.4.3/docs/yum.8.orig 2017-10-20 18:27:45.135593595 +0200
+++ yum-3.4.3/docs/yum.8 2017-10-20 18:27:48.368578897 +0200
@@ -835,8 +835,12 @@ Configuration Option: \fBrpmverbosity\fP
.IP "\fB\-R, \-\-randomwait=[time in minutes]\fP"
Sets the maximum amount of time yum will wait before performing a command \- it randomizes over the time.
.IP "\fB\-C, \-\-cacheonly\fP"
-Tells yum to run entirely from system cache - does not download or
-update any headers unless it has to to perform the requested action.
+Tells yum to run entirely from system cache; does not download or update
+metadata.
+When this is used by a non\-root user, yum will run entirely from user cache in
+$TMPDIR.
+This option doesn't stop yum from updating user cache from system cache locally
+if the latter is newer (this is always done when running as a user).
.IP "\fB\-\-version\fP"
Reports the \fByum\fP version number and installed package versions for
everything in history_record_packages (can be added to by plugins).
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2017-10-20 18:27:45.137593585 +0200
+++ yum-3.4.3/docs/yum.conf.5 2017-10-20 18:27:48.368578897 +0200
@@ -40,6 +40,19 @@ of headers and packages after successful
.br
.IP
+\fBusercache\fR
+Either `1' or `0'. Determines whether or not yum should store per-user cache in
+$TMPDIR.
+When set to `0', then whenever yum runs as a non\-root user,
+\fB\-\-cacheonly\fR is implied and system cache is used directly, and no new
+user cache is created in $TMPDIR.
+This can be used to prevent $TMPDIR from filling up if many users on the system
+often use yum and root tends to have up-to-date metadata that the users can
+rely on (they can still enable this feature with \fB\-\-setopt\fR if they
+wish).
+Default is `1' (user cache enabled).
+
+.IP
\fBreposdir\fR
A list of directories where yum should look for .repo files which define
repositories to use. Default is `/etc/yum.repos.d'. Each
diff -up yum-3.4.3/yum/config.py.orig yum-3.4.3/yum/config.py
--- yum-3.4.3/yum/config.py.orig 2017-10-20 18:27:45.136593590 +0200
+++ yum-3.4.3/yum/config.py 2017-10-20 18:27:48.369578892 +0200
@@ -742,6 +742,7 @@ class YumConf(StartupConf):
cachedir = Option('/var/cache/yum')
keepcache = BoolOption(True)
+ usercache = BoolOption(True)
logfile = Option('/var/log/yum.log')
reposdir = ListOption(['/etc/yum/repos.d', '/etc/yum.repos.d'])
diff -up yum-3.4.3/yummain.py.orig yum-3.4.3/yummain.py
--- yum-3.4.3/yummain.py.orig 2017-10-20 18:27:45.062593926 +0200
+++ yum-3.4.3/yummain.py 2017-10-20 18:27:48.369578892 +0200
@@ -71,7 +71,12 @@ def main(args):
def exRepoError(e):
# For RepoErrors ... help out by forcing new repodata next time.
# XXX: clean only the repo that has failed?
- base.cleanExpireCache()
+ try:
+ base.cleanExpireCache()
+ except Errors.YumBaseError:
+ # Let's not confuse the user further (they don't even know we tried
+ # the clean).
+ pass
msg = _("""\
One of the configured repositories failed (%(repo)s),

73
SOURCES/BZ-1451817-docs-improve-payload-gpgcheck-opt.patch

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
diff -up yum-3.4.3/docs/yum.conf.5.orig yum-3.4.3/docs/yum.conf.5
--- yum-3.4.3/docs/yum.conf.5.orig 2017-10-26 11:13:52.013324456 +0200
+++ yum-3.4.3/docs/yum.conf.5 2017-10-26 11:15:37.733858789 +0200
@@ -106,28 +106,34 @@ default for all repositories. The defaul
.IP
\fBpayload_gpgcheck\fR
-Either `1' or `0'. This tells yum whether or not it should also perform a GPG
-signature check on the payload (part of a package holding the actual files that
-comprise the package).
-
-By default, yum only performs GPG signature checks on package headers.
-Thus, if the payload data has been tampered with or corrupted, yum will fail in
-the middle of the transaction due to an RPM unpacking error, after some
-unverified scriptlets might have already run, and possibly leave the package in
-question partly installed.
-
-To prevent all of that, you can enable this option to extend the signature
-check to also include the payload, so that yum can avoid running the
-transaction in case of payload corruption.
-This slightly improves security, however at the expense of significantly
-increased transaction time, so you may want to only use this option when
-package corruption is a concern.
+Either `1' or `0'. This tells yum whether or not it should perform a v3
+signature check on packages when \fBgpgcheck\fR (or \fBlocalpkg_gpgcheck\fR for
+local packages) is enabled.
+
+There are two types of GPG signatures generated by rpm: v3 (on header+payload)
+and v4 (on header only). When rpm signs a package, it creates both types. Yum
+can verify any of them before the transaction, depending on which options are
+set. When \fBgpgcheck\fR is enabled and this option is disabled, yum will
+verify v4 signatures only. When both \fBgpgcheck\fR and this option are
+enabled, yum will verify both v4 and v3 signatures (equivalent to running "rpm
+\-\-checksig"). The same rules apply to local packages and the
+\fBlocalpkg_gpgcheck\fR option accordingly.
+
+Since the header contains sha256 digests of individual files in the payload (a
+gzip-compressed cpio archive of files used in the package), verifying the
+header signature (v4) is sufficient to ensure authenticity and integrity of the
+whole package. After rpm unpacks the payload, it moves the files to their
+destination paths one by one after they pass the digest check. If a file
+doesn't pass, it won't be moved and the transaction will abort. However,
+because no rollback is done in such a case, the package may end up in the
+partially installed state.
+
+By verifying v3 signatures, yum will detect payload tamper before the
+transaction. While this will slightly increase processing time for big
+transactions and/or packages, it will prevent such broken installs and enhance
+security.
-For this option to have effect, make sure to also enable gpgcheck (or
-localpkg_gpgcheck for local packages).
-
-When this option is set in the [main] section it sets the default for all
-repositories. The default is `0'.
+The default is `0'.
.IP
\fBskip_broken\fR
diff -up yum-3.4.3/rpmUtils/miscutils.py.orig yum-3.4.3/rpmUtils/miscutils.py
--- yum-3.4.3/rpmUtils/miscutils.py.orig 2017-10-26 11:13:49.637334921 +0200
+++ yum-3.4.3/rpmUtils/miscutils.py 2017-10-26 11:15:43.141834969 +0200
@@ -61,8 +61,8 @@ def compareVerOnly(v1, v2):
def checkSig(ts, package, payload=False):
"""Takes a transaction set and a package, check it's sigs.
- By default, only RPMv4 sigs (header-only) will be verified (faster). By
- setting payload to True, RPMv3 sigs (header+payload) will also be verified
+ By default, only v4 sigs (header-only) will be verified (faster). By
+ setting payload to True, v3 sigs (header+payload) will also be verified
(slower).
return 0 if they are all fine

50
SOURCES/BZ-1458841-preload-shared-libs.patch

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
diff -up yum-3.4.3/cli.py.orig yum-3.4.3/cli.py
--- yum-3.4.3/cli.py.orig 2017-06-29 17:44:53.784522557 +0200
+++ yum-3.4.3/cli.py 2017-06-29 17:46:16.249149700 +0200
@@ -28,6 +28,7 @@ import logging
import math
from optparse import OptionParser,OptionGroup,SUPPRESS_HELP
import rpm
+import ctypes
from weakref import proxy as weakref
@@ -779,6 +780,38 @@ class YumBaseCli(yum.YumBase, output.Yum
if self.conf.debuglevel < 2:
cb.display.output = False
+ # Whenever we upgrade a shared library (and its dependencies) which the
+ # yum process itself may dlopen() post-transaction (e.g. in a plugin
+ # hook), we may end up in a situation where the upgraded library and
+ # the pre-transaction version of a library it depends on which is ABI
+ # incompatible are loaded in memory at the same time, leading to
+ # unpredictable behavior and possibly a crash. Let's avoid that by
+ # preloading all such dynamically loaded libraries pre-transaction so
+ # that dlopen(), if called post-transaction, uses those instead of
+ # loading the newly installed versions.
+ preload = {
+ # Loaded by libcurl, see BZ#1458841
+ 'nss-sysinit': ['libnsssysinit.so'],
+ }
+ for pkg in preload:
+ # Only preload the libs if the package is actually installed and we
+ # are changing it with the transaction
+ if not self.tsInfo.matchNaevr(name=pkg) or \
+ not self.rpmdb.searchNevra(name=pkg):
+ continue
+ for lib in preload[pkg]:
+ try:
+ ctypes.cdll.LoadLibrary(lib)
+ self.verbose_logger.log(
+ yum.logginglevels.DEBUG_4,
+ _('Preloaded shared library %s') % lib
+ )
+ except Exception as e:
+ self.verbose_logger.log(
+ yum.logginglevels.DEBUG_4,
+ _('Could not preload shared library %s: %s') % (lib, e)
+ )
+
self.verbose_logger.log(yum.logginglevels.INFO_2, _('Running transaction'))
resultobject = self.runTransaction(cb=cb)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save