Skip to content

Commit b1659b5

Browse files
authored
Retry URL downloads in runqemu.py (#185)
Introduce a `urlopen_retry()` wrapper that retries up to 4 times with exponential back-off. This avoids failing tests due to short network glitches on the Fedora/CentOS image servers. Replace the two non-context urlopen() calls with contexts.
1 parent a07fc9e commit b1659b5

1 file changed

Lines changed: 24 additions & 7 deletions

File tree

src/tox_lsr/test_scripts/runqemu.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
145163
def 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

150168
def 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

Comments
 (0)