Harden Linux Docker retries in CI#8358
Conversation
Co-authored-by: NachoEchevarria <[email protected]>
| #!/usr/bin/env bash | ||
| # Linux Docker readiness check — mirrors the Windows PowerShell logic in ensure-docker-ready.yml. | ||
| # Waits for the Docker daemon, attempts service restarts if needed, and fails fast | ||
| # so the job can be rescheduled on a different agent. |
There was a problem hiding this comment.
# so the job can be rescheduled on a different agent.
This doesn't happen automatically though right, you have to manually retry? But it would never work anyway, so that's fine, just checking 🙂
| # Waits for the Docker daemon, attempts service restarts if needed, and fails fast | ||
| # so the job can be rescheduled on a different agent. | ||
|
|
||
| set -u |
There was a problem hiding this comment.
Should probably exit on failing commands too? Or does that break things? Meh, maybe best to leave it 😅
| set -u | |
| set -eu |
There was a problem hiding this comment.
Yes, we should avoid early exits in some commands that could possibly fail in the script
| fi | ||
|
|
||
| # If Docker is not responding, try restarting the service | ||
| if command -v systemctl >/dev/null 2>&1; then |
There was a problem hiding this comment.
If this command fails (because systemctl is not available, then we don't actually restart anything, so we may as well just exit early instead I think? We can do that after logging the docker state if we want to. Alternatively, we could just not restart it, but still try to wait?
| log "Docker service is ${svc_status}. Attempting restart ${restart_count}/${DOCKER_MAX_RESTARTS}..." | ||
| try_restart_docker |
There was a problem hiding this comment.
(suggestion based on previous comment)
| log "Docker service is ${svc_status}. Attempting restart ${restart_count}/${DOCKER_MAX_RESTARTS}..." | |
| try_restart_docker | |
| if ! command -v systemctl >/dev/null 2>&1; then | |
| log "Docker service is ${svc_status}, but systmctl is not available, so unable to explicitly restart service." | |
| else | |
| log "Docker service is ${svc_status}. Attempting restart ${restart_count}/${DOCKER_MAX_RESTARTS}..." | |
| try_restart_docker | |
| fi |
There was a problem hiding this comment.
In this case, we are already checking systemctl is-active docker in line 93, so if we reach this part of the code, the command was successful. I will leave the original code. WDYT?
There was a problem hiding this comment.
Yeah, buy the problem is if it wasn't successful, we end up stuck in this loop where we're just sleeping repeatedly, not restarting anything, but still sleeping 🤔 That's the scenario this is trying to highlight 😄
| @@ -0,0 +1,113 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
Generally we try to just use POSIX shell instead of bash - if it's simple to convert to that, then it may save us some pain later
There was a problem hiding this comment.
Nice catch! Done!
| displayName: BuildWindowsIntegrationTests | ||
| retryCountOnTaskFailure: 3 | ||
|
|
||
| - template: steps/ensure-docker-ready.yml |
Co-authored-by: Andrew Lock <[email protected]>
Co-authored-by: Andrew Lock <[email protected]>
Co-authored-by: Andrew Lock <[email protected]>
…m/DataDog/dd-trace-dotnet into dd/ci/linux-docker-cgroup-retries
…m/DataDog/dd-trace-dotnet into dd/ci/linux-docker-cgroup-retries
|
Thank you for the feedback and review! |
## Summary of changes Add a targeted retry wrapper around `docker run` in `run-in-docker.yml` to handle transient Docker daemon errors without blanket-retrying the entire CI step. ## Reason for change After merging #8358 (Docker daemon readiness checks), we still observed transient failures where the daemon was confirmed ready but `docker run` failed with D-Bus/cgroup errors like: > `unable to start unit "docker-....scope": Message recipient disconnected from message bus without replying` The daemon is healthy (passes `docker info`), but systemd's D-Bus has a momentary hiccup during container cgroup creation. This is a transient infrastructure issue, not a test failure. ## Implementation details - Adds a `docker_run_with_retry` shell function that wraps the `docker run` invocation - **Only retries on exit code 125** (Docker daemon error — container creation failure), up to 3 attempts with 10s delay - **Does not retry** on any other exit code (test/build failures inside the container pass through immediately) - **Always logs the exit code** on failure (`##[warning]`), so we can observe actual exit codes for future Docker errors regardless of whether they trigger a retry ## Test coverage CI pipeline change — no unit tests. Validated by reviewing Docker's exit code conventions (125 = daemon error). ## Other details Follow-up to #8358.
Summary
Add Linux Docker readiness check to CI, mirroring the existing Windows approach (PR #8245). Targets transient cgroup/systemd/dbus failures — the largest CI flake category (10 commits blocked).
Reason for change
retryCountOnTaskFailureretries on the same agent, so if Docker is broken on that VM, all retries fail. This adds active recovery (service restart) before Docker commands run.For instance:
Changes
ensure-docker-ready-linux.sh: waits for Docker daemon, attemptssystemctl restart dockerif the service is down (mirrors WindowsRestart-Service), emits diagnostics on failureensure-docker-ready.yml: Linux readiness step added alongside existing Windows steprun-in-docker.yml: embeddedensure-docker-ready.ymlcall — automatically covers all ~27 Linux jobs that use this template.ultimate-pipeline.yml: added readiness check tointegration_tests_windows_msijob (the only uncovered Windows docker-compose caller)