Skip to content

Commit 15f6d41

Browse files
committed
docker: fix unauthenticated pulls from gcr.io
Signed-off-by: Antonio Murdaca <[email protected]>
1 parent 514da4b commit 15f6d41

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

docker/docker_client.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,25 @@ func (c *dockerClient) setupRequestAuth(req *http.Request) error {
264264
return err
265265
}
266266
chs := parseAuthHeader(res.Header)
267+
// We could end up in this "if" statement if the /v2/ call (during ping)
268+
// returned 401 with a valid WWW-Authenticate=Bearer header.
269+
// That doesn't **always** mean, however, that the specific API request
270+
// (different from /v2/) actually needs to be authorized.
271+
// One example of this _weird_ scenario happens with GCR.io docker
272+
// registries.
267273
if res.StatusCode != http.StatusUnauthorized || chs == nil || len(chs) == 0 {
268-
// try again one last time with Basic Auth (gcr.io for instance)
274+
// With gcr.io, the /v2/ call returns a 401 with a valid WWW-Authenticate=Bearer
275+
// header but the repository could be _public_ (no authorization is needed).
276+
// Hence, the registry response contains no challenges and the status
277+
// code is not 401.
278+
// We just skip this case as it's not standard on docker/distribution
279+
// registries (https://github.com/docker/distribution/blob/master/docs/spec/api.md#api-version-check)
280+
if res.StatusCode != http.StatusUnauthorized {
281+
return nil
282+
}
283+
// gcr.io private repositories pull instead requires us to send user:pass pair in
284+
// order to retrieve a token and setup the correct Bearer token.
285+
// try again one last time with Basic Auth
269286
testReq2 := *req
270287
// Do not use the body stream, or we couldn't reuse it for the "real" call later.
271288
testReq2.Body = nil

0 commit comments

Comments
 (0)