integration: authenticate Docker Hub pulls and retry transient errors

Anonymous Hub pulls trip the 100/6h IP cap on shared CI runners, turning
into singleton FAIL reports whenever the runner egress IP crosses the
quota. Route every pull through Docker Hub credentials when present, and
retry transient errors with backoff. tsic and hi use the same helper so
both surfaces honour ~/.docker/config.json and the GHA secrets.
This commit is contained in:
Kristoffer Dalby 2026-05-13 13:16:24 +00:00
parent 4d3b567149
commit 98e9ff4d36
6 changed files with 290 additions and 16 deletions

View file

@ -7,6 +7,8 @@ import (
"log"
"os/exec"
"strings"
"github.com/juanfont/headscale/integration/dockertestutil"
)
var ErrSystemChecksFailed = errors.New("system checks failed")
@ -34,6 +36,7 @@ func runDoctorCheck(ctx context.Context) error {
if dockerResult.Status == "PASS" {
results = append(results, checkDockerContext(ctx))
results = append(results, checkDockerSocket(ctx))
results = append(results, checkDockerHubCredentials())
results = append(results, checkGolangImage(ctx))
}
@ -190,6 +193,30 @@ func checkDockerSocket(ctx context.Context) DoctorResult {
}
}
// checkDockerHubCredentials warns when pulls would be anonymous and
// therefore rate-limited.
func checkDockerHubCredentials() DoctorResult {
_, _, source := dockertestutil.Credentials()
if source == dockertestutil.CredentialSourceAnonymous {
return DoctorResult{
Name: "Docker Hub Credentials",
Status: "WARN",
Message: "No Docker Hub credentials found — pulls will be rate-limited (100/6h per IP)",
Suggestions: []string{
"Run: docker login",
"Or export DOCKERHUB_USERNAME and DOCKERHUB_TOKEN",
"In CI: ensure the docker/login-action step is configured with secrets",
},
}
}
return DoctorResult{
Name: "Docker Hub Credentials",
Status: "PASS",
Message: fmt.Sprintf("Credentials available (source: %s)", source),
}
}
// checkGolangImage verifies the golang Docker image is available locally or can be pulled.
func checkGolangImage(ctx context.Context) DoctorResult {
cli, err := createDockerClient(ctx)