Merge pull request #41745 from AkihiroSuda/vendor-bk-080
vendor: BuildKit 950603da215ae03b843f3f66fbe86c4876a6f5a1
diff --git a/distribution/errors.go b/distribution/errors.go
index 194287d..02f5870 100644
--- a/distribution/errors.go
+++ b/distribution/errors.go
@@ -112,6 +112,23 @@
return errdefs.Unknown(err)
}
+func isNotFound(err error) bool {
+ switch v := err.(type) {
+ case errcode.Errors:
+ for _, e := range v {
+ if isNotFound(e) {
+ return true
+ }
+ }
+ case errcode.Error:
+ switch v.Code {
+ case errcode.ErrorCodeDenied, v2.ErrorCodeManifestUnknown, v2.ErrorCodeNameUnknown:
+ return true
+ }
+ }
+ return false
+}
+
// continueOnError returns true if we should fallback to the next endpoint
// as a result of this error.
func continueOnError(err error, mirrorEndpoint bool) bool {
diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go
index b5db4ee..12497ea 100644
--- a/distribution/pull_v2.go
+++ b/distribution/pull_v2.go
@@ -343,16 +343,19 @@
dgst digest.Digest
mt string
size int64
+ tagged reference.NamedTagged
+ isTagged bool
)
if digested, isDigested := ref.(reference.Canonical); isDigested {
dgst = digested.Digest()
tagOrDigest = digested.String()
- } else if tagged, isTagged := ref.(reference.NamedTagged); isTagged {
+ } else if tagged, isTagged = ref.(reference.NamedTagged); isTagged {
tagService := p.repo.Tags(ctx)
desc, err := tagService.Get(ctx, tagged.Tag())
if err != nil {
return false, allowV1Fallback(err)
}
+
dgst = desc.Digest
tagOrDigest = tagged.Tag()
mt = desc.MediaType
@@ -367,13 +370,40 @@
"remote": ref,
}))
- manifest, err := p.manifestStore.Get(ctx, specs.Descriptor{
+ desc := specs.Descriptor{
MediaType: mt,
Digest: dgst,
Size: size,
- })
+ }
+ manifest, err := p.manifestStore.Get(ctx, desc)
if err != nil {
- return false, err
+ if isTagged && isNotFound(errors.Cause(err)) {
+ logrus.WithField("ref", ref).WithError(err).Debug("Falling back to pull manifest by tag")
+
+ msg := `%s Failed to pull manifest by the resolved digest. This registry does not
+ appear to conform to the distribution registry specification; falling back to
+ pull by tag. This fallback is DEPRECATED, and will be removed in a future
+ release. Please contact admins of %s. %s
+`
+
+ warnEmoji := "\U000026A0\U0000FE0F"
+ progress.Messagef(p.config.ProgressOutput, "WARNING", msg, warnEmoji, p.endpoint.URL, warnEmoji)
+
+ // Fetch by tag worked, but fetch by digest didn't.
+ // This is a broken registry implementation.
+ // We'll fallback to the old behavior and get the manifest by tag.
+ var ms distribution.ManifestService
+ ms, err = p.repo.Manifests(ctx)
+ if err != nil {
+ return false, err
+ }
+
+ manifest, err = ms.Get(ctx, "", distribution.WithTag(tagged.Tag()))
+ err = errors.Wrap(err, "error after falling back to get manifest by tag")
+ }
+ if err != nil {
+ return false, err
+ }
}
if manifest == nil {
@@ -818,11 +848,12 @@
return "", "", err
}
- manifest, err := p.manifestStore.Get(ctx, specs.Descriptor{
+ desc := specs.Descriptor{
Digest: match.Digest,
Size: match.Size,
MediaType: match.MediaType,
- })
+ }
+ manifest, err := p.manifestStore.Get(ctx, desc)
if err != nil {
return "", "", err
}