Browse code

api: remove handling of HostConfig on POST /containers/{id}/start (api < v1.24)

API v1.20 (Docker Engine v1.11.0) and older allowed a HostConfig to be passed
when starting a container. This feature was deprecated in API v1.21 (Docker
Engine v1.10.0) in 3e7405aea8589f4b6b0713640596f7dee9cf7193, and removed in
API v1.23 (Docker Engine v1.12.0) in commit 0a8386c8be3fa87b7523bef7fd31c81a7f84709c.

API v1.23 and older are deprecated, and this patch removes the feature.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2024/01/22 01:52:05
Showing 17 changed files
... ...
@@ -12,5 +12,4 @@ import (
12 12
 // container configuration.
13 13
 type ContainerDecoder interface {
14 14
 	DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error)
15
-	DecodeHostConfig(src io.Reader) (*container.HostConfig, error)
16 15
 }
... ...
@@ -38,7 +38,7 @@ type stateBackend interface {
38 38
 	ContainerResize(name string, height, width int) error
39 39
 	ContainerRestart(ctx context.Context, name string, options container.StopOptions) error
40 40
 	ContainerRm(name string, config *backend.ContainerRmConfig) error
41
-	ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
41
+	ContainerStart(ctx context.Context, name string, checkpoint string, checkpointDir string) error
42 42
 	ContainerStop(ctx context.Context, name string, options container.StopOptions) error
43 43
 	ContainerUnpause(name string) error
44 44
 	ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error)
... ...
@@ -168,14 +168,6 @@ func (s *containerRouter) getContainersExport(ctx context.Context, w http.Respon
168 168
 	return s.backend.ContainerExport(ctx, vars["name"], w)
169 169
 }
170 170
 
171
-type bodyOnStartError struct{}
172
-
173
-func (bodyOnStartError) Error() string {
174
-	return "starting container with non-empty request body was deprecated since API v1.22 and removed in v1.24"
175
-}
176
-
177
-func (bodyOnStartError) InvalidParameter() {}
178
-
179 171
 func (s *containerRouter) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
180 172
 	// If contentLength is -1, we can assumed chunked encoding
181 173
 	// or more technically that the length is unknown
