Nejc Habjan 2 weeks ago committed by GitHub
commit 6950c3672e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,3 @@
---
minor_changes:
- Make HTTP status codes to retry during galaxy API calls configurable (https://github.com/ansible/ansible/pull/82246).

@ -1470,6 +1470,18 @@ GALAXY_REQUIRED_VALID_SIGNATURE_COUNT:
- The number of signatures that must be successful during GPG signature verification while installing or verifying collections.
- This should be a positive integer or all to indicate all signatures must successfully validate the collection.
- Prepend + to the value to fail if no valid signatures are found for the collection.
GALAXY_RETRY_HTTP_ERROR_CODES:
type: list
default:
- "429" # Too many requests
- "520" # Galaxy rate limit error code (Cloudflare unknown error)
- "502" # Common error from galaxy that may represent any number of transient backend issues
env:
- name: ANSIBLE_GALAXY_RETRY_HTTP_ERROR_CODES
ini:
- section: galaxy
key: retry_http_error_codes
description: List of HTTP Status error codes to retry on.
HOST_KEY_CHECKING:
# NOTE: constant not in use by ssh/paramiko plugins anymore, but they do support the same configuration sources
# TODO: check non ssh connection plugins for use/migration

@ -15,7 +15,6 @@ import tarfile
import time
import threading
from http import HTTPStatus
from http.client import BadStatusLine, IncompleteRead
from urllib.error import HTTPError, URLError
from urllib.parse import quote as urlquote, urlencode, urlparse, parse_qs, urljoin
@ -35,11 +34,6 @@ from ansible.utils.path import makedirs_safe
display = Display()
_CACHE_LOCK = threading.Lock()
COLLECTION_PAGE_SIZE = 100
RETRY_HTTP_ERROR_CODES = { # TODO: Allow user-configuration
HTTPStatus.TOO_MANY_REQUESTS,
520, # Galaxy rate limit error code (Cloudflare unknown error)
HTTPStatus.BAD_GATEWAY, # Common error from galaxy that may represent any number of transient backend issues
}
def cache_lock(func):
@ -54,7 +48,12 @@ def should_retry_error(exception):
# Note: cloud.redhat.com masks rate limit errors with 403 (Forbidden) error codes.
# Since 403 could reflect the actual problem (such as an expired token), we should
# not retry by default.
if isinstance(exception, GalaxyError) and exception.http_code in RETRY_HTTP_ERROR_CODES:
try:
retry_codes = [int(code) for code in C.GALAXY_RETRY_HTTP_ERROR_CODES]
except ValueError as e:
raise AnsibleError("Invalid value for HTTP retry code: %s. Only integer values are supported." % e)
if isinstance(exception, GalaxyError) and exception.http_code in retry_codes:
return True
if isinstance(exception, AnsibleError) and (orig_exc := getattr(exception, 'orig_exc', None)):

@ -20,7 +20,7 @@ import ansible.constants as C
from ansible import context
from ansible.errors import AnsibleError
from ansible.galaxy import api as galaxy_api
from ansible.galaxy.api import CollectionVersionMetadata, GalaxyAPI, GalaxyError
from ansible.galaxy.api import CollectionVersionMetadata, GalaxyAPI, GalaxyError, should_retry_error
from ansible.galaxy.token import BasicAuthToken, GalaxyToken, KeycloakToken
from ansible.module_utils.common.file import S_IRWU_RG_RO
from ansible.module_utils.common.text.converters import to_native, to_text
@ -1354,3 +1354,11 @@ def test_clear_cache(cache_dir):
def test_cache_id(url, expected):
actual = galaxy_api.get_cache_id(url)
assert actual == expected
def test_should_retry_error_with_invalid_code(monkeypatch):
expected = "Invalid value for HTTP retry code"
monkeypatch.setattr(C, 'GALAXY_RETRY_HTTP_ERROR_CODES', ["429", "invalid"])
with pytest.raises(AnsibleError, match=expected):
should_retry_error(Exception())

Loading…
Cancel
Save