From f115aa545208ace7b99895b76ba6487be3804eee Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Wed, 18 Feb 2026 15:56:59 +0000 Subject: [PATCH 1/2] ci: add 429 support for pulling images --- .ci/pull_fluent_image.py | 50 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/.ci/pull_fluent_image.py b/.ci/pull_fluent_image.py index d30565faed3b..4fdb35b4cebc 100644 --- a/.ci/pull_fluent_image.py +++ b/.ci/pull_fluent_image.py @@ -2,19 +2,65 @@ Pull a Fluent Docker image based on the FLUENT_IMAGE_TAG environment variable. """ +import re import subprocess +import time from ansys.fluent.core import config from ansys.fluent.core.docker.utils import get_ghcr_fluent_image_name +MAX_RETRIES = 5 +BASE_DELAY = 1.0 # seconds -def pull_fluent_image(): + +def pull_fluent_image(): # pylint: disable=missing-raises-doc """Pull Fluent Docker image and clean up dangling images.""" fluent_image_tag = config.fluent_image_tag image_name = get_ghcr_fluent_image_name(fluent_image_tag) separator = "@" if fluent_image_tag.startswith("sha256") else ":" full_image_name = f"{image_name}{separator}{fluent_image_tag}" - subprocess.run(["docker", "pull", full_image_name], check=True) + + # Retry logic for handling rate limits (429 errors) + + for attempt in range(MAX_RETRIES): + try: + subprocess.run( + ["docker", "pull", full_image_name], + check=True, + capture_output=True, + text=True, + ) + break # Success, exit retry loop + except subprocess.CalledProcessError as e: + stderr_output = e.stderr.lower() + + # Check if it's a 429 rate limit error + if "toomanyrequests" in stderr_output or "429" in stderr_output: + if attempt < MAX_RETRIES - 1: + # Parse retry-after hint if available + retry_after = None + match = re.search( + r"retry-after:\s*([\d.]+)\s*ms", e.stderr, re.IGNORECASE + ) + if match: + retry_after = float(match.group(1)) / 1000 + + # Use retry-after if available, otherwise exponential backoff + delay = retry_after if retry_after else BASE_DELAY * (2**attempt) + + print( + f"Rate limit hit (429), retrying in {delay:.2f} seconds... (attempt {attempt + 1}/{MAX_RETRIES})" + ) + time.sleep(delay) + else: + print( + "Max retries reached. Failed to pull image due to rate limiting." + ) + raise + else: + # Not a rate limit error, re-raise immediately + raise + subprocess.run(["docker", "image", "prune", "-f"], check=True) From a42b2d321e826d7105fa4ba955ebad15c93c1937 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:58:45 +0000 Subject: [PATCH 2/2] chore: adding changelog file 4940.maintenance.md [dependabot-skip] --- doc/changelog.d/4940.maintenance.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/4940.maintenance.md diff --git a/doc/changelog.d/4940.maintenance.md b/doc/changelog.d/4940.maintenance.md new file mode 100644 index 000000000000..a272a1098178 --- /dev/null +++ b/doc/changelog.d/4940.maintenance.md @@ -0,0 +1 @@ +Add 429 support for pulling images