Browse code

Remove v1 manifest code

Signed-off-by: Tibor Vass <tibor@docker.com>
(cherry picked from commit 53dad9f0274fcc1ec742f9411142382c83d08ff9)
Signed-off-by: Tibor Vass <tibor@docker.com>

Tibor Vass authored on 2019/06/18 10:04:17
Showing 12 changed files
... ...
@@ -83,13 +83,6 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
83 83
 
84 84
 	flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU")
85 85
 
86
-	// "--deprecated-key-path" is to allow configuration of the key used
87
-	// for the daemon ID and the deprecated image signing. It was never
88
-	// exposed as a command line option but is added here to allow
89
-	// overriding the default path in configuration.
90
-	flags.Var(opts.NewQuotedString(&conf.TrustKeyPath), "deprecated-key-path", "Path to key file for ID and image signing")
91
-	flags.MarkHidden("deprecated-key-path")
92
-
93 86
 	conf.MaxConcurrentDownloads = &maxConcurrentDownloads
94 87
 	conf.MaxConcurrentUploads = &maxConcurrentUploads
95 88
 	return nil
... ...
@@ -103,10 +96,4 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.
103 103
 	flags.Var(ana, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry")
104 104
 	flags.Var(mirrors, "registry-mirror", "Preferred Docker registry mirror")
105 105
 	flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
106
-
107
-	if runtime.GOOS != "windows" {
108
-		// TODO: Remove this flag after 3 release cycles (18.03)
109
-		flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
110
-		flags.MarkHidden("disable-legacy-registry")
111
-	}
112 106
 }
... ...
@@ -454,17 +454,6 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
454 454
 		return nil, err
455 455
 	}
456 456
 
457
-	if runtime.GOOS != "windows" {
458
-		if flags.Changed("disable-legacy-registry") {
459
-			// TODO: Remove this error after 3 release cycles (18.03)
460
-			return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported")
461
-		}
462
-		if !conf.V2Only {
463
-			// TODO: Remove this error after 3 release cycles (18.03)
464
-			return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported")
465
-		}
466
-	}
467
-
468 457
 	if flags.Changed("graph") {
469 458
 		logrus.Warnf(`The "-g / --graph" flag is deprecated. Please use "--data-root" instead`)
470 459
 	}
... ...
@@ -8,7 +8,6 @@ import (
8 8
 	"io/ioutil"
9 9
 	"os"
10 10
 	"reflect"
11
-	"runtime"
12 11
 	"strings"
13 12
 	"sync"
14 13
 
... ...
@@ -246,10 +245,6 @@ func New() *Config {
246 246
 	config := Config{}
247 247
 	config.LogConfig.Config = make(map[string]string)
248 248
 	config.ClusterOpts = make(map[string]string)
249
-
250
-	if runtime.GOOS != "linux" {
251
-		config.V2Only = true
252
-	}
253 249
 	return &config
254 250
 }
255 251
 
... ...
@@ -39,12 +39,7 @@ func newPuller(endpoint registry.APIEndpoint, repoInfo *registry.RepositoryInfo,
39 39
 			repoInfo:          repoInfo,
40 40
 		}, nil
41 41
 	case registry.APIVersion1:
42
-		return &v1Puller{
43
-			v1IDService: metadata.NewV1IDService(imagePullConfig.MetadataStore),
44
-			endpoint:    endpoint,
45
-			config:      imagePullConfig,
46
-			repoInfo:    repoInfo,
47
-		}, nil
42
+		return nil, fmt.Errorf("protocol version %d no longer supported. Please contact admins of registry %s", endpoint.Version, endpoint.URL)
48 43
 	}
49 44
 	return nil, fmt.Errorf("unknown version %d for registry %s", endpoint.Version, endpoint.URL)
50 45
 }
