diff --git a/daemon/container_operations.go b/daemon/container_operations.go index e1ca06e93d..d3cfb6d643 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -28,7 +28,6 @@ import ( "github.com/docker/docker/daemon/network" "github.com/docker/docker/daemon/pkg/opts" "github.com/docker/docker/errdefs" - "github.com/docker/docker/runconfig" "github.com/docker/go-connections/nat" containertypes "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/events" @@ -174,7 +173,7 @@ func (daemon *Daemon) updateNetworkSettings(ctr *container.Container, n *libnetw } if !ctr.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() { - return runconfig.ErrConflictConnectToHostNetwork + return cerrdefs.ErrInvalidArgument.WithMessage("cannot connect container to host network - container must be created in host network mode") } for s, v := range ctr.NetworkSettings.Networks { @@ -194,13 +193,11 @@ func (daemon *Daemon) updateNetworkSettings(ctr *container.Container, n *libnetw // Avoid duplicate config return nil } - if !containertypes.NetworkMode(sn.Type()).IsPrivate() || - !containertypes.NetworkMode(n.Type()).IsPrivate() { - return runconfig.ErrConflictSharedNetwork + if !containertypes.NetworkMode(sn.Type()).IsPrivate() || !containertypes.NetworkMode(n.Type()).IsPrivate() { + return cerrdefs.ErrInvalidArgument.WithMessage("container sharing network namespace with another container or host cannot be connected to any other network") } - if containertypes.NetworkMode(sn.Name()).IsNone() || - containertypes.NetworkMode(n.Name()).IsNone() { - return runconfig.ErrConflictNoNetwork + if containertypes.NetworkMode(sn.Name()).IsNone() || containertypes.NetworkMode(n.Name()).IsNone() { + return cerrdefs.ErrInvalidArgument.WithMessage("container cannot be connected to multiple networks with one of the networks in private (none) mode") } } @@ -549,10 +546,10 @@ func validateEndpointSettings(nw *libnetwork.Network, nwName string, epConfig *n hasStaticAddresses := ipamConfig.IPv4Address != "" || ipamConfig.IPv6Address != "" // On Linux, user specified IP address is accepted only by networks with user specified subnets. if hasStaticAddresses && !enableIPOnPredefinedNetwork() { - errs = append(errs, runconfig.ErrUnsupportedNetworkAndIP) + errs = append(errs, cerrdefs.ErrInvalidArgument.WithMessage("user specified IP address is supported on user defined networks only")) } if len(epConfig.Aliases) > 0 && !serviceDiscoveryOnDefaultNetwork() { - errs = append(errs, runconfig.ErrUnsupportedNetworkAndAlias) + errs = append(errs, cerrdefs.ErrInvalidArgument.WithMessage("network-scoped alias is supported only for containers in user defined networks")) } } @@ -671,7 +668,7 @@ func (daemon *Daemon) connectToNetwork(ctx context.Context, cfg *config.Config, start := time.Now() if ctr.HostConfig.NetworkMode.IsContainer() { - return runconfig.ErrConflictSharedNetwork + return cerrdefs.ErrInvalidArgument.WithMessage("container sharing network namespace with another container or host cannot be connected to any other network") } if cfg.DisableBridge && containertypes.NetworkMode(idOrName).IsBridge() { ctr.Config.NetworkDisabled = true @@ -1046,7 +1043,7 @@ func (daemon *Daemon) DisconnectFromNetwork(ctx context.Context, ctr *container. delete(ctr.NetworkSettings.Networks, networkName) } else if err == nil { if ctr.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() { - return runconfig.ErrConflictDisconnectFromHostNetwork + return cerrdefs.ErrInvalidArgument.WithMessage("cannot disconnect container from host network - container was created in host network mode") } if err := daemon.disconnectFromNetwork(ctx, ctr, n, false); err != nil { diff --git a/daemon/create.go b/daemon/create.go index a411789922..851038e2ae 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -23,7 +23,6 @@ import ( "github.com/docker/docker/daemon/internal/otelutil" "github.com/docker/docker/daemon/server/backend" "github.com/docker/docker/errdefs" - "github.com/docker/docker/runconfig" containertypes "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/events" networktypes "github.com/moby/moby/api/types/network" @@ -77,7 +76,7 @@ func (daemon *Daemon) containerCreate(ctx context.Context, daemonCfg *configStor start := time.Now() if opts.params.Config == nil { - return containertypes.CreateResponse{}, errdefs.InvalidParameter(runconfig.ErrEmptyConfig) + return containertypes.CreateResponse{}, errdefs.InvalidParameter(errors.New("config cannot be empty in order to create a container")) } // Normalize some defaults. Doing this "ad-hoc" here for now, as there's diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index a0cc3a9b7e..2dd9d792de 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -40,7 +40,6 @@ import ( volumemounts "github.com/docker/docker/daemon/volume/mounts" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/sysinfo" - "github.com/docker/docker/runconfig" "github.com/moby/moby/api/types/blkiodev" containertypes "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/network" @@ -1565,7 +1564,7 @@ func (daemon *Daemon) registerLinks(container *container.Container, hostConfig * } } if child.HostConfig.NetworkMode.IsHost() { - return runconfig.ErrConflictHostNetworkAndLinks + return cerrdefs.ErrInvalidArgument.WithMessage("conflicting options: host type networking can't be used with links. This would result in undefined behavior") } if err := daemon.registerLink(container, child, alias); err != nil { return err diff --git a/daemon/server/router/container/container_routes.go b/daemon/server/router/container/container_routes.go index 2ec2977f7b..f335a36eae 100644 --- a/daemon/server/router/container/container_routes.go +++ b/daemon/server/router/container/container_routes.go @@ -19,7 +19,6 @@ import ( "github.com/docker/docker/daemon/server/httputils" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/ioutils" - "github.com/docker/docker/runconfig" "github.com/moby/moby/api/types" "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/filters" @@ -506,7 +505,7 @@ func (c *containerRouter) postContainersCreate(ctx context.Context, w http.Respo } if config == nil { - return errdefs.InvalidParameter(runconfig.ErrEmptyConfig) + return errdefs.InvalidParameter(errors.New("config cannot be empty in order to create a container")) } if hostConfig == nil { hostConfig = &container.HostConfig{} @@ -763,7 +762,7 @@ func handleMACAddressBC(config *container.Config, hostConfig *container.HostConf return "", nil } if !hostConfig.NetworkMode.IsBridge() && !hostConfig.NetworkMode.IsUserDefined() { - return "", runconfig.ErrConflictContainerNetworkAndMac + return "", errdefs.InvalidParameter(errors.New("conflicting options: mac-address and the network mode")) } epConfig, err := epConfigForNetMode(version, hostConfig.NetworkMode, networkingConfig) diff --git a/runconfig/config.go b/runconfig/config.go index 52220e987e..b4a872101b 100644 --- a/runconfig/config.go +++ b/runconfig/config.go @@ -81,7 +81,8 @@ func decodeContainerConfig(src io.Reader, si *sysinfo.SysInfo) (*container.Confi func loadJSON(src io.Reader, out interface{}) error { dec := json.NewDecoder(src) if err := dec.Decode(&out); err != nil { - return invalidJSONError{Err: err} + // invalidJSONError allows unwrapping the error to detect io.EOF etc. + return invalidJSONError{error: err} } if dec.More() { return validationError("unexpected content after JSON") diff --git a/runconfig/errors.go b/runconfig/errors.go index feeb679ec0..36c4ab295e 100644 --- a/runconfig/errors.go +++ b/runconfig/errors.go @@ -1,60 +1,19 @@ package runconfig -const ( - // ErrConflictContainerNetworkAndLinks conflict between --net=container and links - ErrConflictContainerNetworkAndLinks validationError = "conflicting options: container type network can't be used with links. This would result in undefined behavior" - // ErrConflictSharedNetwork conflict between private and other networks - ErrConflictSharedNetwork validationError = "container sharing network namespace with another container or host cannot be connected to any other network" - // ErrConflictConnectToHostNetwork error when attempting to connect a container to host network when not in host network mode - ErrConflictConnectToHostNetwork validationError = "cannot connect container to host network - container must be created in host network mode" - // ErrConflictDisconnectFromHostNetwork error when attempting to disconnect a container from host network when in host network mode - ErrConflictDisconnectFromHostNetwork validationError = "cannot disconnect container from host network - container was created in host network mode" - // ErrConflictNoNetwork conflict between private and other networks - ErrConflictNoNetwork validationError = "container cannot be connected to multiple networks with one of the networks in private (none) mode" - // ErrConflictNetworkAndDNS conflict between --dns and the network mode - ErrConflictNetworkAndDNS validationError = "conflicting options: dns and the network mode" - // ErrConflictNetworkHostname conflict between the hostname and the network mode - ErrConflictNetworkHostname validationError = "conflicting options: hostname and the network mode" - // ErrConflictHostNetworkAndLinks conflict between --net=host and links - ErrConflictHostNetworkAndLinks validationError = "conflicting options: host type networking can't be used with links. This would result in undefined behavior" - // ErrConflictContainerNetworkAndMac conflict between the mac address and the network mode - ErrConflictContainerNetworkAndMac validationError = "conflicting options: mac-address and the network mode" - // ErrConflictNetworkHosts conflict between add-host and the network mode - ErrConflictNetworkHosts validationError = "conflicting options: custom host-to-IP mapping and the network mode" - // ErrConflictNetworkPublishPorts conflict between the publish options and the network mode - ErrConflictNetworkPublishPorts validationError = "conflicting options: port publishing and the container type network mode" - // ErrConflictNetworkExposePorts conflict between the expose option and the network mode - ErrConflictNetworkExposePorts validationError = "conflicting options: port exposing and the container type network mode" - // ErrUnsupportedNetworkAndIP conflict between network mode and requested ip address - ErrUnsupportedNetworkAndIP validationError = "user specified IP address is supported on user defined networks only" - // ErrUnsupportedNetworkNoSubnetAndIP conflict between network with no configured subnet and requested ip address - ErrUnsupportedNetworkNoSubnetAndIP validationError = "user specified IP address is supported only when connecting to networks with user configured subnets" - // ErrUnsupportedNetworkAndAlias conflict between network mode and alias - 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" -) +import cerrdefs "github.com/containerd/errdefs" -type validationError string - -func (e validationError) Error() string { - return string(e) +func validationError(msg string) error { + return cerrdefs.ErrInvalidArgument.WithMessage(msg) } -func (e validationError) InvalidParameter() {} - -type invalidJSONError struct { - Err error -} +type invalidJSONError struct{ error } func (e invalidJSONError) Error() string { - return "invalid JSON: " + e.Err.Error() + return "invalid JSON: " + e.error.Error() } func (e invalidJSONError) Unwrap() error { - return e.Err + return e.error } func (e invalidJSONError) InvalidParameter() {} diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go index 37b98e499e..2e212d83b8 100644 --- a/runconfig/hostconfig.go +++ b/runconfig/hostconfig.go @@ -1,8 +1,6 @@ package runconfig -import ( - "github.com/moby/moby/api/types/container" -) +import "github.com/moby/moby/api/types/container" // validateNetContainerMode ensures that the various combinations of requested // network settings wrt container mode are valid. @@ -17,27 +15,27 @@ func validateNetContainerMode(c *container.Config, hc *container.HostConfig) err } if c.Hostname != "" { - return ErrConflictNetworkHostname + return validationError("conflicting options: hostname and the network mode") } if len(hc.Links) > 0 { - return ErrConflictContainerNetworkAndLinks + return validationError("conflicting options: container type network can't be used with links. This would result in undefined behavior") } if len(hc.DNS) > 0 { - return ErrConflictNetworkAndDNS + return validationError("conflicting options: dns and the network mode") } if len(hc.ExtraHosts) > 0 { - return ErrConflictNetworkHosts + return validationError("conflicting options: custom host-to-IP mapping and the network mode") } if len(hc.PortBindings) > 0 || hc.PublishAllPorts { - return ErrConflictNetworkPublishPorts + return validationError("conflicting options: port publishing and the container type network mode") } if len(c.ExposedPorts) > 0 { - return ErrConflictNetworkExposePorts + return validationError("conflicting options: port exposing and the container type network mode") } return nil } diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go index 9951619f7e..07c2964b75 100644 --- a/runconfig/hostconfig_unix.go +++ b/runconfig/hostconfig_unix.go @@ -18,10 +18,10 @@ func validateNetMode(c *container.Config, hc *container.HostConfig) error { return err } if hc.UTSMode.IsHost() && c.Hostname != "" { - return ErrConflictUTSHostname + return validationError("conflicting options: hostname and the UTS mode") } if hc.NetworkMode.IsHost() && len(hc.Links) > 0 { - return ErrConflictHostNetworkAndLinks + return validationError("conflicting options: host type networking can't be used with links. This would result in undefined behavior") } return nil }