Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit dc9321b

Browse files
authored
Upstream-commit: ece4cd4c4d9e0a8353a5b04a89ecbb6d477341b9
Component: engine
2 parents 481f4f9 + 0521a36 commit dc9321b

File tree

17 files changed

+57
-221
lines changed

17 files changed

+57
-221
lines changed

components/engine/api/server/router/distribution/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ import (
1111
// Backend is all the methods that need to be implemented
1212
// to provide image specific functionality.
1313
type Backend interface {
14-
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, bool, error)
14+
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, error)
1515
}

components/engine/api/server/router/distribution/distribution_routes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (s *distributionRouter) getDistributionInfo(ctx context.Context, w http.Res
5757
return errdefs.InvalidParameter(errors.Errorf("unknown image reference format: %s", image))
5858
}
5959

60-
distrepo, _, err := s.backend.GetRepository(ctx, namedRef, config)
60+
distrepo, err := s.backend.GetRepository(ctx, namedRef, config)
6161
if err != nil {
6262
return err
6363
}

components/engine/daemon/cluster/executor/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ type VolumeBackend interface {
7272
// ImageBackend is used by an executor to perform image operations
7373
type ImageBackend interface {
7474
PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
75-
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, bool, error)
75+
GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, error)
7676
LookupImage(name string) (*types.ImageInspect, error)
7777
}

components/engine/daemon/cluster/services.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ func (c *Cluster) imageWithDigestString(ctx context.Context, image string, authC
633633
return "", errors.Errorf("image reference not tagged: %s", image)
634634
}
635635

636-
repo, _, err := c.config.ImageBackend.GetRepository(ctx, taggedRef, authConfig)
636+
repo, err := c.config.ImageBackend.GetRepository(ctx, taggedRef, authConfig)
637637
if err != nil {
638638
return "", err
639639
}

components/engine/daemon/images/image_pull.go

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
progressutils "github.com/docker/docker/distribution/utils"
1616
"github.com/docker/docker/errdefs"
1717
"github.com/docker/docker/pkg/progress"
18-
"github.com/docker/docker/registry"
1918
digest "github.com/opencontainers/go-digest"
2019
specs "github.com/opencontainers/image-spec/specs-go/v1"
2120
"github.com/pkg/errors"
@@ -110,41 +109,36 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference
110109
}
111110

