Blame SOURCES/BZ-1520454-gpgkey-retry-broken-redirects.patch

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