51 46
deleted file mode 100644
... ...
@@ -1,365 +0,0 @@
1
-package distribution // import "github.com/docker/docker/distribution"
2
-
3
-import (
4
-	"context"
5
-	"errors"
6
-	"fmt"
7
-	"io"
8
-	"io/ioutil"
9
-	"net"
10
-	"net/url"
11
-	"os"
12
-	"strings"
13
-	"time"
14
-
15
-	"github.com/docker/distribution/reference"
16
-	"github.com/docker/distribution/registry/client/transport"
17
-	"github.com/docker/docker/distribution/metadata"
18
-	"github.com/docker/docker/distribution/xfer"
19
-	"github.com/docker/docker/dockerversion"
20
-	"github.com/docker/docker/image"
21
-	"github.com/docker/docker/image/v1"
22
-	"github.com/docker/docker/layer"
23
-	"github.com/docker/docker/pkg/ioutils"
24
-	"github.com/docker/docker/pkg/progress"
25
-	"github.com/docker/docker/pkg/stringid"
26
-	"github.com/docker/docker/registry"
27
-	specs "github.com/opencontainers/image-spec/specs-go/v1"
28
-	"github.com/sirupsen/logrus"
29
-)
30
-
31
-type v1Puller struct {
32
-	v1IDService *metadata.V1IDService
33
-	endpoint    registry.APIEndpoint
34
-	config      *ImagePullConfig
35
-	repoInfo    *registry.RepositoryInfo
36
-	session     *registry.Session
37
-}
38
-
39
-func (p *v1Puller) Pull(ctx context.Context, ref reference.Named, _ *specs.Platform) error {
40
-	if _, isCanonical := ref.(reference.Canonical); isCanonical {
41
-		// Allowing fallback, because HTTPS v1 is before HTTP v2
42
-		return fallbackError{err: ErrNoSupport{Err: errors.New("Cannot pull by digest with v1 registry")}}
43
-	}
44
-
45
-	tlsConfig, err := p.config.RegistryService.TLSConfig(p.repoInfo.Index.Name)
46
-	if err != nil {
47
-		return err
48
-	}
49
-	// Adds Docker-specific headers as well as user-specified headers (metaHeaders)
50
-	tr := transport.NewTransport(
51
-		// TODO(tiborvass): was ReceiveTimeout
52
-		registry.NewTransport(tlsConfig),
53
-		registry.Headers(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)...,
54
-	)
55
-	client := registry.HTTPClient(tr)
56
-	v1Endpoint := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)
57
-	p.session, err = registry.NewSession(client, p.config.AuthConfig, v1Endpoint)
58
-	if err != nil {
59
-		// TODO(dmcgowan): Check if should fallback
60
-		logrus.Debugf("Fallback from error: %s", err)
61
-		return fallbackError{err: err}
62
-	}
63
-	if err := p.pullRepository(ctx, ref); err != nil {
64
-		// TODO(dmcgowan): Check if should fallback
65
-		return err
66
-	}
67
-	progress.Message(p.config.ProgressOutput, "", p.repoInfo.Name.Name()+": this image was pulled from a legacy registry.  Important: This registry version will not be supported in future versions of docker.")
68
-
69
-	return nil
70
-}
71
-
72
-func (p *v1Puller) pullRepository(ctx context.Context, ref reference.Named) error {
73
-	progress.Message(p.config.ProgressOutput, "", "Pulling repository "+p.repoInfo.Name.Name())
74
-
75
-	tagged, isTagged := ref.(reference.NamedTagged)
76
-
77
-	repoData, err := p.session.GetRepositoryData(p.repoInfo.Name)
78
-	if err != nil {
79
-		if strings.Contains(err.Error(), "HTTP code: 404") {
80
-			if isTagged {
81
-				return fmt.Errorf("Error: image %s:%s not found", reference.Path(p.repoInfo.Name), tagged.Tag())
82
-			}
83
-			return fmt.Errorf("Error: image %s not found", reference.Path(p.repoInfo.Name))
84
-		}
85
-		// Unexpected HTTP error
86
-		return err
87
-	}
88
-
89
-	logrus.Debug("Retrieving the tag list")
90
-	var tagsList map[string]string
91
-	if !isTagged {
92
-		tagsList, err = p.session.GetRemoteTags(repoData.Endpoints, p.repoInfo.Name)
93
-	} else {
94
-		var tagID string
95
-		tagsList = make(map[string]string)
96
-		tagID, err = p.session.GetRemoteTag(repoData.Endpoints, p.repoInfo.Name, tagged.Tag())
97
-		if err == registry.ErrRepoNotFound {
98
-			return fmt.Errorf("Tag %s not found in repository %s", tagged.Tag(), p.repoInfo.Name.Name())
99
-		}
100
-		tagsList[tagged.Tag()] = tagID
101
-	}
102
-	if err != nil {
103
-		logrus.Errorf("unable to get remote tags: %s", err)
104
-		return err
105
-	}
106
-
107
-	for tag, id := range tagsList {
108
-		repoData.ImgList[id] = &registry.ImgData{
109
-			ID:       id,
110
-			Tag:      tag,
111
-			Checksum: "",
112
-		}
113
-	}
114
-
115
-	layersDownloaded := false
116
-	for _, imgData := range repoData.ImgList {
117
-		if isTagged && imgData.Tag != tagged.Tag() {
118
-			continue
119
-		}
120
-
121
-		err := p.downloadImage(ctx, repoData, imgData, &layersDownloaded)
122
-		if err != nil {
123
-			return err
124
-		}
125
-	}
126
-
127
-	writeStatus(reference.FamiliarString(ref), p.config.ProgressOutput, layersDownloaded)
128
-	return nil
129
-}
130
-
131
-func (p *v1Puller) downloadImage(ctx context.Context, repoData *registry.RepositoryData, img *registry.ImgData, layersDownloaded *bool) error {
132
-	if img.Tag == "" {
133
-		logrus.Debugf("Image (id: %s) present in this repository but untagged, skipping", img.ID)
134
-		return nil
135
-	}
136
-
137
-	localNameRef, err := reference.WithTag(p.repoInfo.Name, img.Tag)
138
-	if err != nil {
139
-		retErr := fmt.Errorf("Image (id: %s) has invalid tag: %s", img.ID, img.Tag)
140
-		logrus.Debug(retErr.Error())
141
-		return retErr
142
-	}
143
-
144
-	if err := v1.ValidateID(img.ID); err != nil {
145
-		return err
146
-	}
147
-
148
-	progress.Updatef(p.config.ProgressOutput, stringid.TruncateID(img.ID), "Pulling image (%s) from %s", img.Tag, p.repoInfo.Name.Name())
149
-	success := false
150
-	var lastErr error
151
-	for _, ep := range p.repoInfo.Index.Mirrors {
152
-		ep += "v1/"
153
-		progress.Updatef(p.config.ProgressOutput, stringid.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, mirror: %s", img.Tag, p.repoInfo.Name.Name(), ep))
154
-		if err = p.pullImage(ctx, img.ID, ep, localNameRef, layersDownloaded); err != nil {
155
-			// Don't report errors when pulling from mirrors.
156
-			logrus.Debugf("Error pulling image (%s) from %s, mirror: %s, %s", img.Tag, p.repoInfo.Name.Name(), ep, err)
157
-			continue
158
-		}
159
-		success = true
160
-		break
161
-	}
162
-	if !success {
163
-		for _, ep := range repoData.Endpoints {
164
-			progress.Updatef(p.config.ProgressOutput, stringid.TruncateID(img.ID), "Pulling image (%s) from %s, endpoint: %s", img.Tag, p.repoInfo.Name.Name(), ep)
165
-			if err = p.pullImage(ctx, img.ID, ep, localNameRef, layersDownloaded); err != nil {
166
-				// It's not ideal that only the last error is returned, it would be better to concatenate the errors.
167
-				// As the error is also given to the output stream the user will see the error.
168
-				lastErr = err
169
-				progress.Updatef(p.config.ProgressOutput, stringid.TruncateID(img.ID), "Error pulling image (%s) from %s, endpoint: %s, %s", img.Tag, p.repoInfo.Name.Name(), ep, err)
170
-				continue
171
-			}
172
-			success = true
173
-			break
174
-		}
175
-	}
176
-	if !success {
177
-		err := fmt.Errorf("Error pulling image (%s) from %s, %v", img.Tag, p.repoInfo.Name.Name(), lastErr)
178
-		progress.Update(p.config.ProgressOutput, stringid.TruncateID(img.ID), err.Error())
179
-		return err
180
-	}
181
-	return nil
182
-}
183
-
184
-func (p *v1Puller) pullImage(ctx context.Context, v1ID, endpoint string, localNameRef reference.Named, layersDownloaded *bool) (err error) {
185
-	var history []string
186
-	history, err = p.session.GetRemoteHistory(v1ID, endpoint)
187
-	if err != nil {
188
-		return err
189
-	}
190
-	if len(history) < 1 {
191
-		return fmt.Errorf("empty history for image %s", v1ID)
192
-	}
193
-	progress.Update(p.config.ProgressOutput, stringid.TruncateID(v1ID), "Pulling dependent layers")
194
-
195
-	var (
196
-		descriptors []xfer.DownloadDescriptor
197
-		newHistory  []image.History
198
-		imgJSON     []byte
199
-		imgSize     int64
200
-	)
201
-
202
-	// Iterate over layers, in order from bottom-most to top-most. Download
203
-	// config for all layers and create descriptors.
204
-	for i := len(history) - 1; i >= 0; i-- {
205
-		v1LayerID := history[i]
206
-		imgJSON, imgSize, err = p.downloadLayerConfig(v1LayerID, endpoint)
207
-		if err != nil {
208
-			return err
209
-		}
210
-
211
-		// Create a new-style config from the legacy configs
212
-		h, err := v1.HistoryFromConfig(imgJSON, false)
213
-		if err != nil {
214
-			return err
215
-		}
216
-		newHistory = append(newHistory, h)
217
-
218
-		layerDescriptor := &v1LayerDescriptor{
219
-			v1LayerID:        v1LayerID,
220
-			indexName:        p.repoInfo.Index.Name,
221
-			endpoint:         endpoint,
222
-			v1IDService:      p.v1IDService,
223
-			layersDownloaded: layersDownloaded,
224
-			layerSize:        imgSize,
225
-			session:          p.session,
226
-		}
227
-
228
-		descriptors = append(descriptors, layerDescriptor)
229
-	}
230
-
231
-	rootFS := image.NewRootFS()
232
-	resultRootFS, release, err := p.config.DownloadManager.Download(ctx, *rootFS, "", descriptors, p.config.ProgressOutput)
233
-	if err != nil {
234
-		return err
235
-	}
236
-	defer release()
237
-
238
-	config, err := v1.MakeConfigFromV1Config(imgJSON, &resultRootFS, newHistory)
239
-	if err != nil {
240
-		return err
241
-	}
242
-
243
-	imageID, err := p.config.ImageStore.Put(config)
244
-	if err != nil {
245
-		return err
246
-	}
247
-
248
-	if p.config.ReferenceStore != nil {
249
-		if err := p.config.ReferenceStore.AddTag(localNameRef, imageID, true); err != nil {
250
-			return err
251
-		}
252
-	}
253
-
254
-	return nil
255
-}
256
-
257
-func (p *v1Puller) downloadLayerConfig(v1LayerID, endpoint string) (imgJSON []byte, imgSize int64, err error) {
258
-	progress.Update(p.config.ProgressOutput, stringid.TruncateID(v1LayerID), "Pulling metadata")
259
-
260
-	retries := 5
261
-	for j := 1; j <= retries; j++ {
262
-		imgJSON, imgSize, err := p.session.GetRemoteImageJSON(v1LayerID, endpoint)
263
-		if err != nil && j == retries {
264
-			progress.Update(p.config.ProgressOutput, stringid.TruncateID(v1LayerID), "Error pulling layer metadata")
265
-			return nil, 0, err
266
-		} else if err != nil {
267
-			time.Sleep(time.Duration(j) * 500 * time.Millisecond)
268
-			continue
269
-		}
270
-
271
-		return imgJSON, imgSize, nil
272
-	}
273
-
274
-	// not reached
275
-	return nil, 0, nil
276
-}
277
-
278
-type v1LayerDescriptor struct {
279
-	v1LayerID        string
280
-	indexName        string
281
-	endpoint         string
282
-	v1IDService      *metadata.V1IDService
283
-	layersDownloaded *bool
284
-	layerSize        int64
285
-	session          *registry.Session
286
-	tmpFile          *os.File
287
-}
288
-
289
-func (ld *v1LayerDescriptor) Key() string {
290
-	return "v1:" + ld.v1LayerID
291
-}
292
-
293
-func (ld *v1LayerDescriptor) ID() string {
294
-	return stringid.TruncateID(ld.v1LayerID)
295
-}
296
-
297
-func (ld *v1LayerDescriptor) DiffID() (layer.DiffID, error) {
298
-	return ld.v1IDService.Get(ld.v1LayerID, ld.indexName)
299
-}
300
-
301
-func (ld *v1LayerDescriptor) Download(ctx context.Context, progressOutput progress.Output) (io.ReadCloser, int64, error) {
302
-	progress.Update(progressOutput, ld.ID(), "Pulling fs layer")
303
-	layerReader, err := ld.session.GetRemoteImageLayer(ld.v1LayerID, ld.endpoint, ld.layerSize)
304
-	if err != nil {
305
-		progress.Update(progressOutput, ld.ID(), "Error pulling dependent layers")
306
-		if uerr, ok := err.(*url.Error); ok {
307
-			err = uerr.Err
308
-		}
309
-		if terr, ok := err.(net.Error); ok && terr.Timeout() {
310
-			return nil, 0, err
311
-		}
312
-		return nil, 0, xfer.DoNotRetry{Err: err}
313
-	}
314
-	*ld.layersDownloaded = true
315
-
316
-	ld.tmpFile, err = ioutil.TempFile("", "GetImageBlob")
317
-	if err != nil {
318
-		layerReader.Close()
319
-		return nil, 0, err
320
-	}
321
-
322
-	reader := progress.NewProgressReader(ioutils.NewCancelReadCloser(ctx, layerReader), progressOutput, ld.layerSize, ld.ID(), "Downloading")
323
-	defer reader.Close()
324
-
325
-	_, err = io.Copy(ld.tmpFile, reader)
326
-	if err != nil {
327
-		ld.Close()
328
-		return nil, 0, err
329
-	}
330
-
331
-	progress.Update(progressOutput, ld.ID(), "Download complete")
332
-
333
-	logrus.Debugf("Downloaded %s to tempfile %s", ld.ID(), ld.tmpFile.Name())
334
-
335
-	ld.tmpFile.Seek(0, 0)
336
-
337
-	// hand off the temporary file to the download manager, so it will only
338
-	// be closed once
339
-	tmpFile := ld.tmpFile
340
-	ld.tmpFile = nil
341
-
342
-	return ioutils.NewReadCloserWrapper(tmpFile, func() error {
343
-		tmpFile.Close()
344
-		err := os.RemoveAll(tmpFile.Name())
345
-		if err != nil {
346
-			logrus.Errorf("Failed to remove temp file: %s", tmpFile.Name())
347
-		}
348
-		return err
349
-	}), ld.layerSize, nil
350
-}
351
-
352
-func (ld *v1LayerDescriptor) Close() {
353
-	if ld.tmpFile != nil {
354
-		ld.tmpFile.Close()
355
-		if err := os.RemoveAll(ld.tmpFile.Name()); err != nil {
356
-			logrus.Errorf("Failed to remove temp file: %s", ld.tmpFile.Name())
357
-		}
358
-		ld.tmpFile = nil
359
-	}
360
-}
361
-
362
-func (ld *v1LayerDescriptor) Registered(diffID layer.DiffID) {
363
-	// Cache mapping from this layer's DiffID to the blobsum
364
-	ld.v1IDService.Set(ld.v1LayerID, ld.indexName, diffID)
365
-}
... ...
@@ -41,13 +41,7 @@ func NewPusher(ref reference.Named, endpoint registry.APIEndpoint, repoInfo *reg
41 41
 			config:            imagePushConfig,
42 42
 		}, nil
43 43
 	case registry.APIVersion1:
44
-		return &v1Pusher{
45
-			v1IDService: metadata.NewV1IDService(imagePushConfig.MetadataStore),
46
-			ref:         ref,
47
-			endpoint:    endpoint,
48
-			repoInfo:    repoInfo,
49
-			config:      imagePushConfig,
50
-		}, nil
44
+		return nil, fmt.Errorf("protocol version %d no longer supported. Please contact admins of registry %s", endpoint.Version, endpoint.URL)
51 45
 	}
