|
|
e5ee8d |
commit a7d50db151a2bfef09b3004c7afae5e1eed651e3
|
|
|
e5ee8d |
Author: Michal Domonkos <mdomonko@redhat.com>
|
|
|
e5ee8d |
Date: Tue Jun 19 10:08:47 2018 +0200
|
|
|
e5ee8d |
|
|
|
e5ee8d |
gpgkey: retry on broken redirects. BZ 1520454
|
|
|
e5ee8d |
|
|
|
e5ee8d |
This adds support for MirrorManager2 URLs in gpgkey (see the docstring
|
|
|
e5ee8d |
for details).
|
|
|
e5ee8d |
|
|
|
e5ee8d |
diff --git a/yum/__init__.py b/yum/__init__.py
|
|
|
e5ee8d |
index a156a6a6..a2965a2d 100644
|
|
|
e5ee8d |
--- a/yum/__init__.py
|
|
|
e5ee8d |
+++ b/yum/__init__.py
|
|
|
e5ee8d |
@@ -6116,6 +6116,31 @@ much more problems).
|
|
|
e5ee8d |
self.conf.obsoletes = old_conf_obs
|
|
|
e5ee8d |
return done
|
|
|
e5ee8d |
|
|
|
e5ee8d |
+ def redirect_failure_callback(self, data):
|
|
|
e5ee8d |
+ """Failure callback for urlgrabber to force a retry if we time out
|
|
|
e5ee8d |
+ (code 12) or error out (code 14) after being redirected (since these
|
|
|
e5ee8d |
+ codes are not in opts.retrycodes).
|
|
|
e5ee8d |
+
|
|
|
e5ee8d |
+ This allows for failovers if the URL points to a MirrorManager2 (such
|
|
|
e5ee8d |
+ as download.fedoraproject.org). If the mirror it redirects to is down
|
|
|
e5ee8d |
+ for some reason, this will ensure that we try again, hopefully getting
|
|
|
e5ee8d |
+ a mirror that works.
|
|
|
e5ee8d |
+ """
|
|
|
e5ee8d |
+ e = data.exception
|
|
|
e5ee8d |
+ url_initial = data.url
|
|
|
e5ee8d |
+ url_actual = e.url
|
|
|
e5ee8d |
+ if (e.errno not in (12, 14) or url_initial == url_actual):
|
|
|
e5ee8d |
+ # Not a timeout/HTTPError, or there was no redirect, so leave it up
|
|
|
e5ee8d |
+ # to urlgrabber
|
|
|
e5ee8d |
+ return
|
|
|
e5ee8d |
+ if e.errno == 12:
|
|
|
e5ee8d |
+ msg = _('Timeout on %s, trying again') % url_actual
|
|
|
e5ee8d |
+ else:
|
|
|
e5ee8d |
+ msg = _('Could not retrieve %s: %s, trying again') % (url_actual, e)
|
|
|
e5ee8d |
+ # Force a retry by hacking the errno so that it falls within retrycodes
|
|
|
e5ee8d |
+ e.errno = -1
|
|
|
e5ee8d |
+ self.logger.error(msg)
|
|
|
e5ee8d |
+
|
|
|
e5ee8d |
def _retrievePublicKey(self, keyurl, repo=None, getSig=True):
|
|
|
e5ee8d |
"""
|
|
|
e5ee8d |
Retrieve a key file
|
|
|
e5ee8d |
@@ -6123,6 +6148,7 @@ much more problems).
|
|
|
e5ee8d |
Returns a list of dicts with all the keyinfo
|
|
|
e5ee8d |
"""
|
|
|
e5ee8d |
key_installed = False
|
|
|
e5ee8d |
+ cb = self.redirect_failure_callback
|
|
|
e5ee8d |
|
|
|
e5ee8d |
msg = _('Retrieving key from %s') % keyurl
|
|
|
e5ee8d |
self.verbose_logger.log(logginglevels.INFO_2, msg)
|
|
|
e5ee8d |
@@ -6139,7 +6165,7 @@ much more problems).
|
|
|
e5ee8d |
# external callers should just update.
|
|
|
e5ee8d |
opts = repo._default_grabopts()
|
|
|
e5ee8d |
text = repo.id + '/gpgkey'
|
|
|
e5ee8d |
- rawkey = urlgrabber.urlread(url, **opts)
|
|
|
e5ee8d |
+ rawkey = urlgrabber.urlread(url, failure_callback=cb, **opts)
|
|
|
e5ee8d |
|
|
|
e5ee8d |
except urlgrabber.grabber.URLGrabError, e:
|
|
|
e5ee8d |
raise Errors.YumBaseError(_('GPG key retrieval failed: ') +
|
|
|
e5ee8d |
@@ -6155,7 +6181,7 @@ much more problems).
|
|
|
e5ee8d |
url = misc.to_utf8(keyurl + '.asc')
|
|
|
e5ee8d |
opts = repo._default_grabopts()
|
|
|
e5ee8d |
text = repo.id + '/gpgkeysig'
|
|
|
e5ee8d |
- sigfile = urlgrabber.urlopen(url, **opts)
|
|
|
e5ee8d |
+ sigfile = urlgrabber.urlopen(url, failure_callback=cb, **opts)
|
|
|
e5ee8d |
|
|
|
e5ee8d |
except urlgrabber.grabber.URLGrabError, e:
|
|
|
e5ee8d |
sigfile = None
|