Explorar o código

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 hai 1 ano
pai
achega
8758d08bb4

+ 0 - 1
api/server/httputils/decoder.go

@@ -12,5 +12,4 @@ import (
 // container configuration.
 // container configuration.
 type ContainerDecoder interface {
 type ContainerDecoder interface {
 	DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error)
 	DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error)
-	DecodeHostConfig(src io.Reader) (*container.HostConfig, error)
 }
 }

+ 1 - 1
api/server/router/container/backend.go

@@ -38,7 +38,7 @@ type stateBackend interface {
 	ContainerResize(name string, height, width int) error
 	ContainerResize(name string, height, width int) error
 	ContainerRestart(ctx context.Context, name string, options container.StopOptions) error
 	ContainerRestart(ctx context.Context, name string, options container.StopOptions) error
 	ContainerRm(name string, config *backend.ContainerRmConfig) error
 	ContainerRm(name string, config *backend.ContainerRmConfig) error
-	ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
+	ContainerStart(ctx context.Context, name string, checkpoint string, checkpointDir string) error
 	ContainerStop(ctx context.Context, name string, options container.StopOptions) error
 	ContainerStop(ctx context.Context, name string, options container.StopOptions) error
 	ContainerUnpause(name string) error
 	ContainerUnpause(name string) error
 	ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error)
 	ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error)

+ 3 - 27
api/server/router/container/container_routes.go

@@ -168,14 +168,6 @@ func (s *containerRouter) getContainersExport(ctx context.Context, w http.Respon
 	return s.backend.ContainerExport(ctx, vars["name"], w)
 	return s.backend.ContainerExport(ctx, vars["name"], w)
 }
 }
 
 
-type bodyOnStartError struct{}
-
-func (bodyOnStartError) Error() string {
-	return "starting container with non-empty request body was deprecated since API v1.22 and removed in v1.24"
-}
-
-func (bodyOnStartError) InvalidParameter() {}
-
 func (s *containerRouter) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 func (s *containerRouter) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	// If contentLength is -1, we can assumed chunked encoding
 	// If contentLength is -1, we can assumed chunked encoding
 	// or more technically that the length is unknown
 	// or more technically that the length is unknown
@@ -183,33 +175,17 @@ func (s *containerRouter) postContainersStart(ctx context.Context, w http.Respon
 	// net/http otherwise seems to swallow any headers related to chunked encoding
 	// net/http otherwise seems to swallow any headers related to chunked encoding
 	// including r.TransferEncoding
 	// including r.TransferEncoding
 	// allow a nil body for backwards compatibility
 	// allow a nil body for backwards compatibility
-
-	version := httputils.VersionFromContext(ctx)
-	var hostConfig *container.HostConfig
+	//
 	// A non-nil json object is at least 7 characters.
 	// A non-nil json object is at least 7 characters.
 	if r.ContentLength > 7 || r.ContentLength == -1 {
 	if r.ContentLength > 7 || r.ContentLength == -1 {
-		if versions.GreaterThanOrEqualTo(version, "1.24") {
-			return bodyOnStartError{}
-		}
-
-		if err := httputils.CheckForJSON(r); err != nil {
-			return err
-		}
-
-		c, err := s.decoder.DecodeHostConfig(r.Body)
-		if err != nil {
-			return err
-		}
-		hostConfig = c
+		return errdefs.InvalidParameter(errors.New("starting container with non-empty request body was deprecated since API v1.22 and removed in v1.24"))
 	}
 	}
 
 
 	if err := httputils.ParseForm(r); err != nil {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	checkpoint := r.Form.Get("checkpoint")
-	checkpointDir := r.Form.Get("checkpoint-dir")
-	if err := s.backend.ContainerStart(ctx, vars["name"], hostConfig, checkpoint, checkpointDir); err != nil {
+	if err := s.backend.ContainerStart(ctx, vars["name"], r.Form.Get("checkpoint"), r.Form.Get("checkpoint-dir")); err != nil {
 		return err
 		return err
 	}
 	}
 
 

+ 1 - 1
builder/builder.go

@@ -64,7 +64,7 @@ type ExecBackend interface {
 	// ContainerRm removes a container specified by `id`.
 	// ContainerRm removes a container specified by `id`.
 	ContainerRm(name string, config *backend.ContainerRmConfig) error
 	ContainerRm(name string, config *backend.ContainerRmConfig) error
 	// ContainerStart starts a new container
 	// ContainerStart starts a new container
-	ContainerStart(ctx context.Context, containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
+	ContainerStart(ctx context.Context, containerID string, checkpoint string, checkpointDir string) error
 	// ContainerWait stops processing until the given container is stopped.
 	// ContainerWait stops processing until the given container is stopped.
 	ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error)
 	ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error)
 }
 }