112111
// GetRepository returns a repository from the registry.
113-
func (i *ImageService) GetRepository(ctx context.Context, ref reference.Named, authConfig *types.AuthConfig) (dist.Repository, bool, error) {
112+
func (i *ImageService) GetRepository(ctx context.Context, ref reference.Named, authConfig *types.AuthConfig) (dist.Repository, error) {
114113
// get repository info
115114
repoInfo, err := i.registryService.ResolveRepository(ref)
116115
if err != nil {
117-
return nil, false, errdefs.InvalidParameter(err)
116+
return nil, errdefs.InvalidParameter(err)
118117
}
119118
// makes sure name is not empty or `scratch`
120119
if err := distribution.ValidateRepoName(repoInfo.Name); err != nil {
121-
return nil, false, errdefs.InvalidParameter(err)
120+
return nil, errdefs.InvalidParameter(err)
122121
}
123122

124123
// get endpoints
125124
endpoints, err := i.registryService.LookupPullEndpoints(reference.Domain(repoInfo.Name))
126125
if err != nil {
127-
return nil, false, err
126+
return nil, err
128127
}
129128

130129
// retrieve repository
131130
var (
132-
confirmedV2 bool
133-
repository dist.Repository
134-
lastError error
131+
repository dist.Repository
132+
lastError error
135133
)
136134

137135
for _, endpoint := range endpoints {
138-
if endpoint.Version == registry.APIVersion1 {
139-
continue
140-
}
141-
142-
repository, confirmedV2, lastError = distribution.NewV2Repository(ctx, repoInfo, endpoint, nil, authConfig, "pull")
143-
if lastError == nil && confirmedV2 {
136+
repository, lastError = distribution.NewV2Repository(ctx, repoInfo, endpoint, nil, authConfig, "pull")
137+
if lastError == nil {
144138
break
145139
}
146140
}
147-
return repository, confirmedV2, lastError
141+
return repository, lastError
148142
}
149143

150144
func tempLease(ctx context.Context, mgr leases.Manager) (context.Context, func(context.Context) error, error) {

components/engine/distribution/errors.go

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ func (e ErrNoSupport) Error() string {
3434
type fallbackError struct {
3535
// err is the error being wrapped.
3636
err error
37-
// confirmedV2 is set to true if it was confirmed that the registry
38-
// supports the v2 protocol. This is used to limit fallbacks to the v1
39-
// protocol.
40-
confirmedV2 bool
4137
// transportOK is set to true if we managed to speak HTTP with the
4238
// registry. This confirms that we're using appropriate TLS settings
4339
// (or lack of TLS).
@@ -53,15 +49,6 @@ func (f fallbackError) Cause() error {
5349
return f.err
5450
}
5551

56-
// shouldV2Fallback returns true if this error is a reason to fall back to v1.
57-
func shouldV2Fallback(err errcode.Error) bool {
58-
switch err.Code {
59-
case errcode.ErrorCodeUnauthorized, v2.ErrorCodeManifestUnknown, v2.ErrorCodeNameUnknown:
60-
return true
61-
}
62-
return false
63-
}
64-
6552
type notFoundError struct {
6653
cause errcode.Error
6754
ref reference.Named
@@ -141,7 +128,7 @@ func continueOnError(err error, mirrorEndpoint bool) bool {
141128
case ErrNoSupport:
142129
return continueOnError(v.Err, mirrorEndpoint)
143130
case errcode.Error:
144-
return mirrorEndpoint || shouldV2Fallback(v)
131+
return mirrorEndpoint
145132
case *client.UnexpectedHTTPResponseError:
146133
return true
147134
case ImageConfigPullError:

components/engine/distribution/errors_test.go

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,26 @@ import (
77
"testing"
88

99
"github.com/docker/distribution/registry/api/errcode"
10-
v2 "github.com/docker/distribution/registry/api/v2"
1110
"github.com/docker/distribution/registry/client"
1211
)
1312

13+
var errUnexpected = errors.New("some totally unexpected error")
14+
1415
var alwaysContinue = []error{
1516
&client.UnexpectedHTTPResponseError{},
16-
17-
// Some errcode.Errors that don't disprove the existence of a V1 image
18-
errcode.Error{Code: errcode.ErrorCodeUnauthorized},
19-
errcode.Error{Code: v2.ErrorCodeManifestUnknown},
20-
errcode.Error{Code: v2.ErrorCodeNameUnknown},
21-
22-
errors.New("some totally unexpected error"),
17+
errcode.Errors{},
18+
errUnexpected,
19+
// nested
20+
errcode.Errors{errUnexpected},
21+
ErrNoSupport{Err: errUnexpected},
2322
}
2423

2524
var continueFromMirrorEndpoint = []error{
2625
ImageConfigPullError{},
27-
28-
// Some other errcode.Error that doesn't indicate we should search for a V1 image.
29-
errcode.Error{Code: errcode.ErrorCodeTooManyRequests},
26+
errcode.Error{},
27+
// nested
28+
errcode.Errors{errcode.Error{}},
29+
ErrNoSupport{Err: errcode.Error{}},
3030
}
3131

3232
var neverContinue = []error{
@@ -67,19 +67,3 @@ func TestContinueOnError_NeverContinue(t *testing.T) {
6767
}
6868
}
6969
}
70-
71-
func TestContinueOnError_UnnestsErrors(t *testing.T) {
72-
// ContinueOnError should evaluate nested errcode.Errors.
73-
74-
// Assumes that v2.ErrorCodeNameUnknown is a continueable error code.
75-
err := errcode.Errors{errcode.Error{Code: v2.ErrorCodeNameUnknown}}
76-
if !continueOnError(err, false) {
77-
t.Fatal("ContinueOnError should unnest, base return value on errcode.Errors")
78-
}
79-
80-
// Assumes that errcode.ErrorCodeTooManyRequests is not a V1-fallback indication
81-
err = errcode.Errors{errcode.Error{Code: errcode.ErrorCodeTooManyRequests}}
82-
if continueOnError(err, false) {
83-
t.Fatal("ContinueOnError should unnest, base return value on errcode.Errors")
84-
}
85-
}

components/engine/distribution/pull.go

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ type Puller interface {
2424
Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) error
2525
}
2626

27-
// newPuller returns a Puller interface that will pull from either a v1 or v2
28-
// registry. The endpoint argument contains a Version field that determines
29-
// whether a v1 or v2 puller will be created. The other parameters are passed
30-
// through to the underlying puller implementation for use during the actual
31-
// pull operation.
27+
// newPuller returns a Puller interface that will pull from a v2 registry.
3228
func newPuller(endpoint registry.APIEndpoint, repoInfo *registry.RepositoryInfo, imagePullConfig *ImagePullConfig, local ContentStore) (Puller, error) {
3329
switch endpoint.Version {
3430
case registry.APIVersion2:
@@ -78,26 +74,12 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
7874
// error is the ones from v2 endpoints not v1.
7975
discardNoSupportErrors bool
8076

81-
// confirmedV2 is set to true if a pull attempt managed to
82-
// confirm that it was talking to a v2 registry. This will
83-
// prevent fallback to the v1 protocol.
84-
confirmedV2 bool
85-
8677
// confirmedTLSRegistries is a map indicating which registries
8778
// are known to be using TLS. There should never be a plaintext
8879
// retry for any of these.
8980
confirmedTLSRegistries = make(map[string]struct{})
9081
)
9182
for _, endpoint := range endpoints {
92-
if imagePullConfig.RequireSchema2 && endpoint.Version == registry.APIVersion1 {
93-
continue
94-
}
95-
96-
if confirmedV2 && endpoint.Version == registry.APIVersion1 {
97-
logrus.Debugf("Skipping v1 endpoint %s because v2 registry was detected", endpoint.URL)
98-
continue
99-
}
100-
10183
if endpoint.URL.Scheme != "https" {
10284
if _, confirmedTLS := confirmedTLSRegistries[endpoint.URL.Host]; confirmedTLS {
10385
logrus.Debugf("Skipping non-TLS endpoint %s for host/port that appears to use TLS", endpoint.URL)
@@ -122,7 +104,6 @@ func Pull(ctx context.Context, ref reference.Named, imagePullConfig *ImagePullCo
122104
default:
123105
if fallbackErr, ok := err.(fallbackError); ok {
124106
fallback = true
125-
confirmedV2 = confirmedV2 || fallbackErr.confirmedV2
126107
if fallbackErr.transportOK && endpoint.URL.Scheme == "https" {
127108
confirmedTLSRegistries[endpoint.URL.Host] = struct{}{}
128109
}

components/engine/distribution/pull_v2.go

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77
"io"
88
"io/ioutil"
9-
"net/url"
109
"os"
1110
"runtime"
1211
"strings"
@@ -19,8 +18,6 @@ import (
1918
"github.com/docker/distribution/manifest/schema1"
2019
"github.com/docker/distribution/manifest/schema2"
2120
"github.com/docker/distribution/reference"
22-
"github.com/docker/distribution/registry/api/errcode"
23-
"github.com/docker/distribution/registry/client/auth"
2421
"github.com/docker/distribution/registry/client/transport"
2522
"github.com/docker/docker/distribution/metadata"
2623
"github.com/docker/docker/distribution/xfer"
@@ -61,15 +58,12 @@ type v2Puller struct {
6158
config *ImagePullConfig
6259
repoInfo *registry.RepositoryInfo
6360
repo distribution.Repository
64-
// confirmedV2 is set to true if we confirm we're talking to a v2
65-
// registry. This is used to limit fallbacks to the v1 protocol.
66-
confirmedV2 bool
67-
manifestStore *manifestStore
61+
manifestStore *manifestStore
6862
}
6963

7064
func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) {
7165
// TODO(tiborvass): was ReceiveTimeout
72-
p.repo, p.confirmedV2, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull")
66+
p.repo, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull")
7367
if err != nil {
7468
logrus.Warnf("Error getting v2 registry: %v", err)
7569
return err
@@ -87,7 +81,6 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform *spec
8781
if continueOnError(err, p.endpoint.Mirror) {
8882
return fallbackError{
8983
err: err,
90-
confirmedV2: p.confirmedV2,
9184
transportOK: true,
9285
}
9386
}
@@ -105,16 +98,9 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named, pl
10598
} else {
10699
tags, err := p.repo.Tags(ctx).All(ctx)
107100
if err != nil {
108-
// If this repository doesn't exist on V2, we should
109-
// permit a fallback to V1.
110-
return allowV1Fallback(err)
101+
return err
111102
}
112103

113-
// The v2 registry knows about this repository, so we will not
114-
// allow fallback to the v1 protocol even if we encounter an
115-
// error later on.
116-
p.confirmedV2 = true
117-
118104
for _, tag := range tags {
119105
tagRef, err := reference.WithTag(ref, tag)
120106
if err != nil {
@@ -353,7 +339,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
353339
tagService := p.repo.Tags(ctx)
354340
desc, err := tagService.Get(ctx, tagged.Tag())
355341
if err != nil {
356-
return false, allowV1Fallback(err)
342+
return false, err
357343
}
358344

359345
dgst = desc.Digest
@@ -427,10 +413,6 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform
427413
}
428414
}
429415

430-
// If manSvc.Get succeeded, we can be confident that the registry on
431-
// the other side speaks the v2 protocol.
432-
p.confirmedV2 = true
433-
434416
logrus.Debugf("Pulling ref from V2 registry: %s", reference.FamiliarString(ref))
435417
progress.Message(p.config.ProgressOutput, tagOrDigest, "Pulling from "+reference.FamiliarName(p.repo.Named()))
436418

@@ -945,39 +927,6 @@ func schema2ManifestDigest(ref reference.Named, mfst distribution.Manifest) (dig
945927
return digest.FromBytes(canonical), nil
946928
}
947929

948-
// allowV1Fallback checks if the error is a possible reason to fallback to v1
949-
// (even if confirmedV2 has been set already), and if so, wraps the error in
950-
// a fallbackError with confirmedV2 set to false. Otherwise, it returns the
951-
// error unmodified.
952-
func allowV1Fallback(err error) error {
953-
switch v := err.(type) {
954-
case errcode.Errors:
955-
if len(v) != 0 {
956-
if v0, ok := v[0].(errcode.Error); ok && shouldV2Fallback(v0) {
957-
return fallbackError{
958-
err: err,
959-
confirmedV2: false,
960-
transportOK: true,
961-
}
962-
}
963-
}
964-
case errcode.Error:
965-
if shouldV2Fallback(v) {
966-
return fallbackError{
967-
err: err,
968-
confirmedV2: false,
969-
transportOK: true,
970-
}
971-
}
972-
case *url.Error:
973-
if v.Err == auth.ErrNoBasicAuthCredentials {
974-
return fallbackError{err: err, confirmedV2: false}
975-
}
976-
}
977-
978-
return err
979-
}
980-
981930
func verifySchema1Manifest(signedManifest *schema1.SignedManifest, ref reference.Reference) (m *schema1.Manifest, err error) {
982931
// If pull by digest, then verify the manifest digest. NOTE: It is
983932
// important to do this first, before any other content validation. If the

components/engine/distribution/push.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,13 @@ func Push(ctx context.Context, ref reference.Named, imagePushConfig *ImagePushCo
7373
var (
7474
lastErr error
7575

76-
// confirmedV2 is set to true if a push attempt managed to
77-
// confirm that it was talking to a v2 registry. This will
78-
// prevent fallback to the v1 protocol.
79-
confirmedV2 bool
80-
8176
// confirmedTLSRegistries is a map indicating which registries
8277
// are known to be using TLS. There should never be a plaintext
8378
// retry for any of these.
8479
confirmedTLSRegistries = make(map[string]struct{})
8580
)
8681

8782
for _, endpoint := range endpoints {
88-
if imagePushConfig.RequireSchema2 && endpoint.Version == registry.APIVersion1 {
89-
continue
90-
}
91-
if confirmedV2 && endpoint.Version == registry.APIVersion1 {
92-
logrus.Debugf("Skipping v1 endpoint %s because v2 registry was detected", endpoint.URL)
93-
continue
94-
}
95-
9683
if endpoint.URL.Scheme != "https" {
9784
if _, confirmedTLS := confirmedTLSRegistries[endpoint.URL.Host]; confirmedTLS {
9885
logrus.Debugf("Skipping non-TLS endpoint %s for host/port that appears to use TLS", endpoint.URL)
@@ -114,7 +101,6 @@ func Push(ctx context.Context, ref reference.Named, imagePushConfig *ImagePushCo
114101
case <-ctx.Done():
115102
default:
116103
if fallbackErr, ok := err.(fallbackError); ok {
117-
confirmedV2 = confirmedV2 || fallbackErr.confirmedV2
118104
if fallbackErr.transportOK && endpoint.URL.Scheme == "https" {
119105
confirmedTLSRegistries[endpoint.URL.Host] = struct{}{}
120106
}

0 commit comments

Comments
 (0)