Merge pull request #46720 from akerouanton/container-create-init-structs
api: ContainerCreate: clean up BC conditions
This commit is contained in:
commit
460e1b3600
4 changed files with 61 additions and 42 deletions
|
@ -19,10 +19,12 @@ import (
|
|||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
containerpkg "github.com/docker/docker/container"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/runconfig"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/websocket"
|
||||
|
@ -492,21 +494,39 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if config == nil {
|
||||
return errdefs.InvalidParameter(runconfig.ErrEmptyConfig)
|
||||
}
|
||||
if hostConfig == nil {
|
||||
hostConfig = &container.HostConfig{}
|
||||
}
|
||||
if hostConfig.NetworkMode == "" {
|
||||
hostConfig.NetworkMode = "default"
|
||||
}
|
||||
if networkingConfig == nil {
|
||||
networkingConfig = &network.NetworkingConfig{}
|
||||
}
|
||||
if networkingConfig.EndpointsConfig == nil {
|
||||
networkingConfig.EndpointsConfig = make(map[string]*network.EndpointSettings)
|
||||
}
|
||||
|
||||
version := httputils.VersionFromContext(ctx)
|
||||
adjustCPUShares := versions.LessThan(version, "1.19")
|
||||
|
||||
// When using API 1.24 and under, the client is responsible for removing the container
|
||||
if hostConfig != nil && versions.LessThan(version, "1.25") {
|
||||
if versions.LessThan(version, "1.25") {
|
||||
hostConfig.AutoRemove = false
|
||||
}
|
||||
|
||||
if hostConfig != nil && versions.LessThan(version, "1.40") {
|
||||
if versions.LessThan(version, "1.40") {
|
||||
// Ignore BindOptions.NonRecursive because it was added in API 1.40.
|
||||
for _, m := range hostConfig.Mounts {
|
||||
if bo := m.BindOptions; bo != nil {
|
||||
bo.NonRecursive = false
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore KernelMemoryTCP because it was added in API 1.40.
|
||||
hostConfig.KernelMemoryTCP = 0
|
||||
|
||||
|
@ -515,14 +535,26 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
hostConfig.IpcMode = container.IPCModeShareable
|
||||
}
|
||||
}
|
||||
if hostConfig != nil && versions.LessThan(version, "1.41") && !s.cgroup2 {
|
||||
|
||||
if versions.LessThan(version, "1.41") {
|
||||
// Older clients expect the default to be "host" on cgroup v1 hosts
|
||||
if hostConfig.CgroupnsMode.IsEmpty() {
|
||||
if !s.cgroup2 && hostConfig.CgroupnsMode.IsEmpty() {
|
||||
hostConfig.CgroupnsMode = container.CgroupnsModeHost
|
||||
}
|
||||
}
|
||||
|
||||
if hostConfig != nil && versions.LessThan(version, "1.42") {
|
||||
var platform *ocispec.Platform
|
||||
if versions.GreaterThanOrEqualTo(version, "1.41") {
|
||||
if v := r.Form.Get("platform"); v != "" {
|
||||
p, err := platforms.Parse(v)
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
platform = &p
|
||||
}
|
||||
}
|
||||
|
||||
if versions.LessThan(version, "1.42") {
|
||||
for _, m := range hostConfig.Mounts {
|
||||
// Ignore BindOptions.CreateMountpoint because it was added in API 1.42.
|
||||
if bo := m.BindOptions; bo != nil {
|
||||
|
@ -542,16 +574,14 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
bo.CreateMountpoint = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config != nil && versions.LessThan(version, "1.44") {
|
||||
if config.Healthcheck != nil {
|
||||
// StartInterval was added in API 1.44
|
||||
config.Healthcheck.StartInterval = 0
|
||||
if runtime.GOOS == "linux" {
|
||||
// ConsoleSize is not respected by Linux daemon before API 1.42
|
||||
hostConfig.ConsoleSize = [2]uint{0, 0}
|
||||
}
|
||||
}
|
||||
|
||||
if hostConfig != nil && versions.GreaterThanOrEqualTo(version, "1.42") {
|
||||
if versions.GreaterThanOrEqualTo(version, "1.42") {
|
||||
// Ignore KernelMemory removed in API 1.42.
|
||||
hostConfig.KernelMemory = 0
|
||||
for _, m := range hostConfig.Mounts {
|
||||
|
@ -567,36 +597,17 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
}
|
||||
}
|
||||
|
||||
if hostConfig != nil && runtime.GOOS == "linux" && versions.LessThan(version, "1.42") {
|
||||
// ConsoleSize is not respected by Linux daemon before API 1.42
|
||||
hostConfig.ConsoleSize = [2]uint{0, 0}
|
||||
}
|
||||
|
||||
if hostConfig != nil && versions.LessThan(version, "1.43") {
|
||||
if versions.LessThan(version, "1.43") {
|
||||
// Ignore Annotations because it was added in API v1.43.
|
||||
hostConfig.Annotations = nil
|
||||
}
|
||||
|
||||
var platform *ocispec.Platform
|
||||
if versions.GreaterThanOrEqualTo(version, "1.41") {
|
||||
if v := r.Form.Get("platform"); v != "" {
|
||||
p, err := platforms.Parse(v)
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
platform = &p
|
||||
if versions.LessThan(version, "1.44") {
|
||||
if config.Healthcheck != nil {
|
||||
// StartInterval was added in API 1.44
|
||||
config.Healthcheck.StartInterval = 0
|
||||
}
|
||||
}
|
||||
|
||||
if hostConfig != nil && hostConfig.PidsLimit != nil && *hostConfig.PidsLimit <= 0 {
|
||||
// Don't set a limit if either no limit was specified, or "unlimited" was
|
||||
// explicitly set.
|
||||
// Both `0` and `-1` are accepted as "unlimited", and historically any
|
||||
// negative value was accepted, so treat those as "unlimited" as well.
|
||||
hostConfig.PidsLimit = nil
|
||||
}
|
||||
|
||||
if hostConfig != nil && versions.LessThan(version, "1.44") {
|
||||
for _, m := range hostConfig.Mounts {
|
||||
if m.BindOptions != nil {
|
||||
// Ignore ReadOnlyNonRecursive because it was added in API 1.44.
|
||||
|
@ -606,11 +617,9 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if versions.LessThan(version, "1.44") {
|
||||
// Creating a container connected to several networks is not supported until v1.44.
|
||||
if networkingConfig != nil && len(networkingConfig.EndpointsConfig) > 1 {
|
||||
if len(networkingConfig.EndpointsConfig) > 1 {
|
||||
l := make([]string, 0, len(networkingConfig.EndpointsConfig))
|
||||
for k := range networkingConfig.EndpointsConfig {
|
||||
l = append(l, k)
|
||||
|
@ -619,6 +628,14 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
}
|
||||
}
|
||||
|
||||
if hostConfig.PidsLimit != nil && *hostConfig.PidsLimit <= 0 {
|
||||
// Don't set a limit if either no limit was specified, or "unlimited" was
|
||||
// explicitly set.
|
||||
// Both `0` and `-1` are accepted as "unlimited", and historically any
|
||||
// negative value was accepted, so treat those as "unlimited" as well.
|
||||
hostConfig.PidsLimit = nil
|
||||
}
|
||||
|
||||
ccr, err := s.backend.ContainerCreate(ctx, types.ContainerCreateConfig{
|
||||
Name: name,
|
||||
Config: config,
|
||||
|
|
|
@ -2,7 +2,6 @@ package daemon // import "github.com/docker/docker/daemon"
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -61,7 +60,7 @@ func (daemon *Daemon) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context
|
|||
func (daemon *Daemon) containerCreate(ctx context.Context, daemonCfg *configStore, opts createOpts) (containertypes.CreateResponse, error) {
|
||||
start := time.Now()
|
||||
if opts.params.Config == nil {
|
||||
return containertypes.CreateResponse{}, errdefs.InvalidParameter(errors.New("Config cannot be empty in order to create a container"))
|
||||
return containertypes.CreateResponse{}, errdefs.InvalidParameter(runconfig.ErrEmptyConfig)
|
||||
}
|
||||
|
||||
// Normalize some defaults. Doing this "ad-hoc" here for now, as there's
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/testutil"
|
||||
"github.com/docker/docker/testutil/request"
|
||||
"gotest.tools/v3/assert"
|
||||
|
@ -82,7 +83,7 @@ func (s *DockerAPISuite) TestAPIErrorJSON(c *testing.T) {
|
|||
assert.Assert(c, strings.Contains(httpResp.Header.Get("Content-Type"), "application/json"))
|
||||
b, err := request.ReadBody(body)
|
||||
assert.NilError(c, err)
|
||||
assert.Equal(c, getErrorMessage(c, b), "Config cannot be empty in order to create a container")
|
||||
assert.Equal(c, getErrorMessage(c, b), runconfig.ErrEmptyConfig.Error())
|
||||
}
|
||||
|
||||
func (s *DockerAPISuite) TestAPIErrorPlainText(c *testing.T) {
|
||||
|
@ -99,7 +100,7 @@ func (s *DockerAPISuite) TestAPIErrorPlainText(c *testing.T) {
|
|||
assert.Assert(c, strings.Contains(httpResp.Header.Get("Content-Type"), "text/plain"))
|
||||
b, err := request.ReadBody(body)
|
||||
assert.NilError(c, err)
|
||||
assert.Equal(c, strings.TrimSpace(string(b)), "Config cannot be empty in order to create a container")
|
||||
assert.Equal(c, strings.TrimSpace(string(b)), runconfig.ErrEmptyConfig.Error())
|
||||
}
|
||||
|
||||
func (s *DockerAPISuite) TestAPIErrorNotFoundJSON(c *testing.T) {
|
||||
|
|
|
@ -31,6 +31,8 @@ const (
|
|||
ErrUnsupportedNetworkAndAlias validationError = "network-scoped alias is supported only for containers in user defined networks"
|
||||
// ErrConflictUTSHostname conflict between the hostname and the UTS mode
|
||||
ErrConflictUTSHostname validationError = "conflicting options: hostname and the UTS mode"
|
||||
// ErrEmptyConfig when container config is nil
|
||||
ErrEmptyConfig validationError = "config cannot be empty in order to create a container"
|
||||
)
|
||||
|
||||
type validationError string
|
||||
|
|
Loading…
Add table
Reference in a new issue