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 3e7405aea8, and removed in
API v1.23 (Docker Engine v1.12.0) in commit 0a8386c8be.

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2024-01-21 17:52:05 +01:00
parent ffd877f948
commit 8758d08bb4
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
17 changed files with 12 additions and 462 deletions

View file

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

View file

@ -38,7 +38,7 @@ type stateBackend interface {
ContainerResize(name string, height, width int) error
ContainerRestart(ctx context.Context, name string, options container.StopOptions) 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
ContainerUnpause(name string) error
ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error)

View file

@ -168,14 +168,6 @@ func (s *containerRouter) getContainersExport(ctx context.Context, w http.Respon
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 {
// If contentLength is -1, we can assumed chunked encoding
// 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
// including r.TransferEncoding
// 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.
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 {
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
}

View file

@ -64,7 +64,7 @@ type ExecBackend interface {
// ContainerRm removes a container specified by `id`.
ContainerRm(name string, config *backend.ContainerRmConfig) error
// 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(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error)
}

View file

@ -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)
logCancellationError(cancelErrCh, "error from ContainerStart: "+err.Error())
return err

View file

@ -46,7 +46,7 @@ func (m *MockBackend) CommitBuildStep(ctx context.Context, c backend.CommitConfi
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
}

View file

@ -38,7 +38,7 @@ type Backend interface {
SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
ReleaseIngress() (<-chan struct{}, 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
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

View file

@ -347,7 +347,7 @@ func (c *containerAdapter) start(ctx context.Context) error {
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) {

View file

@ -2,12 +2,10 @@ package daemon // import "github.com/docker/docker/daemon"
import (
"context"
"runtime"
"time"
"github.com/containerd/log"
"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/container"
"github.com/docker/docker/errdefs"
@ -41,7 +39,7 @@ func validateState(ctr *container.Container) error {
}
// 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()
if checkpoint != "" && !daemonCfg.Experimental {
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
}
// 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.
// 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 {
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)
}

View file

@ -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, "[]")
}

View file

@ -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")
}

View file

@ -2,7 +2,6 @@ package container // import "github.com/docker/docker/integration/container"
import (
"net/http"
"runtime"
"testing"
"github.com/docker/docker/testutil"
@ -25,14 +24,6 @@ func TestContainerInvalidJSON(t *testing.T) {
"/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 {
ep := ep
t.Run(ep[1:], func(t *testing.T) {

View file

@ -27,11 +27,6 @@ func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *conta
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
// struct and returns both a Config and a HostConfig struct, and performs some
// validation. Certain parameters need daemon-side validation that cannot be done

View file

@ -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"]
}

View file

@ -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": ""
}

View file

@ -1,23 +1,12 @@
package runconfig // import "github.com/docker/docker/runconfig"
import (
"io"
"strings"
"github.com/docker/docker/api/types/container"
"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
// 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

View file

@ -3,51 +3,12 @@
package runconfig // import "github.com/docker/docker/runconfig"
import (
"bytes"
"fmt"
"os"
"testing"
"github.com/docker/docker/api/types/container"
"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) {
type resourceTest struct {
ConfigCPURealtimePeriod int64