52 46
 	return nil, fmt.Errorf("unknown version %d for registry %s", endpoint.Version, endpoint.URL)
53 47
 }
54 48
deleted file mode 100644
... ...
@@ -1,457 +0,0 @@
1
-package distribution // import "github.com/docker/docker/distribution"
2
-
3
-import (
4
-	"context"
5
-	"fmt"
6
-	"sync"
7
-
8
-	"github.com/docker/distribution/reference"
9
-	"github.com/docker/distribution/registry/client/transport"
10
-	"github.com/docker/docker/distribution/metadata"
11
-	"github.com/docker/docker/dockerversion"
12
-	"github.com/docker/docker/image"
13
-	"github.com/docker/docker/image/v1"
14
-	"github.com/docker/docker/layer"
15
-	"github.com/docker/docker/pkg/ioutils"
16
-	"github.com/docker/docker/pkg/progress"
17
-	"github.com/docker/docker/pkg/stringid"
18
-	"github.com/docker/docker/pkg/system"
19
-	"github.com/docker/docker/registry"
20
-	"github.com/opencontainers/go-digest"
21
-	"github.com/sirupsen/logrus"
22
-)
23
-
24
-type v1Pusher struct {
25
-	v1IDService *metadata.V1IDService
26
-	endpoint    registry.APIEndpoint
27
-	ref         reference.Named
28
-	repoInfo    *registry.RepositoryInfo
29
-	config      *ImagePushConfig
30
-	session     *registry.Session
31
-}
32
-
33
-func (p *v1Pusher) Push(ctx context.Context) error {
34
-	tlsConfig, err := p.config.RegistryService.TLSConfig(p.repoInfo.Index.Name)
35
-	if err != nil {
36
-		return err
37
-	}
38
-	// Adds Docker-specific headers as well as user-specified headers (metaHeaders)
39
-	tr := transport.NewTransport(
40
-		// TODO(tiborvass): was NoTimeout
41
-		registry.NewTransport(tlsConfig),
42
-		registry.Headers(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)...,
43
-	)
44
-	client := registry.HTTPClient(tr)
45
-	v1Endpoint := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)
46
-	p.session, err = registry.NewSession(client, p.config.AuthConfig, v1Endpoint)
47
-	if err != nil {
48
-		// TODO(dmcgowan): Check if should fallback
49
-		return fallbackError{err: err}
50
-	}
51
-	if err := p.pushRepository(ctx); err != nil {
52
-		// TODO(dmcgowan): Check if should fallback
53
-		return err
54
-	}
55
-	return nil
56
-}
57
-
58
-// v1Image exposes the configuration, filesystem layer ID, and a v1 ID for an
59
-// image being pushed to a v1 registry.
60
-type v1Image interface {
61
-	Config() []byte
62
-	Layer() layer.Layer
63
-	V1ID() string
64
-}
65
-
66
-type v1ImageCommon struct {
67
-	layer  layer.Layer
68
-	config []byte
69
-	v1ID   string
70
-}
71
-
72
-func (common *v1ImageCommon) Config() []byte {
73
-	return common.config
74
-}
75
-
76
-func (common *v1ImageCommon) V1ID() string {
77
-	return common.v1ID
78
-}
79
-
80
-func (common *v1ImageCommon) Layer() layer.Layer {
81
-	return common.layer
82
-}
83
-
84
-// v1TopImage defines a runnable (top layer) image being pushed to a v1
85
-// registry.
86
-type v1TopImage struct {
87
-	v1ImageCommon
88
-	imageID image.ID
89
-}
90
-
91
-func newV1TopImage(imageID image.ID, img *image.Image, l layer.Layer, parent *v1DependencyImage) (*v1TopImage, error) {
92
-	v1ID := imageID.Digest().Hex()
93
-	parentV1ID := ""
94
-	if parent != nil {
95
-		parentV1ID = parent.V1ID()
96
-	}
97
-
98
-	config, err := v1.MakeV1ConfigFromConfig(img, v1ID, parentV1ID, false)
99
-	if err != nil {
100
-		return nil, err
101
-	}
102
-
103
-	return &v1TopImage{
104
-		v1ImageCommon: v1ImageCommon{
105
-			v1ID:   v1ID,
106
-			config: config,
107
-			layer:  l,
108
-		},
109
-		imageID: imageID,
110
-	}, nil
111
-}
112
-
113
-// v1DependencyImage defines a dependency layer being pushed to a v1 registry.
114
-type v1DependencyImage struct {
115
-	v1ImageCommon
116
-}
117
-
118
-func newV1DependencyImage(l layer.Layer, parent *v1DependencyImage) *v1DependencyImage {
119
-	v1ID := digest.Digest(l.ChainID()).Hex()
120
-
121
-	var config string
122
-	if parent != nil {
123
-		config = fmt.Sprintf(`{"id":"%s","parent":"%s"}`, v1ID, parent.V1ID())
124
-	} else {
125
-		config = fmt.Sprintf(`{"id":"%s"}`, v1ID)
126
-	}
127
-	return &v1DependencyImage{
128
-		v1ImageCommon: v1ImageCommon{
129
-			v1ID:   v1ID,
130
-			config: []byte(config),
131
-			layer:  l,
132
-		},
133
-	}
134
-}
135
-
136
-// Retrieve the all the images to be uploaded in the correct order
137
-func (p *v1Pusher) getImageList() (imageList []v1Image, tagsByImage map[image.ID][]string, referencedLayers []PushLayer, err error) {
138
-	tagsByImage = make(map[image.ID][]string)
139
-
140
-	// Ignore digest references
141
-	if _, isCanonical := p.ref.(reference.Canonical); isCanonical {
142
-		return
143
-	}
144
-
145
-	tagged, isTagged := p.ref.(reference.NamedTagged)
146
-	if isTagged {
147
-		// Push a specific tag
148
-		var imgID image.ID
149
-		var dgst digest.Digest
150
-		dgst, err = p.config.ReferenceStore.Get(p.ref)
151
-		if err != nil {
152
-			return
153
-		}
154
-		imgID = image.IDFromDigest(dgst)
155
-
156
-		imageList, err = p.imageListForTag(imgID, nil, &referencedLayers)
157
-		if err != nil {
158
-			return
159
-		}
160
-
161
-		tagsByImage[imgID] = []string{tagged.Tag()}
162
-
163
-		return
164
-	}
165
-
166
-	imagesSeen := make(map[digest.Digest]struct{})
167
-	dependenciesSeen := make(map[layer.ChainID]*v1DependencyImage)
168
-
169
-	associations := p.config.ReferenceStore.ReferencesByName(p.ref)
170
-	for _, association := range associations {
171
-		if tagged, isTagged = association.Ref.(reference.NamedTagged); !isTagged {
172
-			// Ignore digest references.
173
-			continue
174
-		}
175
-
176
-		imgID := image.IDFromDigest(association.ID)
177
-		tagsByImage[imgID] = append(tagsByImage[imgID], tagged.Tag())
178
-
179
-		if _, present := imagesSeen[association.ID]; present {
180
-			// Skip generating image list for already-seen image
181
-			continue
182
-		}
183
-		imagesSeen[association.ID] = struct{}{}
184
-
185
-		imageListForThisTag, err := p.imageListForTag(imgID, dependenciesSeen, &referencedLayers)
186
-		if err != nil {
187
-			return nil, nil, nil, err
188
-		}
189
-
190
-		// append to main image list
191
-		imageList = append(imageList, imageListForThisTag...)
192
-	}
193
-	if len(imageList) == 0 {
194
-		return nil, nil, nil, fmt.Errorf("No images found for the requested repository / tag")
195
-	}
196
-	logrus.Debugf("Image list: %v", imageList)
197
-	logrus.Debugf("Tags by image: %v", tagsByImage)
198
-
199
-	return
200
-}
201
-
202
-func (p *v1Pusher) imageListForTag(imgID image.ID, dependenciesSeen map[layer.ChainID]*v1DependencyImage, referencedLayers *[]PushLayer) (imageListForThisTag []v1Image, err error) {
203
-	ics, ok := p.config.ImageStore.(*imageConfigStore)
204
-	if !ok {
205
-		return nil, fmt.Errorf("only image store images supported for v1 push")
206
-	}
207
-	img, err := ics.Store.Get(imgID)
208
-	if err != nil {
209
-		return nil, err
210
-	}
211
-
212
-	topLayerID := img.RootFS.ChainID()
213
-
214
-	if !system.IsOSSupported(img.OperatingSystem()) {
215
-		return nil, system.ErrNotSupportedOperatingSystem
216
-	}
217
-	pl, err := p.config.LayerStores[img.OperatingSystem()].Get(topLayerID)
218
-	*referencedLayers = append(*referencedLayers, pl)
219
-	if err != nil {
220
-		return nil, fmt.Errorf("failed to get top layer from image: %v", err)
221
-	}
222
-
223
-	// V1 push is deprecated, only support existing layerstore layers
224
-	lsl, ok := pl.(*storeLayer)
225
-	if !ok {
226
-		return nil, fmt.Errorf("only layer store layers supported for v1 push")
227
-	}
228
-	l := lsl.Layer
229
-
230
-	dependencyImages, parent := generateDependencyImages(l.Parent(), dependenciesSeen)
231
-
232
-	topImage, err := newV1TopImage(imgID, img, l, parent)
233
-	if err != nil {
234
-		return nil, err
235
-	}
236
-
237
-	imageListForThisTag = append(dependencyImages, topImage)
238
-
239
-	return
240
-}
241
-
242
-func generateDependencyImages(l layer.Layer, dependenciesSeen map[layer.ChainID]*v1DependencyImage) (imageListForThisTag []v1Image, parent *v1DependencyImage) {
243
-	if l == nil {
244
-		return nil, nil
245
-	}
246
-
247
-	imageListForThisTag, parent = generateDependencyImages(l.Parent(), dependenciesSeen)
248
-
249
-	if dependenciesSeen != nil {
250
-		if dependencyImage, present := dependenciesSeen[l.ChainID()]; present {
251
-			// This layer is already on the list, we can ignore it
252
-			// and all its parents.
253
-			return imageListForThisTag, dependencyImage
254
-		}
255
-	}
256
-
257
-	dependencyImage := newV1DependencyImage(l, parent)
258
-	imageListForThisTag = append(imageListForThisTag, dependencyImage)
259
-
260
-	if dependenciesSeen != nil {
261
-		dependenciesSeen[l.ChainID()] = dependencyImage
262
-	}
263
-
264
-	return imageListForThisTag, dependencyImage
265
-}
266
-
267
-// createImageIndex returns an index of an image's layer IDs and tags.
268
-func createImageIndex(images []v1Image, tags map[image.ID][]string) []*registry.ImgData {
269
-	var imageIndex []*registry.ImgData
270
-	for _, img := range images {
271
-		v1ID := img.V1ID()
272
-
273
-		if topImage, isTopImage := img.(*v1TopImage); isTopImage {
274
-			if tags, hasTags := tags[topImage.imageID]; hasTags {
275
-				// If an image has tags you must add an entry in the image index
276
-				// for each tag
277
-				for _, tag := range tags {
278
-					imageIndex = append(imageIndex, &registry.ImgData{
279
-						ID:  v1ID,
280
-						Tag: tag,
281
-					})
282
-				}
283
-				continue
284
-			}
285
-		}
286
-
287
-		// If the image does not have a tag it still needs to be sent to the
288
-		// registry with an empty tag so that it is associated with the repository
289
-		imageIndex = append(imageIndex, &registry.ImgData{
290
-			ID:  v1ID,
291
-			Tag: "",
292
-		})
293
-	}
294
-	return imageIndex
295
-}
296
-
297
-// lookupImageOnEndpoint checks the specified endpoint to see if an image exists
298
-// and if it is absent then it sends the image id to the channel to be pushed.
299
-func (p *v1Pusher) lookupImageOnEndpoint(wg *sync.WaitGroup, endpoint string, images chan v1Image, imagesToPush chan string) {
300
-	defer wg.Done()
301
-	for image := range images {
302
-		v1ID := image.V1ID()
303
-		truncID := stringid.TruncateID(image.Layer().DiffID().String())
304
-		if err := p.session.LookupRemoteImage(v1ID, endpoint); err != nil {
305
-			logrus.Errorf("Error in LookupRemoteImage: %s", err)
306
-			imagesToPush <- v1ID
307
-			progress.Update(p.config.ProgressOutput, truncID, "Waiting")
308
-		} else {
309
-			progress.Update(p.config.ProgressOutput, truncID, "Already exists")
310
-		}
311
-	}
312
-}
313
-
314
-func (p *v1Pusher) pushImageToEndpoint(ctx context.Context, endpoint string, imageList []v1Image, tags map[image.ID][]string, repo *registry.RepositoryData) error {
315
-	workerCount := len(imageList)
316
-	// start a maximum of 5 workers to check if images exist on the specified endpoint.
317
-	if workerCount > 5 {
318
-		workerCount = 5
319
-	}
320
-	var (
321
-		wg           = &sync.WaitGroup{}
322
-		imageData    = make(chan v1Image, workerCount*2)
323
-		imagesToPush = make(chan string, workerCount*2)
324
-		pushes       = make(chan map[string]struct{}, 1)
325
-	)
326
-	for i := 0; i < workerCount; i++ {
327
-		wg.Add(1)
328
-		go p.lookupImageOnEndpoint(wg, endpoint, imageData, imagesToPush)
329
-	}
330
-	// start a go routine that consumes the images to push
331
-	go func() {
332
-		shouldPush := make(map[string]struct{})
333
-		for id := range imagesToPush {
334
-			shouldPush[id] = struct{}{}
335
-		}
336
-		pushes <- shouldPush
337
-	}()
338
-	for _, v1Image := range imageList {
339
-		imageData <- v1Image
340
-	}
341
-	// close the channel to notify the workers that there will be no more images to check.
342
-	close(imageData)
343
-	wg.Wait()
344
-	close(imagesToPush)
345
-	// wait for all the images that require pushes to be collected into a consumable map.
346
-	shouldPush := <-pushes
347
-	// finish by pushing any images and tags to the endpoint.  The order that the images are pushed
348
-	// is very important that is why we are still iterating over the ordered list of imageIDs.
349
-	for _, img := range imageList {
350
-		v1ID := img.V1ID()
351
-		if _, push := shouldPush[v1ID]; push {
352
-			if _, err := p.pushImage(ctx, img, endpoint); err != nil {
353
-				// FIXME: Continue on error?
354
-				return err
355
-			}
356
-		}
357
-		if topImage, isTopImage := img.(*v1TopImage); isTopImage {
358
-			for _, tag := range tags[topImage.imageID] {
359
-				progress.Messagef(p.config.ProgressOutput, "", "Pushing tag for rev [%s] on {%s}", stringid.TruncateID(v1ID), endpoint+"repositories/"+reference.Path(p.repoInfo.Name)+"/tags/"+tag)
360
-				if err := p.session.PushRegistryTag(p.repoInfo.Name, v1ID, tag, endpoint); err != nil {
361
-					return err
362
-				}
363
-			}
364
-		}
365
-	}
366
-	return nil
367
-}
368
-
369
-// pushRepository pushes layers that do not already exist on the registry.
370
-func (p *v1Pusher) pushRepository(ctx context.Context) error {
371
-	imgList, tags, referencedLayers, err := p.getImageList()
372
-	defer func() {
373
-		for _, l := range referencedLayers {
374
-			l.Release()
375
-		}
376
-	}()
377
-	if err != nil {
378
-		return err
379
-	}
380
-
381
-	imageIndex := createImageIndex(imgList, tags)
382
-	for _, data := range imageIndex {
383
-		logrus.Debugf("Pushing ID: %s with Tag: %s", data.ID, data.Tag)
384
-	}
385
-
386
-	// Register all the images in a repository with the registry
387
-	// If an image is not in this list it will not be associated with the repository
388
-	repoData, err := p.session.PushImageJSONIndex(p.repoInfo.Name, imageIndex, false, nil)
389
-	if err != nil {
390
-		return err
391
-	}
392
-	// push the repository to each of the endpoints only if it does not exist.
393
-	for _, endpoint := range repoData.Endpoints {
394
-		if err := p.pushImageToEndpoint(ctx, endpoint, imgList, tags, repoData); err != nil {
395
-			return err
396
-		}
397
-	}
398
-	_, err = p.session.PushImageJSONIndex(p.repoInfo.Name, imageIndex, true, repoData.Endpoints)
399
-	return err
400
-}
401
-
402
-func (p *v1Pusher) pushImage(ctx context.Context, v1Image v1Image, ep string) (checksum string, err error) {
403
-	l := v1Image.Layer()
404
-	v1ID := v1Image.V1ID()
405
-	truncID := stringid.TruncateID(l.DiffID().String())
406
-
407
-	jsonRaw := v1Image.Config()
408
-	progress.Update(p.config.ProgressOutput, truncID, "Pushing")
409
-
410
-	// General rule is to use ID for graph accesses and compatibilityID for
411
-	// calls to session.registry()
412
-	imgData := &registry.ImgData{
413
-		ID: v1ID,
414
-	}
415
-
416
-	// Send the json
417
-	if err := p.session.PushImageJSONRegistry(imgData, jsonRaw, ep); err != nil {
418
-		if err == registry.ErrAlreadyExists {
419
-			progress.Update(p.config.ProgressOutput, truncID, "Image already pushed, skipping")
420
-			return "", nil
421
-		}
422
-		return "", err
423
-	}
424
-
425
-	arch, err := l.TarStream()
426
-	if err != nil {
427
-		return "", err
428
-	}
429
-	defer arch.Close()
430
-
431
-	// don't care if this fails; best effort
432
-	size, _ := l.DiffSize()
433
-
434
-	// Send the layer
435
-	logrus.Debugf("rendered layer for %s of [%d] size", v1ID, size)
436
-
437
-	reader := progress.NewProgressReader(ioutils.NewCancelReadCloser(ctx, arch), p.config.ProgressOutput, size, truncID, "Pushing")
438
-	defer reader.Close()
439
-
440
-	checksum, checksumPayload, err := p.session.PushImageLayerRegistry(v1ID, reader, ep, jsonRaw)
441
-	if err != nil {
442
-		return "", err
443
-	}
444
-	imgData.Checksum = checksum
445
-	imgData.ChecksumPayload = checksumPayload
446
-	// Send the checksum
447
-	if err := p.session.PushImageChecksumRegistry(imgData, ep); err != nil {
448
-		return "", err
449
-	}
450
-
451
-	if err := p.v1IDService.Set(v1ID, p.repoInfo.Index.Name, l.DiffID()); err != nil {
452
-		logrus.Warnf("Could not set v1 ID mapping: %v", err)
453
-	}
454
-
455
-	progress.Update(p.config.ProgressOutput, truncID, "Image successfully pushed")
456
-	return imgData.Checksum, nil
457
-}
... ...
@@ -92,7 +92,7 @@ func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig,
92 92
 		return nil, nil