+ 1 - 1
builder/dockerfile/containerbackend.go

@@ -72,7 +72,7 @@ func (c *containerManager) Run(ctx context.Context, cID string, stdout, stderr i
 		}
 		}
 	}()
 	}()
 
 
-	if err := c.backend.ContainerStart(ctx, cID, nil, "", ""); err != nil {
+	if err := c.backend.ContainerStart(ctx, cID, "", ""); err != nil {
 		close(finished)
 		close(finished)
 		logCancellationError(cancelErrCh, "error from ContainerStart: "+err.Error())
 		logCancellationError(cancelErrCh, "error from ContainerStart: "+err.Error())
 		return err
 		return err

+ 1 - 1
builder/dockerfile/mockbackend_test.go

@@ -46,7 +46,7 @@ func (m *MockBackend) CommitBuildStep(ctx context.Context, c backend.CommitConfi
 	return "", nil
 	return "", nil
 }
 }
 
 
-func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error {
+func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, checkpoint string, checkpointDir string) error {
 	return nil
 	return nil
 }
 }
 
 

+ 1 - 1
daemon/cluster/executor/backend.go

@@ -38,7 +38,7 @@ type Backend interface {
 	SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
 	SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
 	ReleaseIngress() (<-chan struct{}, error)
 	ReleaseIngress() (<-chan struct{}, error)
 	CreateManagedContainer(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error)
 	CreateManagedContainer(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error)
-	ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
+	ContainerStart(ctx context.Context, name string, checkpoint string, checkpointDir string) error
 	ContainerStop(ctx context.Context, name string, config container.StopOptions) error
 	ContainerStop(ctx context.Context, name string, config container.StopOptions) error
 	ContainerLogs(ctx context.Context, name string, config *container.LogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
 	ContainerLogs(ctx context.Context, name string, config *container.LogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
 	ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
 	ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error

+ 1 - 1
daemon/cluster/executor/container/adapter.go

@@ -347,7 +347,7 @@ func (c *containerAdapter) start(ctx context.Context) error {
 		return err
 		return err
 	}
 	}
 
 
-	return c.backend.ContainerStart(ctx, c.container.name(), nil, "", "")
+	return c.backend.ContainerStart(ctx, c.container.name(), "", "")
 }
 }
 
 
 func (c *containerAdapter) inspect(ctx context.Context) (types.ContainerJSON, error) {
 func (c *containerAdapter) inspect(ctx context.Context) (types.ContainerJSON, error) {

+ 3 - 44
daemon/start.go

@@ -2,12 +2,10 @@ package daemon // import "github.com/docker/docker/daemon"
 
 
 import (
 import (
 	"context"
 	"context"
-	"runtime"
 	"time"
 	"time"
 
 
 	"github.com/containerd/log"
 	"github.com/containerd/log"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/backend"
-	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
@@ -41,7 +39,7 @@ func validateState(ctr *container.Container) error {
 }
 }
 
 
 // ContainerStart starts a container.
 // ContainerStart starts a container.
-func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
+func (daemon *Daemon) ContainerStart(ctx context.Context, name string, checkpoint string, checkpointDir string) error {
 	daemonCfg := daemon.config()
 	daemonCfg := daemon.config()
 	if checkpoint != "" && !daemonCfg.Experimental {
 	if checkpoint != "" && !daemonCfg.Experimental {
 		return errdefs.InvalidParameter(errors.New("checkpoint is only supported in experimental mode"))
 		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
 		return err
 		return err
 	}
 	}
 
 
-	// Windows does not have the backwards compatibility issue here.
-	if runtime.GOOS != "windows" {
-		// This is kept for backward compatibility - hostconfig should be passed when
-		// creating a container, not during start.
-		if hostConfig != nil {
-			log.G(ctx).Warn("DEPRECATED: Setting host configuration options when the container starts is deprecated and has been removed in Docker 1.12")
-			oldNetworkMode := ctr.HostConfig.NetworkMode
-			if err := daemon.setSecurityOptions(&daemonCfg.Config, ctr, hostConfig); err != nil {
-				return errdefs.InvalidParameter(err)
-			}
-			if err := daemon.mergeAndVerifyLogConfig(&hostConfig.LogConfig); err != nil {
-				return errdefs.InvalidParameter(err)
-			}
-			if err := daemon.setHostConfig(ctr, hostConfig); err != nil {
-				return errdefs.InvalidParameter(err)
-			}
-			newNetworkMode := ctr.HostConfig.NetworkMode
-			if string(oldNetworkMode) != string(newNetworkMode) {
-				// if user has change the network mode on starting, clean up the
-				// old networks. It is a deprecated feature and has been removed in Docker 1.12
-				ctr.NetworkSettings.Networks = nil
-			}
-			if err := ctr.CheckpointTo(daemon.containersReplica); err != nil {
-				return errdefs.System(err)
-			}
-			ctr.InitDNSHostConfig()
-		}
-	} else {
-		if hostConfig != nil {
-			return errdefs.InvalidParameter(errors.New("Supplying a hostconfig on start is not supported. It should be supplied on create"))
-		}
-	}
-
 	// check if hostConfig is in line with the current system settings.
 	// check if hostConfig is in line with the current system settings.
-	// It may happen cgroups are umounted or the like.
+	// It may happen cgroups are unmounted or the like.
 	if _, err = daemon.verifyContainerSettings(daemonCfg, ctr.HostConfig, nil, false); err != nil {
 	if _, err = daemon.verifyContainerSettings(daemonCfg, ctr.HostConfig, nil, false); err != nil {
 		return errdefs.InvalidParameter(err)
 		return errdefs.InvalidParameter(err)
 	}
 	}
-	// Adapt for old containers in case we have updates in this function and
-	// old containers never have chance to call the new function in create stage.
-	if hostConfig != nil {
-		if err := daemon.adaptContainerSettings(&daemonCfg.Config, ctr.HostConfig); err != nil {
-			return errdefs.InvalidParameter(err)
-		}
-	}
+
 	return daemon.containerStart(ctx, daemonCfg, ctr, checkpoint, checkpointDir, true)
 	return daemon.containerStart(ctx, daemonCfg, ctr, checkpoint, checkpointDir, true)
 }
 }
 
 

+ 0 - 239
integration-cli/docker_deprecated_api_v124_test.go

@@ -1,239 +0,0 @@
-// This file will be removed when we completely drop support for
-// passing HostConfig to container start API.
-
-package main
-
-import (
-	"net/http"
-	"strings"
-	"testing"
-
-	"github.com/docker/docker/integration-cli/cli"
-	"github.com/docker/docker/testutil"
-	"github.com/docker/docker/testutil/request"
-	"gotest.tools/v3/assert"
-	is "gotest.tools/v3/assert/cmp"
-)
-
-func formatV123StartAPIURL(url string) string {
-	return "/v1.23" + url
-}
-
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartHostConfig(c *testing.T) {
-	name := "test-deprecated-api-124"
-	cli.DockerCmd(c, "create", "--name", name, "busybox")
-	config := map[string]interface{}{
-		"Binds": []string{"/aa:/bb"},
-	}
-	res, body, err := request.Post(testutil.GetContext(c), "/containers/"+name+"/start", request.JSONBody(config))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
-	buf, err := request.ReadBody(body)
-	assert.NilError(c, err)
-
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
-	assert.Assert(c, strings.Contains(string(buf), "was deprecated since API v1.22"))
-}
-
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartVolumeBinds(c *testing.T) {
-	// TODO Windows CI: Investigate further why this fails on Windows to Windows CI.
-	testRequires(c, DaemonIsLinux)
-	path := "/foo"
-	if testEnv.DaemonInfo.OSType == "windows" {
-		path = `c:\foo`
-	}
-	name := "testing"
-	config := map[string]interface{}{
-		"Image":   "busybox",
-		"Volumes": map[string]struct{}{path: {}},
-	}
-
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusCreated)
-
-	bindPath := RandomTmpDirPath("test", testEnv.DaemonInfo.OSType)
-	config = map[string]interface{}{
-		"Binds": []string{bindPath + ":" + path},
-	}
-	res, _, err = request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-
-	pth, err := inspectMountSourceField(name, path)
-	assert.NilError(c, err)
-	assert.Equal(c, pth, bindPath, "expected volume host path to be %s, got %s", bindPath, pth)
-}
-
-// Test for GH#10618
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartDupVolumeBinds(c *testing.T) {
-	// TODO Windows to Windows CI - Port this
-	testRequires(c, DaemonIsLinux)
-	name := "testdups"
-	config := map[string]interface{}{
-		"Image":   "busybox",
-		"Volumes": map[string]struct{}{"/tmp": {}},
-	}
-
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusCreated)
-
-	bindPath1 := RandomTmpDirPath("test1", testEnv.DaemonInfo.OSType)
-	bindPath2 := RandomTmpDirPath("test2", testEnv.DaemonInfo.OSType)
-
-	config = map[string]interface{}{
-		"Binds": []string{bindPath1 + ":/tmp", bindPath2 + ":/tmp"},
-	}
-	res, body, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
-	assert.NilError(c, err)
-
-	buf, err := request.ReadBody(body)
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
-	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)
-}
-
-func (s *DockerAPISuite) TestDeprecatedContainerAPIStartVolumesFrom(c *testing.T) {
-	// TODO Windows to Windows CI - Port this
-	testRequires(c, DaemonIsLinux)
-	volName := "voltst"
-	volPath := "/tmp"
-
-	cli.DockerCmd(c, "run", "--name", volName, "-v", volPath, "busybox")
-
-	name := "TestContainerAPIStartVolumesFrom"
-	config := map[string]interface{}{
-		"Image":   "busybox",
-		"Volumes": map[string]struct{}{volPath: {}},
-	}
-
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusCreated)
-
-	config = map[string]interface{}{
-		"VolumesFrom": []string{volName},
-	}
-	res, _, err = request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-
-	pth, err := inspectMountSourceField(name, volPath)
-	assert.NilError(c, err)
-	pth2, err := inspectMountSourceField(volName, volPath)
-	assert.NilError(c, err)
-	assert.Equal(c, pth, pth2, "expected volume host path to be %s, got %s", pth, pth2)
-}
-
-// #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
-func (s *DockerAPISuite) TestDeprecatedPostContainerBindNormalVolume(c *testing.T) {
-	// TODO Windows to Windows CI - Port this
-	testRequires(c, DaemonIsLinux)
-	cli.DockerCmd(c, "create", "-v", "/foo", "--name=one", "busybox")
-
-	fooDir, err := inspectMountSourceField("one", "/foo")
-	assert.NilError(c, err)
-
-	cli.DockerCmd(c, "create", "-v", "/foo", "--name=two", "busybox")
-
-	bindSpec := map[string][]string{"Binds": {fooDir + ":/foo"}}
-	res, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/two/start"), request.JSONBody(bindSpec))
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-
-	fooDir2, err := inspectMountSourceField("two", "/foo")
-	assert.NilError(c, err)
-	assert.Equal(c, fooDir2, fooDir, "expected volume path to be %s, got: %s", fooDir, fooDir2)
-}
-
-func (s *DockerAPISuite) TestDeprecatedStartWithTooLowMemoryLimit(c *testing.T) {
-	// TODO Windows: Port once memory is supported
-	testRequires(c, DaemonIsLinux)
-	containerID := cli.DockerCmd(c, "create", "busybox").Stdout()
-	containerID = strings.TrimSpace(containerID)
-
-	const config = `{
-                "CpuShares": 100,
-                "Memory":    524287
-        }`
-
-	res, body, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+containerID+"/start"), request.RawString(config), request.JSON)
-	assert.NilError(c, err)
-	b, err := request.ReadBody(body)
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusBadRequest)
-	assert.Assert(c, is.Contains(string(b), "Minimum memory limit allowed is 6MB"))
-}
-
-// #14640
-func (s *DockerAPISuite) TestDeprecatedPostContainersStartWithoutLinksInHostConfig(c *testing.T) {
-	// TODO Windows: Windows doesn't support supplying a hostconfig on start.
-	// An alternate test could be written to validate the negative testing aspect of this
-	testRequires(c, DaemonIsLinux)
-	name := "test-host-config-links"
-	cli.DockerCmd(c, append([]string{"create", "--name", name, "busybox"}, sleepCommandForDaemonPlatform()...)...)
-
-	hc := inspectFieldJSON(c, name, "HostConfig")
-	config := `{"HostConfig":` + hc + `}`
-
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.RawString(config), request.JSON)
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-	b.Close()
-}
-
-// #14640
-func (s *DockerAPISuite) TestDeprecatedPostContainersStartWithLinksInHostConfig(c *testing.T) {
-	// TODO Windows: Windows doesn't support supplying a hostconfig on start.
-	// An alternate test could be written to validate the negative testing aspect of this
-	testRequires(c, DaemonIsLinux)
-	name := "test-host-config-links"
-	cli.DockerCmd(c, "run", "--name", "foo", "-d", "busybox", "top")
-	cli.DockerCmd(c, "create", "--name", name, "--link", "foo:bar", "busybox", "top")
-
-	hc := inspectFieldJSON(c, name, "HostConfig")
-	config := `{"HostConfig":` + hc + `}`
-
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.RawString(config), request.JSON)
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-	b.Close()
-}
-
-// #14640
-func (s *DockerAPISuite) TestDeprecatedPostContainersStartWithLinksInHostConfigIdLinked(c *testing.T) {
-	// Windows does not support links
-	testRequires(c, DaemonIsLinux)
-	const name = "test-host-config-links"
-	containerID := cli.DockerCmd(c, "run", "--name", "link0", "-d", "busybox", "top").Combined()
-	containerID = strings.TrimSpace(containerID)
-	defer cli.DockerCmd(c, "stop", "link0")
-	cli.DockerCmd(c, "create", "--name", name, "--link", containerID, "busybox", "top")
-	defer cli.DockerCmd(c, "stop", name)
-
-	hc := inspectFieldJSON(c, name, "HostConfig")
-	config := `{"HostConfig":` + hc + `}`
-
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+name+"/start"), request.RawString(config), request.JSON)
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-	b.Close()
-}
-
-func (s *DockerAPISuite) TestDeprecatedStartWithNilDNS(c *testing.T) {
-	// TODO Windows: Add once DNS is supported
-	testRequires(c, DaemonIsLinux)
-	containerID := cli.DockerCmd(c, "create", "busybox").Stdout()
-	containerID = strings.TrimSpace(containerID)
-
-	const config = `{"HostConfig": {"Dns": null}}`
-
-	res, b, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+containerID+"/start"), request.RawString(config), request.JSON)
-	assert.NilError(c, err)
-	assert.Equal(c, res.StatusCode, http.StatusNoContent)
-	b.Close()
-
-	dns := inspectFieldJSON(c, containerID, "HostConfig.Dns")
-	assert.Equal(c, dns, "[]")
-}