... ...
@@ -183,33 +175,17 @@ func (s *containerRouter) postContainersStart(ctx context.Context, w http.Respon
183 183
 	// net/http otherwise seems to swallow any headers related to chunked encoding
184 184
 	// including r.TransferEncoding
185 185
 	// allow a nil body for backwards compatibility
186
-
187
-	version := httputils.VersionFromContext(ctx)
188
-	var hostConfig *container.HostConfig
186
+	//
189 187
 	// A non-nil json object is at least 7 characters.
190 188
 	if r.ContentLength > 7 || r.ContentLength == -1 {
191
-		if versions.GreaterThanOrEqualTo(version, "1.24") {
192
-			return bodyOnStartError{}
193
-		}
194
-
195
-		if err := httputils.CheckForJSON(r); err != nil {
196
-			return err
197
-		}
198
-
199
-		c, err := s.decoder.DecodeHostConfig(r.Body)
200
-		if err != nil {
201
-			return err
202
-		}
203
-		hostConfig = c
189
+		return errdefs.InvalidParameter(errors.New("starting container with non-empty request body was deprecated since API v1.22 and removed in v1.24"))
204 190
 	}
205 191
 
206 192
 	if err := httputils.ParseForm(r); err != nil {
207 193
 		return err
208 194
 	}
209 195
 
210
-	checkpoint := r.Form.Get("checkpoint")
211
-	checkpointDir := r.Form.Get("checkpoint-dir")
212
-	if err := s.backend.ContainerStart(ctx, vars["name"], hostConfig, checkpoint, checkpointDir); err != nil {
196
+	if err := s.backend.ContainerStart(ctx, vars["name"], r.Form.Get("checkpoint"), r.Form.Get("checkpoint-dir")); err != nil {
213 197
 		return err
214 198
 	}
215 199
 
... ...
@@ -64,7 +64,7 @@ type ExecBackend interface {
64 64
 	// ContainerRm removes a container specified by `id`.
65 65
 	ContainerRm(name string, config *backend.ContainerRmConfig) error
66 66
 	// ContainerStart starts a new container
67
-	ContainerStart(ctx context.Context, containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
67
+	ContainerStart(ctx context.Context, containerID string, checkpoint string, checkpointDir string) error
68 68
 	// ContainerWait stops processing until the given container is stopped.
69 69
 	ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error)
70 70
 }
... ...
@@ -72,7 +72,7 @@ func (c *containerManager) Run(ctx context.Context, cID string, stdout, stderr i
72 72
 		}
73 73
 	}()
74 74
 
75
-	if err := c.backend.ContainerStart(ctx, cID, nil, "", ""); err != nil {
75
+	if err := c.backend.ContainerStart(ctx, cID, "", ""); err != nil {
76 76
 		close(finished)
77 77
 		logCancellationError(cancelErrCh, "error from ContainerStart: "+err.Error())
78 78
 		return err
... ...
@@ -46,7 +46,7 @@ func (m *MockBackend) CommitBuildStep(ctx context.Context, c backend.CommitConfi
46 46
 	return "", nil
47 47
 }
48 48
 
49
-func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error {
49
+func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, checkpoint string, checkpointDir string) error {
50 50
 	return nil
51 51
 }
52 52
 
... ...
@@ -38,7 +38,7 @@ type Backend interface {
38 38
 	SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
39 39
 	ReleaseIngress() (<-chan struct{}, error)
40 40
 	CreateManagedContainer(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error)
41
-	ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
41
+	ContainerStart(ctx context.Context, name string, checkpoint string, checkpointDir string) error
42 42
 	ContainerStop(ctx context.Context, name string, config container.StopOptions) error
43 43
 	ContainerLogs(ctx context.Context, name string, config *container.LogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
44 44
 	ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
... ...
@@ -347,7 +347,7 @@ func (c *containerAdapter) start(ctx context.Context) error {
347 347
 		return err
348 348
 	}
349 349
 
350
-	return c.backend.ContainerStart(ctx, c.container.name(), nil, "", "")
350
+	return c.backend.ContainerStart(ctx, c.container.name(), "", "")
351 351
 }
352 352
 
353 353
 func (c *containerAdapter) inspect(ctx context.Context) (types.ContainerJSON, error) {
... ...
@@ -2,12 +2,10 @@ package daemon // import "github.com/docker/docker/daemon"
2 2
 
3 3
 import (
4 4
 	"context"
5
-	"runtime"
6 5
 	"time"
7 6
 
8 7
 	"github.com/containerd/log"
9 8
 	"github.com/docker/docker/api/types/backend"
10
-	containertypes "github.com/docker/docker/api/types/container"
11 9
 	"github.com/docker/docker/api/types/events"
12 10
 	"github.com/docker/docker/container"
13 11
 	"github.com/docker/docker/errdefs"
... ...
@@ -41,7 +39,7 @@ func validateState(ctr *container.Container) error {
41 41
 }
42 42
 
43 43
 // ContainerStart starts a container.
44
-func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
44
+func (daemon *Daemon) ContainerStart(ctx context.Context, name string, checkpoint string, checkpointDir string) error {
45 45
 	daemonCfg := daemon.config()
46 46
 	if checkpoint != "" && !daemonCfg.Experimental {
47 47
 		return errdefs.InvalidParameter(errors.New("checkpoint is only supported in experimental mode"))
... ...
@@ -55,51 +53,12 @@ func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfi
55 55
 		return err
56 56
 	}
57 57
 
58
-	// Windows does not have the backwards compatibility issue here.
59
-	if runtime.GOOS != "windows" {
60
-		// This is kept for backward compatibility - hostconfig should be passed when
61
-		// creating a container, not during start.
62
-		if hostConfig != nil {
63
-			log.G(ctx).Warn("DEPRECATED: Setting host configuration options when the container starts is deprecated and has been removed in Docker 1.12")
64
-			oldNetworkMode := ctr.HostConfig.NetworkMode
65
-			if err := daemon.setSecurityOptions(&daemonCfg.Config, ctr, hostConfig); err != nil {
66
-				return errdefs.InvalidParameter(err)
67
-			}
68
-			if err := daemon.mergeAndVerifyLogConfig(&hostConfig.LogConfig); err != nil {
69
-				return errdefs.InvalidParameter(err)
70
-			}
71
-			if err := daemon.setHostConfig(ctr, hostConfig); err != nil {
72
-				return errdefs.InvalidParameter(err)
73
-			}
74
-			newNetworkMode := ctr.HostConfig.NetworkMode
75
-			if string(oldNetworkMode) != string(newNetworkMode) {
76
-				// if user has change the network mode on starting, clean up the
77
-				// old networks. It is a deprecated feature and has been removed in Docker 1.12
78
-				ctr.NetworkSettings.Networks = nil
79
-			}
80
-			if err := ctr.CheckpointTo(daemon.containersReplica); err != nil {
81
-				return errdefs.System(err)
82
-			}
83
-			ctr.InitDNSHostConfig()
84
-		}
85
-	} else {
86
-		if hostConfig != nil {
87
-			return errdefs.InvalidParameter(errors.New("Supplying a hostconfig on start is not supported. It should be supplied on create"))
88
-		}
89
-	}
90
-
91 58
 	// check if hostConfig is in line with the current system settings.
92
-	// It may happen cgroups are umounted or the like.
59
+	// It may happen cgroups are unmounted or the like.
93 60
 	if _, err = daemon.verifyContainerSettings(daemonCfg, ctr.HostConfig, nil, false); err != nil {
94 61
 		return errdefs.InvalidParameter(err)
95 62
 	}
96
-	// Adapt for old containers in case we have updates in this function and
97
-	// old containers never have chance to call the new function in create stage.
98
-	if hostConfig != nil {
99
-		if err := daemon.adaptContainerSettings(&daemonCfg.Config, ctr.HostConfig); err != nil {
100
-			return errdefs.InvalidParameter(err)
101
-		}
102
-	}
63
+
103 64
 	return daemon.containerStart(ctx, daemonCfg, ctr, checkpoint, checkpointDir, true)
104 65
 }
105 66
 
106 67
deleted file mode 100644
... ...
@@ -1,239 +0,0 @@
1
-// This file will be removed when we completely drop support for
2
-// passing HostConfig to container start API.
3
-
4
-package main
5
-
6
-import (
7
-	"net/http"
8
-	"strings"
9
-	"testing"
10
-
11
-	"github.com/docker/docker/integration-cli/cli"
12
-	"github.com/docker/docker/testutil"
13
-	"github.com/docker/docker/testutil/request"
14
-	"gotest.tools/v3/assert"
15
-	is "gotest.tools/v3/assert/cmp"
16
-)
17
-
18
-func formatV123StartAPIURL(url string) string {
19
-	return "/v1.23" + url
20
-}
21
-
22
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartHostConfig(c *testing.T) {
23
-	name := "test-deprecated-api-124"
24
-	cli.DockerCmd(c, "create", "--name", name, "busybox")
25
-	config := map[string]interface{}{
26
-		"Binds": []string{"/aa:/bb"},
27
-	}
28
-	res, body, err := request.Post(testutil.GetContext(c), "/containers/"+name+"/start", request.JSONBody(config))
29
-	assert.NilError(c, err)
30
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
31
-	buf, err := request.ReadBody(body)
32
-	assert.NilError(c, err)
33
-
34
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
35
-	assert.Assert(c, strings.Contains(string(buf), "was deprecated since API v1.22"))
36
-}
37
-
38
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartVolumeBinds(c *testing.T) {
39
-	// TODO Windows CI: Investigate further why this fails on Windows to Windows CI.
40
-	testRequires(c, DaemonIsLinux)
41
-	path := "/foo"
42
-	if testEnv.DaemonInfo.OSType == "windows" {
43
-		path = `c:\foo`
44
-	}
45
-	name := "testing"
46
-	config := map[string]interface{}{
47
-		"Image":   "busybox",
48
-		"Volumes": map[string]struct{}{path: {}},
49
-	}
50
-
51
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
52
-	assert.NilError(c, err)
53
-	assert.Equal(c, res.StatusCode, http.StatusCreated)
54
-
55
-	bindPath := RandomTmpDirPath("test", testEnv.DaemonInfo.OSType)
56
-	config = map[string]interface{}{
57
-		"Binds": []string{bindPath + ":" + path},
58
-	}
59
-	res, _, err = request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
60
-	assert.NilError(c, err)
61
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
62
-
63
-	pth, err := inspectMountSourceField(name, path)
64
-	assert.NilError(c, err)
65
-	assert.Equal(c, pth, bindPath, "expected volume host path to be %s, got %s", bindPath, pth)
66
-}
67
-
68
-// Test for GH#10618
69
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartDupVolumeBinds(c *testing.T) {
70
-	// TODO Windows to Windows CI - Port this
71
-	testRequires(c, DaemonIsLinux)
72
-	name := "testdups"
73
-	config := map[string]interface{}{
74
-		"Image":   "busybox",
75
-		"Volumes": map[string]struct{}{"/tmp": {}},
76
-	}
77
-
78
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
79
-	assert.NilError(c, err)
80
-	assert.Equal(c, res.StatusCode, http.StatusCreated)
81
-
82
-	bindPath1 := RandomTmpDirPath("test1", testEnv.DaemonInfo.OSType)
83
-	bindPath2 := RandomTmpDirPath("test2", testEnv.DaemonInfo.OSType)
84
-
85
-	config = map[string]interface{}{
86
-		"Binds": []string{bindPath1 + ":/tmp", bindPath2 + ":/tmp"},
87
-	}
88
-	res, body, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
89
-	assert.NilError(c, err)
90
-
91
-	buf, err := request.ReadBody(body)
92
-	assert.NilError(c, err)
93
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
94
-	assert.Assert(c, strings.Contains(string(buf), "Duplicate mount point"), "Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(buf), err)
95
-}
96
-
97
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartVolumesFrom(c *testing.T) {
98
-	// TODO Windows to Windows CI - Port this
99
-	testRequires(c, DaemonIsLinux)
100
-	volName := "voltst"
101
-	volPath := "/tmp"
102
-
103
-	cli.DockerCmd(c, "run", "--name", volName, "-v", volPath, "busybox")
104
-
105
-	name := "TestContainerAPIStartVolumesFrom"
106
-	config := map[string]interface{}{
107
-		"Image":   "busybox",
108
-		"Volumes": map[string]struct{}{volPath: {}},
109
-	}
110
-
111
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
112
-	assert.NilError(c, err)
113
-	assert.Equal(c, res.StatusCode, http.StatusCreated)
114
-
115
-	config = map[string]interface{}{
116
-		"VolumesFrom": []string{volName},
117
-	}
118
-	res, _, err = request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
119
-	assert.NilError(c, err)
120
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
121
-
122
-	pth, err := inspectMountSourceField(name, volPath)
123
-	assert.NilError(c, err)
124
-	pth2, err := inspectMountSourceField(volName, volPath)
125
-	assert.NilError(c, err)
126
-	assert.Equal(c, pth, pth2, "expected volume host path to be %s, got %s", pth, pth2)
127
-}
128
-
129
-// #9981 - Allow a docker created volume (ie, one in /var/lib/docker/volumes) to be used to overwrite (via passing in Binds on api start) an existing volume
130
-func (s *DockerAPISuite) TestDeprecatedPostContainerBindNormalVolume(c *testing.T) {
131
-	// TODO Windows to Windows CI - Port this
132
-	testRequires(c, DaemonIsLinux)
133
-	cli.DockerCmd(c, "create", "-v", "/foo", "--name=one", "busybox")
134
-
135
-	fooDir, err := inspectMountSourceField("one", "/foo")
136
-	assert.NilError(c, err)
137
-
138
-	cli.DockerCmd(c, "create", "-v", "/foo", "--name=two", "busybox")
139
-
140
-	bindSpec := map[string][]string{"Binds": {fooDir + ":/foo"}}
141
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/two/start"), request.JSONBody(bindSpec))
142
-	assert.NilError(c, err)
143
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
144
-
145
-	fooDir2, err := inspectMountSourceField("two", "/foo")
146
-	assert.NilError(c, err)
147
-	assert.Equal(c, fooDir2, fooDir, "expected volume path to be %s, got: %s", fooDir, fooDir2)
148
-}
149
-
150
-func (s *DockerAPISuite) TestDeprecatedStartWithTooLowMemoryLimit(c *testing.T) {
151
-	// TODO Windows: Port once memory is supported
152
-	testRequires(c, DaemonIsLinux)
153
-	containerID := cli.DockerCmd(c, "create", "busybox").Stdout()
154
-	containerID = strings.TrimSpace(containerID)
155
-
156
-	const config = `{
157
-                "CpuShares": 100,
158
-                "Memory":    524287
159
-        }`
160
-
161
-	res, body, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+containerID+"/start"), request.RawString(config), request.JSON)
162
-	assert.NilError(c, err)
163
-	b, err := request.ReadBody(body)
164
-	assert.NilError(c, err)
165
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
166
-	assert.Assert(c, is.Contains(string(b), "Minimum memory limit allowed is 6MB"))
167
-}
168
-
169
-// #14640
170
-func (s *DockerAPISuite) TestDeprecatedPostContainersStartWithoutLinksInHostConfig(c *testing.T) {
171
-	// TODO Windows: Windows doesn't support supplying a hostconfig on start.
172
-	// An alternate test could be written to validate the negative testing aspect of this
173
-	testRequires(c, DaemonIsLinux)
174
-	name := "test-host-config-links"
175
-	cli.DockerCmd(c, append([]string{"create", "--name", name, "busybox"}, sleepCommandForDaemonPlatform()...)...)
176
-
177
-	hc := inspectFieldJSON(c, name, "HostConfig")
178
-	config := `{"HostConfig":` + hc + `}`
179
-
180
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.RawString(config), request.JSON)
181
-	assert.NilError(c, err)
182
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
183
-	b.Close()
184
-}
185
-
186
-// #14640
187
-func (s *DockerAPISuite) TestDeprecatedPostContainersStartWithLinksInHostConfig(c *testing.T) {
188
-	// TODO Windows: Windows doesn't support supplying a hostconfig on start.
189
-	// An alternate test could be written to validate the negative testing aspect of this
190
-	testRequires(c, DaemonIsLinux)
191
-	name := "test-host-config-links"
192
-	cli.DockerCmd(c, "run", "--name", "foo", "-d", "busybox", "top")
193
-	cli.DockerCmd(c, "create", "--name", name, "--link", "foo:bar", "busybox", "top")
194
-
195
-	hc := inspectFieldJSON(c, name, "HostConfig")
196
-	config := `{"HostConfig":` + hc + `}`
197
-
198
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.RawString(config), request.JSON)
199
-	assert.NilError(c, err)
200
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
201
-	b.Close()
202
-}
203
-
204
-// #14640
205
-func (s *DockerAPISuite) TestDeprecatedPostContainersStartWithLinksInHostConfigIdLinked(c *testing.T) {
206
-	// Windows does not support links
207
-	testRequires(c, DaemonIsLinux)
208
-	const name = "test-host-config-links"
209
-	containerID := cli.DockerCmd(c, "run", "--name", "link0", "-d", "busybox", "top").Combined()
210
-	containerID = strings.TrimSpace(containerID)
211
-	defer cli.DockerCmd(c, "stop", "link0")
212
-	cli.DockerCmd(c, "create", "--name", name, "--link", containerID, "busybox", "top")
213
-	defer cli.DockerCmd(c, "stop", name)
214
-
215
-	hc := inspectFieldJSON(c, name, "HostConfig")
216
-	config := `{"HostConfig":` + hc + `}`
217
-
218
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.RawString(config), request.JSON)
219
-	assert.NilError(c, err)
220
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
221
-	b.Close()
222
-}
223
-
224
-func (s *DockerAPISuite) TestDeprecatedStartWithNilDNS(c *testing.T) {
225
-	// TODO Windows: Add once DNS is supported
226
-	testRequires(c, DaemonIsLinux)
227
-	containerID := cli.DockerCmd(c, "create", "busybox").Stdout()
228
-	containerID = strings.TrimSpace(containerID)
229
-
230
-	const config = `{"HostConfig": {"Dns": null}}`
231
-
232
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+containerID+"/start"), request.RawString(config), request.JSON)
233
-	assert.NilError(c, err)
234
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
235
-	b.Close()
236
-
237
-	dns := inspectFieldJSON(c, containerID, "HostConfig.Dns")
238
-	assert.Equal(c, dns, "[]")
239
-}
240 1
deleted file mode 100644
... ...
@@ -1,33 +0,0 @@
1
-//go:build !windows
2
-
3
-package main
4
-
5
-import (
6
-	"strings"
7
-	"testing"
8
-
9
-	"github.com/docker/docker/integration-cli/cli"
10
-	"github.com/docker/docker/testutil"
11
-	"github.com/docker/docker/testutil/request"
12
-	"gotest.tools/v3/assert"
13
-)
14
-
15
-// #19100 This is a deprecated feature test, it should be removed in Docker 1.12
16
-func (s *DockerNetworkSuite) TestDeprecatedDockerNetworkStartAPIWithHostconfig(c *testing.T) {
17
-	const netName = "test"
18
-	const conName = "foo"
19
-	cli.DockerCmd(c, "network", "create", netName)
20
-	cli.DockerCmd(c, "create", "--name", conName, "busybox", "top")
21
-
22
-	config := map[string]interface{}{
23
-		"HostConfig": map[string]interface{}{
24
-			"NetworkMode": netName,
25
-		},
26
-	}
27
-	_, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+conName+"/start"), request.JSONBody(config))
28
-	assert.NilError(c, err)
29
-	cli.WaitRun(c, conName)
30
-	networks := inspectField(c, conName, "NetworkSettings.Networks")
31
-	assert.Assert(c, strings.Contains(networks, netName), "Should contain '%s' network", netName)
32
-	assert.Assert(c, !strings.Contains(networks, "bridge"), "Should not contain 'bridge' network")
33
-}
... ...
@@ -2,7 +2,6 @@ package container // import "github.com/docker/docker/integration/container"
2 2
 