93 93
 	}
94 94
 
95
-	regService, err := registry.NewService(registry.ServiceOptions{V2Only: true})
95
+	regService, err := registry.NewService(registry.ServiceOptions{})
96 96
 	if err != nil {
97 97
 		return err
98 98
 	}
... ...
@@ -19,16 +19,11 @@ type ServiceOptions struct {
19 19
 	AllowNondistributableArtifacts []string `json:"allow-nondistributable-artifacts,omitempty"`
20 20
 	Mirrors                        []string `json:"registry-mirrors,omitempty"`
21 21
 	InsecureRegistries             []string `json:"insecure-registries,omitempty"`
22
-
23
-	// V2Only controls access to legacy registries.  If it is set to true via the
24
-	// command line flag the daemon will not attempt to contact v1 legacy registries
25
-	V2Only bool `json:"disable-legacy-registry,omitempty"`
26 22
 }
27 23
 
28 24
 // serviceConfig holds daemon configuration for the registry service.
29 25
 type serviceConfig struct {
30 26
 	registrytypes.ServiceConfig
31
-	V2Only bool
32 27
 }
33 28
 
34 29
 var (
... ...
@@ -76,7 +71,6 @@ func newServiceConfig(options ServiceOptions) (*serviceConfig, error) {
76 76
 			// Hack: Bypass setting the mirrors to IndexConfigs since they are going away
77 77
 			// and Mirrors are only for the official registry anyways.
78 78
 		},
79
-		V2Only: options.V2Only,
80 79
 	}