+ 0 - 33
integration-cli/docker_deprecated_api_v124_unix_test.go

@@ -1,33 +0,0 @@
-//go:build !windows
-
-package main
-
-import (
-	"strings"
-	"testing"
-
-	"github.com/docker/docker/integration-cli/cli"
-	"github.com/docker/docker/testutil"
-	"github.com/docker/docker/testutil/request"
-	"gotest.tools/v3/assert"
-)
-
-// #19100 This is a deprecated feature test, it should be removed in Docker 1.12
-func (s *DockerNetworkSuite) TestDeprecatedDockerNetworkStartAPIWithHostconfig(c *testing.T) {
-	const netName = "test"
-	const conName = "foo"
-	cli.DockerCmd(c, "network", "create", netName)
-	cli.DockerCmd(c, "create", "--name", conName, "busybox", "top")
-
-	config := map[string]interface{}{
-		"HostConfig": map[string]interface{}{
-			"NetworkMode": netName,
-		},
-	}
-	_, _, err := request.Post(testutil.GetContext(c), formatV123StartAPIURL("/containers/"+conName+"/start"), request.JSONBody(config))
-	assert.NilError(c, err)
-	cli.WaitRun(c, conName)
-	networks := inspectField(c, conName, "NetworkSettings.Networks")
-	assert.Assert(c, strings.Contains(networks, netName), "Should contain '%s' network", netName)
-	assert.Assert(c, !strings.Contains(networks, "bridge"), "Should not contain 'bridge' network")
-}

