When a manifest is not found, allow fallback to v1

PR #18590 caused compatibility issues with registries such as gcr.io
which support both the v1 and v2 protocols, but do not provide the same
set of images over both protocols. After #18590, pulls from these
registries would never use the v1 protocol, because of the
Docker-Distribution-Api-Version header indicating that v2 was supported.

Fix the problem by making an exception for the case where a manifest is
not found. This should allow fallback to v1 in case that image is
exposed over the v1 protocol but not the v2 protocol.

This avoids the overly aggressive fallback behavior before #18590 which
would allow protocol fallback after almost any error, but restores
interoperability with mixed v1/v2 registry setups.

Fixes #18832

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2015-12-21 15:42:04 -08:00
parent 5717c8243d
commit 71ddfd40ef

View file

@ -188,8 +188,8 @@ func addRequiredHeadersToRedirectedRequests(req *http.Request, via []*http.Reque
return nil return nil
} }
func shouldV2Fallback(err errcode.Error) bool { // ShouldV2Fallback returns true if this error is a reason to fall back to v1.
logrus.Debugf("v2 error: %T %v", err, err) func ShouldV2Fallback(err errcode.Error) bool {
switch err.Code { switch err.Code {
case errcode.ErrorCodeUnauthorized, v2.ErrorCodeManifestUnknown: case errcode.ErrorCodeUnauthorized, v2.ErrorCodeManifestUnknown:
return true return true
@ -220,7 +220,7 @@ func ContinueOnError(err error) bool {
case ErrNoSupport: case ErrNoSupport:
return ContinueOnError(v.Err) return ContinueOnError(v.Err)
case errcode.Error: case errcode.Error:
return shouldV2Fallback(v) return ShouldV2Fallback(v)
case *client.UnexpectedHTTPResponseError: case *client.UnexpectedHTTPResponseError:
return true return true
case error: case error: