basebuilder_pel7ppc64bebuilder0
7 years ago
110 changed files with 216461 additions and 0 deletions
@ -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 |
@ -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) |
@ -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 |
@ -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) |
||||
|
@ -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 \ |
@ -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']} |
@ -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. |
||||
|
@ -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 |
@ -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']] |
@ -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 |
File diff suppressed because it is too large
Load Diff
@ -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): |
File diff suppressed because it is too large
Load Diff
@ -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) |
@ -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)) |
@ -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 |
@ -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 |
||||
-- |
@ -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)): |
@ -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 |
||||
|
@ -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] |
@ -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 |
||||
|
@ -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')) |
@ -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 |
@ -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) |
||||
|
@ -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) |
@ -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() |
@ -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) |
@ -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 |
@ -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 |
@ -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]) |
||||
|
@ -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 |
||||
|
@ -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.) |
@ -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 |
@ -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, |
@ -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 |
@ -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 |
@ -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. |
||||
|
@ -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 |
@ -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): |
@ -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) |
@ -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 |
@ -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 |
@ -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) |
@ -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""" |
@ -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 |
@ -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) |
@ -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: |
@ -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, |
@ -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 |
@ -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" |
@ -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) |
@ -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 |
@ -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 |
||||
|
@ -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." |
@ -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)) |
||||
|
@ -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", |
@ -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 |
@ -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): |
@ -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). |
||||
|
@ -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() |
@ -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) |
@ -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 :). |
@ -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)) |
@ -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) |
@ -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)): |
@ -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 |
@ -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" |
@ -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 |
@ -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 |
||||
|
@ -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)) |
@ -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. |
@ -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 |
@ -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 |
@ -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] |
@ -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 |
@ -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 |
@ -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): |
@ -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. |
@ -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 = """ |
@ -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: |
@ -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: |
@ -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: |
||||
+ <match name="foo" install="foo-lang-%s"> |
||||
+ 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 |
@ -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: |
@ -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 = {} |
@ -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() |
@ -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', |
@ -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() |
||||
|
@ -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): |
@ -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) |
@ -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 |
||||
|
@ -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 |
@ -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 |
@ -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 |
@ -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' |
@ -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) |
@ -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 |
@ -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. |
@ -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), |
@ -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 |
@ -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…
Reference in new issue