@@ -142,14 +142,32 @@ def image_source_last_modified_by_file_metadata(path):
142142 )
143143
144144
145+ @contextmanager
146+ def urlopen_retry (url ):
147+ """Retry opening url up to 5 times."""
148+ for retry in range (1 , 5 ):
149+ try :
150+ yield urlopen (url )
151+ return
152+ except IOError as e :
153+ last_error = e
154+ msg = str (e )
155+ logging .warning (
156+ "Opening %s failed, retry #%i: %s" , url , retry , msg
157+ )
158+ time .sleep (retry * retry )
159+
160+ raise last_error
161+
162+
145163def origurl (path ):
146164 """Return the original URL that a given file was downloaded from."""
147165 return get_metadata_from_file (path , URL_XATTR )
148166
149167
150168def get_metadata_from_url (url , metadata_key ):
151169 """Get metadata from given url."""
152- with urlopen (url ) as url_response : # nosec
170+ with urlopen_retry (url ) as url_response : # nosec
153171 return url_response .getheader (metadata_key )
154172
155173
@@ -160,7 +178,7 @@ def get_inventory_script(inventory):
160178 os .environ ["TOX_WORK_DIR" ], "standard-inventory-qcow2"
161179 )
162180 try :
163- with urlopen (inventory ) as url_response : # nosec
181+ with urlopen_retry (inventory ) as url_response : # nosec
164182 with open (inventory_tempfile , "wb" ) as inf :
165183 shutil .copyfileobj (url_response , inf )
166184 os .chmod (inventory_tempfile , 0o777 ) # nosec
@@ -205,9 +223,8 @@ def fetch_image(url, cache, label):
205223
206224 image_tempfile = tempfile .NamedTemporaryFile (dir = cache , delete = False )
207225 try :
208- request = urlopen (url ) # nosec
209- shutil .copyfileobj (request , image_tempfile )
210- request .close ()
226+ with urlopen_retry (url ) as request : # nosec
227+ shutil .copyfileobj (request , image_tempfile )
211228 except Exception : # pylint: disable=broad-except
212229 logging .warning (traceback .format_exc ())
213230 os .unlink (image_tempfile .name )
@@ -286,8 +303,8 @@ def centoshtml2image(url, desiredarch):
286303 logging .error ("Could not determine CentOS version from %s" , url )
287304 return ""
288305
289- page = urlopen (url ) # nosec
290- tree = BeautifulSoup (page .read (), "html.parser" )
306+ with urlopen_retry (url ) as page : # nosec
307+ tree = BeautifulSoup (page .read (), "html.parser" )
291308 imagelist = [
292309 td .a ["href" ]
293310 for td in tree .find_all ("td" , class_ = "indexcolname" )
0 commit comments