+ 0 - 9
integration/container/container_test.go

@@ -2,7 +2,6 @@ package container // import "github.com/docker/docker/integration/container"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
-	"runtime"
 	"testing"
 	"testing"
 
 
 	"github.com/docker/docker/testutil"
 	"github.com/docker/docker/testutil"
@@ -25,14 +24,6 @@ func TestContainerInvalidJSON(t *testing.T) {
 		"/exec/foobar/start",
 		"/exec/foobar/start",
 	}
 	}
 
 
-	// windows doesnt support API < v1.24
-	if runtime.GOOS != "windows" {
-		endpoints = append(
-			endpoints,
-			"/v1.23/containers/foobar/start", // accepts a body on API < v1.24
-		)
-	}
-
 	for _, ep := range endpoints {
 	for _, ep := range endpoints {
 		ep := ep
 		ep := ep
 		t.Run(ep[1:], func(t *testing.T) {
 		t.Run(ep[1:], func(t *testing.T) {

+ 0 - 5
runconfig/config.go

@@ -27,11 +27,6 @@ func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *conta
 	return decodeContainerConfig(src, si)
 	return decodeContainerConfig(src, si)
 }
 }
 
 
-// DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder
-func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
-	return decodeHostConfig(src)
-}
-
 // decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
 // decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
 // struct and returns both a Config and a HostConfig struct, and performs some
 // struct and returns both a Config and a HostConfig struct, and performs some
 // validation. Certain parameters need daemon-side validation that cannot be done
 // validation. Certain parameters need daemon-side validation that cannot be done

+ 0 - 18
runconfig/fixtures/unix/container_hostconfig_1_14.json

@@ -1,18 +0,0 @@
-{
-    "Binds": ["/tmp:/tmp"],
-    "ContainerIDFile": "",
-    "LxcConf": [],
-    "Privileged": false,
-    "PortBindings": {
-        "80/tcp": [
-            {
-                "HostIp": "0.0.0.0",
-                "HostPort": "49153"
-            }
-        ]
-    },
-    "Links": ["/name:alias"],
-    "PublishAllPorts": false,
-    "CapAdd": ["NET_ADMIN"],
-    "CapDrop": ["MKNOD"]
-}

+ 0 - 30
runconfig/fixtures/unix/container_hostconfig_1_19.json

@@ -1,30 +0,0 @@
-{
-    "Binds": ["/tmp:/tmp"],
-    "Links": ["redis3:redis"],
-    "LxcConf": {"lxc.utsname":"docker"},
-    "Memory": 0,
-    "MemorySwap": 0,
-    "CpuShares": 512,
-    "CpuPeriod": 100000,
-    "CpusetCpus": "0,1",
-    "CpusetMems": "0,1",
-    "BlkioWeight": 300,
-    "OomKillDisable": false,
-    "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
-    "PublishAllPorts": false,
-    "Privileged": false,
-    "ReadonlyRootfs": false,
-    "Dns": ["8.8.8.8"],
-    "DnsSearch": [""],
-    "ExtraHosts": null,
-    "VolumesFrom": ["parent", "other:ro"],
-    "CapAdd": ["NET_ADMIN"],
-    "CapDrop": ["MKNOD"],
-    "RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
-    "NetworkMode": "bridge",
-    "Devices": [],
-    "Ulimits": [{}],
-    "LogConfig": { "Type": "json-file", "Config": {} },
-    "SecurityOpt": [""],
-    "CgroupParent": ""
-}

+ 0 - 11
runconfig/hostconfig.go

@@ -1,23 +1,12 @@
 package runconfig // import "github.com/docker/docker/runconfig"
 package runconfig // import "github.com/docker/docker/runconfig"
 
 
 import (
 import (
-	"io"
 	"strings"
 	"strings"
 
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/api/types/network"
 )
 )
 
 
-// DecodeHostConfig creates a HostConfig based on the specified Reader.
-// It assumes the content of the reader will be JSON, and decodes it.
-func decodeHostConfig(src io.Reader) (*container.HostConfig, error) {
-	var w ContainerConfigWrapper
-	if err := loadJSON(src, &w); err != nil {
-		return nil, err
-	}
-	return w.getHostConfig(), nil
-}
-
 // SetDefaultNetModeIfBlank changes the NetworkMode in a HostConfig structure
 // SetDefaultNetModeIfBlank changes the NetworkMode in a HostConfig structure
 // to default if it is not populated. This ensures backwards compatibility after
 // to default if it is not populated. This ensures backwards compatibility after
 // the validation of the network mode was moved from the docker CLI to the
 // the validation of the network mode was moved from the docker CLI to the

+ 0 - 39
runconfig/hostconfig_test.go

@@ -3,51 +3,12 @@
 package runconfig // import "github.com/docker/docker/runconfig"
 package runconfig // import "github.com/docker/docker/runconfig"
 
 
 import (
 import (
-	"bytes"
-	"fmt"
-	"os"
 	"testing"
 	"testing"
 
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/pkg/sysinfo"
-	"gotest.tools/v3/assert"
 )
 )
 
 
-func TestDecodeHostConfig(t *testing.T) {
-	fixtures := []struct {
-		file string
-	}{
-		{"fixtures/unix/container_hostconfig_1_14.json"},
-		{"fixtures/unix/container_hostconfig_1_19.json"},
-	}
-
-	for _, f := range fixtures {
-		b, err := os.ReadFile(f.file)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		c, err := decodeHostConfig(bytes.NewReader(b))
-		if err != nil {
-			t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
-		}
-
-		assert.Check(t, !c.Privileged)
-
-		if l := len(c.Binds); l != 1 {
-			t.Fatalf("Expected 1 bind, found %d\n", l)
-		}
-
-		if len(c.CapAdd) != 1 && c.CapAdd[0] != "NET_ADMIN" {
-			t.Fatalf("Expected CapAdd NET_ADMIN, got %v", c.CapAdd)
-		}
-
-		if len(c.CapDrop) != 1 && c.CapDrop[0] != "NET_ADMIN" {
-			t.Fatalf("Expected CapDrop NET_ADMIN, got %v", c.CapDrop)
-		}
-	}
-}
-
 func TestValidateResources(t *testing.T) {
 func TestValidateResources(t *testing.T) {
 	type resourceTest struct {
 	type resourceTest struct {
 		ConfigCPURealtimePeriod  int64
 		ConfigCPURealtimePeriod  int64