81 80
 	if err := config.LoadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil {
82 81
 		return nil, err
... ...
@@ -309,20 +309,5 @@ func (s *DefaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn
309 309
 }
310 310
 
311 311
 func (s *DefaultService) lookupEndpoints(hostname string) (endpoints []APIEndpoint, err error) {
312
-	endpoints, err = s.lookupV2Endpoints(hostname)
313
-	if err != nil {
314
-		return nil, err
315
-	}
316
-
317
-	if s.config.V2Only {
318
-		return endpoints, nil
319
-	}
320
-
321
-	legacyEndpoints, err := s.lookupV1Endpoints(hostname)
322
-	if err != nil {
323
-		return nil, err
324
-	}
325
-	endpoints = append(endpoints, legacyEndpoints...)
326
-
327
-	return endpoints, nil
312
+	return s.lookupV2Endpoints(hostname)
328 313
 }
329 314
deleted file mode 100644
... ...
@@ -1,40 +0,0 @@
1
-package registry // import "github.com/docker/docker/registry"
2
-
3
-import "net/url"
4
-
5
-func (s *DefaultService) lookupV1Endpoints(hostname string) (endpoints []APIEndpoint, err error) {
6
-	if hostname == DefaultNamespace || hostname == DefaultV2Registry.Host || hostname == IndexHostname {
7
-		return []APIEndpoint{}, nil
8
-	}
9
-
10
-	tlsConfig, err := s.tlsConfig(hostname)
11
-	if err != nil {
12
-		return nil, err
13
-	}
14
-
15
-	endpoints = []APIEndpoint{
16
-		{
17
-			URL: &url.URL{
18
-				Scheme: "https",
19
-				Host:   hostname,
20
-			},
21
-			Version:      APIVersion1,
22
-			TrimHostname: true,
23
-			TLSConfig:    tlsConfig,
24
-		},
25
-	}
26
-
27
-	if tlsConfig.InsecureSkipVerify {
28
-		endpoints = append(endpoints, APIEndpoint{ // or this
29
-			URL: &url.URL{
30
-				Scheme: "http",
31
-				Host:   hostname,
32
-			},
33
-			Version:      APIVersion1,
34
-			TrimHostname: true,
35
-			// used to check if supposed to be secure via InsecureSkipVerify
36
-			TLSConfig: tlsConfig,
37
-		})
38
-	}
39
-	return endpoints, nil
40
-}
41 1
deleted file mode 100644
... ...
@@ -1,32 +0,0 @@
1
-package registry // import "github.com/docker/docker/registry"
2
-
3
-import (
4
-	"os"
5
-	"testing"
6
-
7
-	"gotest.tools/skip"
8
-)
9
-
10
-func TestLookupV1Endpoints(t *testing.T) {
11
-	skip.If(t, os.Getuid() != 0, "skipping test that requires root")
12
-	s, err := NewService(ServiceOptions{})
13
-	if err != nil {
14
-		t.Fatal(err)
15
-	}
16
-
17
-	cases := []struct {
18
-		hostname    string
19
-		expectedLen int
20
-	}{
21
-		{"example.com", 1},
22
-		{DefaultNamespace, 0},
23
-		{DefaultV2Registry.Host, 0},
24
-		{IndexHostname, 0},
25
-	}
26
-
27
-	for _, c := range cases {
28
-		if ret, err := s.lookupV1Endpoints(c.hostname); err != nil || len(ret) != c.expectedLen {
29
-			t.Errorf("lookupV1Endpoints(`"+c.hostname+"`) returned %+v and %+v", ret, err)
30
-		}
31
-	}
32
-}