mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
ci: retry dagger pipeline on transient registry/image-pull failures
The dagger job failed pulling python:3.11-bookworm from Docker Hub with a 520 (transient auth/CDN outage) — the residual risk noted in the Phase 3 dependency audit. The earlier hardening pre-pulled only the dagger engine image (registry.dagger.io); the base-image pull happens inside the engine via client.container().from_(...), which the host pre-pull cannot cover. Wrap the whole dagger pipeline (_run_checks) in a 3-attempt retry that re-runs on transient registry/pull markers (Docker Hub 5xx/429, oauth/authorize failures, TransportQueryError, i/o timeout, connection reset, context deadline). Permanent failures (lint/type/test) still fail immediately on the first attempt. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6aa5a1bc96
commit
97da477424
+34
-1
@@ -6,8 +6,25 @@ import anyio
|
|||||||
|
|
||||||
import dagger
|
import dagger
|
||||||
|
|
||||||
|
# Substrings that mark a transient registry / image-pull failure (e.g. a Docker
|
||||||
|
# Hub 5xx on the python:3.11-bookworm pull, or a registry.dagger.io timeout) that
|
||||||
|
# is worth retrying rather than failing the whole pipeline.
|
||||||
|
_TRANSIENT_MARKERS = (
|
||||||
|
"pull image",
|
||||||
|
"failed to authorize",
|
||||||
|
"failed to fetch oauth",
|
||||||
|
"TransportQueryError",
|
||||||
|
"i/o timeout",
|
||||||
|
"connection reset",
|
||||||
|
"context deadline exceeded",
|
||||||
|
" 502",
|
||||||
|
" 503",
|
||||||
|
" 520",
|
||||||
|
" 429",
|
||||||
|
)
|
||||||
|
|
||||||
async def main() -> None:
|
|
||||||
|
async def _run_checks() -> None:
|
||||||
config = dagger.Config(log_output=sys.stderr)
|
config = dagger.Config(log_output=sys.stderr)
|
||||||
async with dagger.Connection(config) as client:
|
async with dagger.Connection(config) as client:
|
||||||
source = client.host().directory(
|
source = client.host().directory(
|
||||||
@@ -39,5 +56,21 @@ async def main() -> None:
|
|||||||
await checks.sync()
|
await checks.sync()
|
||||||
|
|
||||||
|
|
||||||
|
async def main() -> None:
|
||||||
|
attempts = 3
|
||||||
|
for attempt in range(1, attempts + 1):
|
||||||
|
try:
|
||||||
|
await _run_checks()
|
||||||
|
return
|
||||||
|
except Exception as exc: # noqa: BLE001 — retry only transient registry/pull failures
|
||||||
|
message = str(exc)
|
||||||
|
transient = any(marker in message for marker in _TRANSIENT_MARKERS)
|
||||||
|
if attempt < attempts and transient:
|
||||||
|
print(f"dagger: transient registry/pull failure on attempt {attempt}; retrying in 20s", file=sys.stderr)
|
||||||
|
await anyio.sleep(20)
|
||||||
|
continue
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
anyio.run(main)
|
anyio.run(main)
|
||||||
|
|||||||
Reference in New Issue
Block a user