Interacting with v1 registries was deprecated in Docker 1.8.3, disabled by default
in Docker 17.06, and scheduled for removal in Docker 17.12.
This patch disallows enabling V1 registry through the `--disable-legacy-registry`
option, and the `"disable-legacy-registry": false` option in the daemon configuration
file. The actual V1 registry code is still in place, and will be removed separately.
With this patch applied:
$ dockerd --disable-legacy-registry=false
ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported
Or, when setting through the `daemon.json` configuration file
$ mkdir -p /etc/docker/
$ echo '{"disable-legacy-registry":false}' > /etc/docker/daemon.json
$ dockerd
ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
... | ... |
@@ -92,6 +92,8 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag. |
92 | 92 |
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") |
93 | 93 |
|
94 | 94 |
if runtime.GOOS != "windows" { |
95 |
+ // TODO: Remove this flag after 3 release cycles (18.03) |
|
95 | 96 |
flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries") |
97 |
+ flags.MarkHidden("disable-legacy-registry") |
|
96 | 98 |
} |
97 | 99 |
} |
... | ... |
@@ -6,6 +6,7 @@ import ( |
6 | 6 |
"fmt" |
7 | 7 |
"os" |
8 | 8 |
"path/filepath" |
9 |
+ "runtime" |
|
9 | 10 |
"strings" |
10 | 11 |
"time" |
11 | 12 |
|
... | ... |
@@ -472,8 +473,15 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) { |
472 | 472 |
return nil, err |
473 | 473 |
} |
474 | 474 |
|
475 |
- if !conf.V2Only { |
|
476 |
- logrus.Warnf(`The "disable-legacy-registry" option is deprecated and wil be removed in Docker v17.12. Interacting with legacy (v1) registries will no longer be supported in Docker v17.12"`) |
|
475 |
+ if runtime.GOOS != "windows" { |
|
476 |
+ if flags.Changed("disable-legacy-registry") { |
|
477 |
+ // TODO: Remove this error after 3 release cycles (18.03) |
|
478 |
+ return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported") |
|
479 |
+ } |
|
480 |
+ if !conf.V2Only { |
|
481 |
+ // TODO: Remove this error after 3 release cycles (18.03) |
|
482 |
+ return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported") |
|
483 |
+ } |
|
477 | 484 |
} |
478 | 485 |
|
479 | 486 |
if flags.Changed("graph") { |
... | ... |
@@ -97,15 +97,3 @@ func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) { |
97 | 97 |
|
98 | 98 |
assert.True(t, loadedConfig.EnableUserlandProxy) |
99 | 99 |
} |
100 |
- |
|
101 |
-func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) { |
|
102 |
- content := `{"disable-legacy-registry": false}` |
|
103 |
- tempFile := fs.NewFile(t, "config", fs.WithContent(content)) |
|
104 |
- defer tempFile.Remove() |
|
105 |
- |
|
106 |
- opts := defaultOptions(tempFile.Path()) |
|
107 |
- loadedConfig, err := loadDaemonCliConfig(opts) |
|
108 |
- require.NoError(t, err) |
|
109 |
- require.NotNil(t, loadedConfig) |
|
110 |
- assert.False(t, loadedConfig.V2Only) |
|
111 |
-} |
... | ... |
@@ -13,9 +13,7 @@ import ( |
13 | 13 |
) |
14 | 14 |
|
15 | 15 |
func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C) { |
16 |
- |
|
17 |
- // @TODO TestLogoutWithExternalAuth expects docker to fall back to a v1 registry, so has to be updated for v17.12, when v1 registries are no longer supported |
|
18 |
- s.d.StartWithBusybox(c, "--disable-legacy-registry=false") |
|
16 |
+ s.d.StartWithBusybox(c) |
|
19 | 17 |
|
20 | 18 |
osPath := os.Getenv("PATH") |
21 | 19 |
defer os.Setenv("PATH", osPath) |
... | ... |
@@ -62,7 +60,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C) |
62 | 62 |
// check I cannot pull anymore |
63 | 63 |
out, err := s.d.Cmd("--config", tmp, "pull", repoName) |
64 | 64 |
c.Assert(err, check.NotNil, check.Commentf(out)) |
65 |
- c.Assert(out, checker.Contains, "Error: image dockercli/busybox:authtest not found") |
|
65 |
+ c.Assert(out, checker.Contains, "no basic auth credentials") |
|
66 | 66 |
} |
67 | 67 |
|
68 | 68 |
// #23100 |
... | ... |
@@ -259,18 +259,6 @@ func (s *DockerHubPullSuite) TestPullClientDisconnect(c *check.C) { |
259 | 259 |
c.Assert(err, checker.NotNil, check.Commentf("image was pulled after client disconnected")) |
260 | 260 |
} |
261 | 261 |
|
262 |
-func (s *DockerRegistryAuthHtpasswdSuite) TestPullNoCredentialsNotFound(c *check.C) { |
|
263 |
- // @TODO TestPullNoCredentialsNotFound expects docker to fall back to a v1 registry, so has to be updated for v17.12, when v1 registries are no longer supported |
|
264 |
- s.d.StartWithBusybox(c, "--disable-legacy-registry=false") |
|
265 |
- |
|
266 |
- // we don't care about the actual image, we just want to see image not found |
|
267 |
- // because that means v2 call returned 401 and we fell back to v1 which usually |
|
268 |
- // gives a 404 (in this case the test registry doesn't handle v1 at all) |
|
269 |
- out, err := s.d.Cmd("pull", privateRegistryURL+"/busybox") |
|
270 |
- c.Assert(err, check.NotNil, check.Commentf(out)) |
|
271 |
- c.Assert(out, checker.Contains, "Error: image busybox:latest not found") |
|
272 |
-} |
|
273 |
- |
|
274 | 262 |
// Regression test for https://github.com/docker/docker/issues/26429 |
275 | 263 |
func (s *DockerSuite) TestPullLinuxImageFailsOnWindows(c *check.C) { |
276 | 264 |
testRequires(c, DaemonIsWindows, Network) |
... | ... |
@@ -22,7 +22,7 @@ func makefile(path string, contents string) (string, error) { |
22 | 22 |
return f.Name(), nil |
23 | 23 |
} |
24 | 24 |
|
25 |
-// TestV2Only ensures that a daemon by default does not |
|
25 |
+// TestV2Only ensures that a daemon does not |
|
26 | 26 |
// attempt to contact any v1 registry endpoints. |
27 | 27 |
func (s *DockerRegistrySuite) TestV2Only(c *check.C) { |
28 | 28 |
reg, err := registry.NewMock(c) |
... | ... |
@@ -56,65 +56,3 @@ func (s *DockerRegistrySuite) TestV2Only(c *check.C) { |
56 | 56 |
s.d.Cmd("push", repoName) |
57 | 57 |
s.d.Cmd("pull", repoName) |
58 | 58 |
} |
59 |
- |
|
60 |
-// TestV1 starts a daemon with legacy registries enabled |
|
61 |
-// and ensure v1 endpoints are hit for the following operations: |
|
62 |
-// login, push, pull, build & run |
|
63 |
-func (s *DockerRegistrySuite) TestV1(c *check.C) { |
|
64 |
- reg, err := registry.NewMock(c) |
|
65 |
- defer reg.Close() |
|
66 |
- c.Assert(err, check.IsNil) |
|
67 |
- |
|
68 |
- v2Pings := 0 |
|
69 |
- reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) { |
|
70 |
- v2Pings++ |
|
71 |
- // V2 ping 404 causes fallback to v1 |
|
72 |
- w.WriteHeader(404) |
|
73 |
- }) |
|
74 |
- |
|
75 |
- v1Pings := 0 |
|
76 |
- reg.RegisterHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) { |
|
77 |
- v1Pings++ |
|
78 |
- }) |
|
79 |
- |
|
80 |
- v1Logins := 0 |
|
81 |
- reg.RegisterHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) { |
|
82 |
- v1Logins++ |
|
83 |
- }) |
|
84 |
- |
|
85 |
- v1Repo := 0 |
|
86 |
- reg.RegisterHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) { |
|
87 |
- v1Repo++ |
|
88 |
- }) |
|
89 |
- |
|
90 |
- reg.RegisterHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) { |
|
91 |
- v1Repo++ |
|
92 |
- }) |
|
93 |
- |
|
94 |
- s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=false") |
|
95 |
- |
|
96 |
- tmp, err := ioutil.TempDir("", "integration-cli-") |
|
97 |
- c.Assert(err, check.IsNil) |
|
98 |
- defer os.RemoveAll(tmp) |
|
99 |
- |
|
100 |
- dockerfileName, err := makefile(tmp, fmt.Sprintf("FROM %s/busybox", reg.URL())) |
|
101 |
- c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile")) |
|
102 |
- |
|
103 |
- s.d.Cmd("build", "--file", dockerfileName, tmp) |
|
104 |
- c.Assert(v1Repo, check.Equals, 1, check.Commentf("Expected v1 repository access after build")) |
|
105 |
- |
|
106 |
- repoName := fmt.Sprintf("%s/busybox", reg.URL()) |
|
107 |
- s.d.Cmd("run", repoName) |
|
108 |
- c.Assert(v1Repo, check.Equals, 2, check.Commentf("Expected v1 repository access after run")) |
|
109 |
- |
|
110 |
- s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.URL()) |
|
111 |
- c.Assert(v1Logins, check.Equals, 1, check.Commentf("Expected v1 login attempt")) |
|
112 |
- |
|
113 |
- s.d.Cmd("tag", "busybox", repoName) |
|
114 |
- s.d.Cmd("push", repoName) |
|
115 |
- |
|
116 |
- c.Assert(v1Repo, check.Equals, 2) |
|
117 |
- |
|
118 |
- s.d.Cmd("pull", repoName) |
|
119 |
- c.Assert(v1Repo, check.Equals, 3, check.Commentf("Expected v1 repository access after pull")) |
|
120 |
-} |