3 3
 import (
4 4
 	"net/http"
5
-	"runtime"
6 5
 	"testing"
7 6
 
8 7
 	"github.com/docker/docker/testutil"
... ...
@@ -25,14 +24,6 @@ func TestContainerInvalidJSON(t *testing.T) {
25 25
 		"/exec/foobar/start",
26 26
 	}
27 27
 
28
-	// windows doesnt support API < v1.24
29
-	if runtime.GOOS != "windows" {
30
-		endpoints = append(
31
-			endpoints,
32
-			"/v1.23/containers/foobar/start", // accepts a body on API < v1.24
33
-		)
34
-	}
35
-
36 28
 	for _, ep := range endpoints {
37 29
 		ep := ep
38 30
 		t.Run(ep[1:], func(t *testing.T) {
... ...
@@ -27,11 +27,6 @@ func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *conta
27 27
 	return decodeContainerConfig(src, si)
28 28
 }
29 29
 
30
-// DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder
31
-func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
32
-	return decodeHostConfig(src)
33
-}
34
-
35 30
 // decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
36 31
 // struct and returns both a Config and a HostConfig struct, and performs some
37 32
 // validation. Certain parameters need daemon-side validation that cannot be done
38 33
deleted file mode 100644
... ...
@@ -1,18 +0,0 @@
1
-{
2
-    "Binds": ["/tmp:/tmp"],
3
-    "ContainerIDFile": "",
4
-    "LxcConf": [],
5
-    "Privileged": false,
6
-    "PortBindings": {
7
-        "80/tcp": [
8
-            {
9
-                "HostIp": "0.0.0.0",
10
-                "HostPort": "49153"
11
-            }
12
-        ]
13
-    },
14
-    "Links": ["/name:alias"],
15
-    "PublishAllPorts": false,
16
-    "CapAdd": ["NET_ADMIN"],
17
-    "CapDrop": ["MKNOD"]
18
-}
19 1
deleted file mode 100644
... ...
@@ -1,30 +0,0 @@
1
-{
2
-    "Binds": ["/tmp:/tmp"],
3
-    "Links": ["redis3:redis"],
4
-    "LxcConf": {"lxc.utsname":"docker"},
5
-    "Memory": 0,
6
-    "MemorySwap": 0,
7
-    "CpuShares": 512,
8
-    "CpuPeriod": 100000,
9
-    "CpusetCpus": "0,1",
10
-    "CpusetMems": "0,1",
11
-    "BlkioWeight": 300,
12
-    "OomKillDisable": false,
13
-    "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
14
-    "PublishAllPorts": false,
15
-    "Privileged": false,
16
-    "ReadonlyRootfs": false,
17
-    "Dns": ["8.8.8.8"],
18
-    "DnsSearch": [""],
19
-    "ExtraHosts": null,
20
-    "VolumesFrom": ["parent", "other:ro"],
21
-    "CapAdd": ["NET_ADMIN"],
22
-    "CapDrop": ["MKNOD"],
23
-    "RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
24
-    "NetworkMode": "bridge",
25
-    "Devices": [],
26
-    "Ulimits": [{}],
27
-    "LogConfig": { "Type": "json-file", "Config": {} },
28
-    "SecurityOpt": [""],
29
-    "CgroupParent": ""
30
-}
... ...
@@ -1,23 +1,12 @@
1 1
 package runconfig // import "github.com/docker/docker/runconfig"
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"strings"
6 5
 
7 6
 	"github.com/docker/docker/api/types/container"
8 7
 	"github.com/docker/docker/api/types/network"
9 8
 )
10 9
 
11
-// DecodeHostConfig creates a HostConfig based on the specified Reader.
12
-// It assumes the content of the reader will be JSON, and decodes it.
13
-func decodeHostConfig(src io.Reader) (*container.HostConfig, error) {
14
-	var w ContainerConfigWrapper
15
-	if err := loadJSON(src, &w); err != nil {
16
-		return nil, err
17
-	}
18
-	return w.getHostConfig(), nil
19
-}
20
-
21 10
 // SetDefaultNetModeIfBlank changes the NetworkMode in a HostConfig structure
22 11
 // to default if it is not populated. This ensures backwards compatibility after
23 12
 // the validation of the network mode was moved from the docker CLI to the
... ...
@@ -3,51 +3,12 @@
3 3
 package runconfig // import "github.com/docker/docker/runconfig"
4 4
 
5 5
 import (
6
-	"bytes"
7
-	"fmt"
8
-	"os"
9 6
 	"testing"
10 7
 
11 8
 	"github.com/docker/docker/api/types/container"
12 9
 	"github.com/docker/docker/pkg/sysinfo"
13
-	"gotest.tools/v3/assert"
14 10
 )
15 11
 
16
-func TestDecodeHostConfig(t *testing.T) {
17
-	fixtures := []struct {
18
-		file string
19
-	}{
20
-		{"fixtures/unix/container_hostconfig_1_14.json"},
21
-		{"fixtures/unix/container_hostconfig_1_19.json"},
22
-	}
23
-
24
-	for _, f := range fixtures {
25
-		b, err := os.ReadFile(f.file)
26
-		if err != nil {
27
-			t.Fatal(err)
28
-		}
29
-
30
-		c, err := decodeHostConfig(bytes.NewReader(b))
31
-		if err != nil {
32
-			t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
33
-		}
34
-
35
-		assert.Check(t, !c.Privileged)
36
-
37
-		if l := len(c.Binds); l != 1 {
38
-			t.Fatalf("Expected 1 bind, found %d\n", l)
39
-		}
40
-
41
-		if len(c.CapAdd) != 1 && c.CapAdd[0] != "NET_ADMIN" {
42
-			t.Fatalf("Expected CapAdd NET_ADMIN, got %v", c.CapAdd)
43
-		}
44
-
45
-		if len(c.CapDrop) != 1 && c.CapDrop[0] != "NET_ADMIN" {
46
-			t.Fatalf("Expected CapDrop NET_ADMIN, got %v", c.CapDrop)
47
-		}
48
-	}
49
-}
50
-
51 12
 func TestValidateResources(t *testing.T) {
52 13
 	type resourceTest struct {
53 14
 		ConfigCPURealtimePeriod  int64