diff --git a/api/client/client.go b/api/client/client.go index e42eebc21c..7da14e2cbb 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -9,9 +9,9 @@ import ( "github.com/docker/docker/api/client/lib" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/runconfig" ) // apiClient is an interface that clients that talk with a docker server must implement. @@ -19,7 +19,7 @@ type apiClient interface { ClientVersion() string ContainerAttach(options types.ContainerAttachOptions) (types.HijackedResponse, error) ContainerCommit(options types.ContainerCommitOptions) (types.ContainerCommitResponse, error) - ContainerCreate(config *runconfig.ContainerConfigWrapper, containerName string) (types.ContainerCreateResponse, error) + ContainerCreate(config *container.Config, hostConfig *container.HostConfig, containerName string) (types.ContainerCreateResponse, error) ContainerDiff(containerID string) ([]types.ContainerChange, error) ContainerExecAttach(execID string, config types.ExecConfig) (types.HijackedResponse, error) ContainerExecCreate(config types.ExecConfig) (types.ContainerExecCreateResponse, error) diff --git a/api/client/commit.go b/api/client/commit.go index e7550dc27b..48678d4d8f 100644 --- a/api/client/commit.go +++ b/api/client/commit.go @@ -6,11 +6,11 @@ import ( "fmt" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" Cli "github.com/docker/docker/cli" "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/reference" - "github.com/docker/docker/runconfig" ) // CmdCommit creates a new image from a container's changes. @@ -54,9 +54,9 @@ func (cli *DockerCli) CmdCommit(args ...string) error { } } - var config *runconfig.Config + var config *container.Config if *flConfig != "" { - config = &runconfig.Config{} + config = &container.Config{} if err := json.Unmarshal([]byte(*flConfig), config); err != nil { return err } diff --git a/api/client/create.go b/api/client/create.go index 0336e86f33..7a4070b0b9 100644 --- a/api/client/create.go +++ b/api/client/create.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/api/client/lib" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" Cli "github.com/docker/docker/cli" "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/reference" @@ -78,9 +79,7 @@ func newCIDFile(path string) (*cidFile, error) { return &cidFile{path: path, file: f}, nil } -func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runconfig.HostConfig, cidfile, name string) (*types.ContainerCreateResponse, error) { - mergedConfig := runconfig.MergeConfigs(config, hostConfig) - +func (cli *DockerCli) createContainer(config *container.Config, hostConfig *container.HostConfig, cidfile, name string) (*types.ContainerCreateResponse, error) { var containerIDFile *cidFile if cidfile != "" { var err error @@ -108,7 +107,7 @@ func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runc } //create the container - response, err := cli.client.ContainerCreate(mergedConfig, name) + response, err := cli.client.ContainerCreate(config, hostConfig, name) //if image not found try to pull it if err != nil { if lib.IsErrImageNotFound(err) { @@ -125,7 +124,7 @@ func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runc } // Retry var retryErr error - response, retryErr = cli.client.ContainerCreate(mergedConfig, name) + response, retryErr = cli.client.ContainerCreate(config, hostConfig, name) if retryErr != nil { return nil, retryErr } diff --git a/api/client/lib/container_create.go b/api/client/lib/container_create.go index a5f24b09fc..e563d7b5a2 100644 --- a/api/client/lib/container_create.go +++ b/api/client/lib/container_create.go @@ -6,19 +6,29 @@ import ( "strings" "github.com/docker/docker/api/types" - "github.com/docker/docker/runconfig" + "github.com/docker/docker/api/types/container" ) +type configWrapper struct { + *container.Config + HostConfig *container.HostConfig +} + // ContainerCreate creates a new container based in the given configuration. // It can be associated with a name, but it's not mandatory. -func (cli *Client) ContainerCreate(config *runconfig.ContainerConfigWrapper, containerName string) (types.ContainerCreateResponse, error) { +func (cli *Client) ContainerCreate(config *container.Config, hostConfig *container.HostConfig, containerName string) (types.ContainerCreateResponse, error) { var response types.ContainerCreateResponse query := url.Values{} if containerName != "" { query.Set("name", containerName) } - serverResp, err := cli.post("/containers/create", query, config, nil) + body := configWrapper{ + Config: config, + HostConfig: hostConfig, + } + + serverResp, err := cli.post("/containers/create", query, body, nil) if err != nil { if serverResp != nil && serverResp.statusCode == 404 && strings.Contains(err.Error(), config.Image) { return response, imageNotFoundError{config.Image} diff --git a/api/client/lib/image_build.go b/api/client/lib/image_build.go index 364a921fbb..0ed5da8dc1 100644 --- a/api/client/lib/image_build.go +++ b/api/client/lib/image_build.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/docker/docker/api/types" - "github.com/docker/docker/runconfig" + "github.com/docker/docker/api/types/container" "github.com/docker/go-units" ) @@ -73,7 +73,7 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro query.Set("pull", "1") } - if !runconfig.IsolationLevel.IsDefault(runconfig.IsolationLevel(options.Isolation)) { + if !container.IsolationLevel.IsDefault(container.IsolationLevel(options.Isolation)) { query.Set("isolation", options.Isolation) } diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go index 8b1ff8fa78..9744033f76 100644 --- a/api/server/router/build/build_routes.go +++ b/api/server/router/build/build_routes.go @@ -14,6 +14,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder" "github.com/docker/docker/builder/dockerfile" "github.com/docker/docker/daemon/daemonbuilder" @@ -24,7 +25,6 @@ import ( "github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/ulimit" "github.com/docker/docker/reference" - "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" "golang.org/x/net/context" ) @@ -144,8 +144,8 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r * buildConfig.ShmSize = &shmSize } - if i := runconfig.IsolationLevel(r.FormValue("isolation")); i != "" { - if !runconfig.IsolationLevel.IsValid(i) { + if i := container.IsolationLevel(r.FormValue("isolation")); i != "" { + if !container.IsolationLevel.IsValid(i) { return errf(fmt.Errorf("Unsupported isolation: %q", i)) } buildConfig.Isolation = i diff --git a/api/server/router/container/backend.go b/api/server/router/container/backend.go index d2c50991dd..fa58324f85 100644 --- a/api/server/router/container/backend.go +++ b/api/server/router/container/backend.go @@ -5,11 +5,11 @@ import ( "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon" "github.com/docker/docker/daemon/exec" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/version" - "github.com/docker/docker/runconfig" ) // execBackend includes functions to implement to provide exec functionality. @@ -39,7 +39,7 @@ type stateBackend interface { ContainerResize(name string, height, width int) error ContainerRestart(name string, seconds int) error ContainerRm(name string, config *types.ContainerRmConfig) error - ContainerStart(name string, hostConfig *runconfig.HostConfig) error + ContainerStart(name string, hostConfig *container.HostConfig) error ContainerStop(name string, seconds int) error ContainerUnpause(name string) error ContainerWait(name string, timeout time.Duration) (int, error) diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go index beea7a8f25..461d784124 100644 --- a/api/server/router/container/container_routes.go +++ b/api/server/router/container/container_routes.go @@ -13,6 +13,7 @@ import ( "github.com/docker/distribution/registry/api/errcode" "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" timetypes "github.com/docker/docker/api/types/time" "github.com/docker/docker/daemon" derr "github.com/docker/docker/errors" @@ -162,7 +163,7 @@ 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 - var hostConfig *runconfig.HostConfig + var hostConfig *container.HostConfig if r.Body != nil && (r.ContentLength > 0 || r.ContentLength == -1) { if err := httputils.CheckForJSON(r); err != nil { return err diff --git a/api/server/router/local/image.go b/api/server/router/local/image.go index ffd7bbb8f6..450c6dd65e 100644 --- a/api/server/router/local/image.go +++ b/api/server/router/local/image.go @@ -12,6 +12,7 @@ import ( "github.com/docker/distribution/digest" "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder/dockerfile" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/ioutils" @@ -43,7 +44,7 @@ func (s *router) postCommit(ctx context.Context, w http.ResponseWriter, r *http. return err } if c == nil { - c = &runconfig.Config{} + c = &container.Config{} } if !s.daemon.Exists(cname) { @@ -162,8 +163,8 @@ func (s *router) postImagesCreate(ctx context.Context, w http.ResponseWriter, r // 'err' MUST NOT be defined within this block, we need any error // generated from the download to be available to the output // stream processing below - var newConfig *runconfig.Config - newConfig, err = dockerfile.BuildFromConfig(&runconfig.Config{}, r.Form["changes"]) + var newConfig *container.Config + newConfig, err = dockerfile.BuildFromConfig(&container.Config{}, r.Form["changes"]) if err != nil { return err } diff --git a/api/types/client.go b/api/types/client.go index 4846e502b7..4a0877f97f 100644 --- a/api/types/client.go +++ b/api/types/client.go @@ -5,9 +5,9 @@ import ( "io" "net" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/pkg/ulimit" - "github.com/docker/docker/runconfig" ) // ContainerAttachOptions holds parameters to attach to a container. @@ -28,7 +28,7 @@ type ContainerCommitOptions struct { Author string Changes []string Pause bool - Config *runconfig.Config + Config *container.Config } // ContainerExecInspect holds information returned by exec inspect. diff --git a/api/types/configs.go b/api/types/configs.go index cc026e73f8..ba8f0e006f 100644 --- a/api/types/configs.go +++ b/api/types/configs.go @@ -1,18 +1,16 @@ package types +import "github.com/docker/docker/api/types/container" + // configs holds structs used for internal communication between the // frontend (such as an http server) and the backend (such as the // docker daemon). -import ( - "github.com/docker/docker/runconfig" -) - // ContainerCreateConfig is the parameter set to ContainerCreate() type ContainerCreateConfig struct { Name string - Config *runconfig.Config - HostConfig *runconfig.HostConfig + Config *container.Config + HostConfig *container.HostConfig AdjustCPUShares bool } @@ -33,7 +31,7 @@ type ContainerCommitConfig struct { Comment string // merge container config into commit config before commit MergeConfigs bool - Config *runconfig.Config + Config *container.Config } // ExecConfig is a small subset of the Config struct that hold the configuration diff --git a/api/types/container/config.go b/api/types/container/config.go new file mode 100644 index 0000000000..5459b5dbaf --- /dev/null +++ b/api/types/container/config.go @@ -0,0 +1,38 @@ +package container + +import ( + "github.com/docker/docker/api/types/strslice" + "github.com/docker/go-connections/nat" +) + +// Config contains the configuration data about a container. +// It should hold only portable information about the container. +// Here, "portable" means "independent from the host we are running on". +// Non-portable information *should* appear in HostConfig. +// All fields added to this struct must be marked `omitempty` to keep getting +// predictable hashes from the old `v1Compatibility` configuration. +type Config struct { + Hostname string // Hostname + Domainname string // Domainname + User string // User that will run the command(s) inside the container + AttachStdin bool // Attach the standard input, makes possible user interaction + AttachStdout bool // Attach the standard output + AttachStderr bool // Attach the standard error + ExposedPorts map[nat.Port]struct{} `json:",omitempty"` // List of exposed ports + PublishService string `json:",omitempty"` // Name of the network service exposed by the container + Tty bool // Attach standard streams to a tty, including stdin if it is not closed. + OpenStdin bool // Open stdin + StdinOnce bool // If true, close stdin after the 1 attached client disconnects. + Env []string // List of environment variable to set in the container + Cmd *strslice.StrSlice // Command to run when starting the container + ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific) + Image string // Name of the image as it was passed by the operator (eg. could be symbolic) + Volumes map[string]struct{} // List of volumes (mounts) used for the container + WorkingDir string // Current directory (PWD) in the command will be launched + Entrypoint *strslice.StrSlice // Entrypoint to run when starting the container + NetworkDisabled bool `json:",omitempty"` // Is network disabled + MacAddress string `json:",omitempty"` // Mac Address of the container + OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile + Labels map[string]string // List of labels set to this container + StopSignal string `json:",omitempty"` // Signal to stop a container +} diff --git a/api/types/container/host_config.go b/api/types/container/host_config.go new file mode 100644 index 0000000000..e1d4ea4095 --- /dev/null +++ b/api/types/container/host_config.go @@ -0,0 +1,228 @@ +package container + +import ( + "strings" + + "github.com/docker/docker/api/types/blkiodev" + "github.com/docker/docker/api/types/strslice" + "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-connections/nat" +) + +// NetworkMode represents the container network stack. +type NetworkMode string + +// IsolationLevel represents the isolation level of a container. The supported +// values are platform specific +type IsolationLevel string + +// IsDefault indicates the default isolation level of a container. On Linux this +// is the native driver. On Windows, this is a Windows Server Container. +func (i IsolationLevel) IsDefault() bool { + return strings.ToLower(string(i)) == "default" || string(i) == "" +} + +// IpcMode represents the container ipc stack. +type IpcMode string + +// IsPrivate indicates whether the container uses it's private ipc stack. +func (n IpcMode) IsPrivate() bool { + return !(n.IsHost() || n.IsContainer()) +} + +// IsHost indicates whether the container uses the host's ipc stack. +func (n IpcMode) IsHost() bool { + return n == "host" +} + +// IsContainer indicates whether the container uses a container's ipc stack. +func (n IpcMode) IsContainer() bool { + parts := strings.SplitN(string(n), ":", 2) + return len(parts) > 1 && parts[0] == "container" +} + +// Valid indicates whether the ipc stack is valid. +func (n IpcMode) Valid() bool { + parts := strings.Split(string(n), ":") + switch mode := parts[0]; mode { + case "", "host": + case "container": + if len(parts) != 2 || parts[1] == "" { + return false + } + default: + return false + } + return true +} + +// Container returns the name of the container ipc stack is going to be used. +func (n IpcMode) Container() string { + parts := strings.SplitN(string(n), ":", 2) + if len(parts) > 1 { + return parts[1] + } + return "" +} + +// UTSMode represents the UTS namespace of the container. +type UTSMode string + +// IsPrivate indicates whether the container uses it's private UTS namespace. +func (n UTSMode) IsPrivate() bool { + return !(n.IsHost()) +} + +// IsHost indicates whether the container uses the host's UTS namespace. +func (n UTSMode) IsHost() bool { + return n == "host" +} + +// Valid indicates whether the UTS namespace is valid. +func (n UTSMode) Valid() bool { + parts := strings.Split(string(n), ":") + switch mode := parts[0]; mode { + case "", "host": + default: + return false + } + return true +} + +// PidMode represents the pid stack of the container. +type PidMode string + +// IsPrivate indicates whether the container uses it's private pid stack. +func (n PidMode) IsPrivate() bool { + return !(n.IsHost()) +} + +// IsHost indicates whether the container uses the host's pid stack. +func (n PidMode) IsHost() bool { + return n == "host" +} + +// Valid indicates whether the pid stack is valid. +func (n PidMode) Valid() bool { + parts := strings.Split(string(n), ":") + switch mode := parts[0]; mode { + case "", "host": + default: + return false + } + return true +} + +// DeviceMapping represents the device mapping between the host and the container. +type DeviceMapping struct { + PathOnHost string + PathInContainer string + CgroupPermissions string +} + +// RestartPolicy represents the restart policies of the container. +type RestartPolicy struct { + Name string + MaximumRetryCount int +} + +// IsNone indicates whether the container has the "no" restart policy. +// This means the container will not automatically restart when exiting. +func (rp *RestartPolicy) IsNone() bool { + return rp.Name == "no" +} + +// IsAlways indicates whether the container has the "always" restart policy. +// This means the container will automatically restart regardless of the exit status. +func (rp *RestartPolicy) IsAlways() bool { + return rp.Name == "always" +} + +// IsOnFailure indicates whether the container has the "on-failure" restart policy. +// This means the contain will automatically restart of exiting with a non-zero exit status. +func (rp *RestartPolicy) IsOnFailure() bool { + return rp.Name == "on-failure" +} + +// IsUnlessStopped indicates whether the container has the +// "unless-stopped" restart policy. This means the container will +// automatically restart unless user has put it to stopped state. +func (rp *RestartPolicy) IsUnlessStopped() bool { + return rp.Name == "unless-stopped" +} + +// LogConfig represents the logging configuration of the container. +type LogConfig struct { + Type string + Config map[string]string +} + +// Resources contains container's resources (cgroups config, ulimits...) +type Resources struct { + // Applicable to all platforms + CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) + + // Applicable to UNIX platforms + CgroupParent string // Parent cgroup. + BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) + BlkioWeightDevice []*blkiodev.WeightDevice + BlkioDeviceReadBps []*blkiodev.ThrottleDevice + BlkioDeviceWriteBps []*blkiodev.ThrottleDevice + BlkioDeviceReadIOps []*blkiodev.ThrottleDevice + BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice + CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period + CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota + CpusetCpus string // CpusetCpus 0-2, 0,1 + CpusetMems string // CpusetMems 0-2, 0,1 + Devices []DeviceMapping // List of devices to map inside the container + KernelMemory int64 // Kernel memory limit (in bytes) + Memory int64 // Memory limit (in bytes) + MemoryReservation int64 // Memory soft limit (in bytes) + MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap + MemorySwappiness *int64 // Tuning container memory swappiness behaviour + OomKillDisable bool // Whether to disable OOM Killer or not + Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container +} + +// HostConfig the non-portable Config structure of a container. +// Here, "non-portable" means "dependent of the host we are running on". +// Portable information *should* appear in Config. +type HostConfig struct { + // Applicable to all platforms + Binds []string // List of volume bindings for this container + ContainerIDFile string // File (path) where the containerId is written + LogConfig LogConfig // Configuration of the logs for this container + NetworkMode NetworkMode // Network mode to use for the container + PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host + RestartPolicy RestartPolicy // Restart policy to be used for the container + VolumeDriver string // Name of the volume driver used to mount volumes + VolumesFrom []string // List of volumes to take from other container + + // Applicable to UNIX platforms + CapAdd *strslice.StrSlice // List of kernel capabilities to add to the container + CapDrop *strslice.StrSlice // List of kernel capabilities to remove from the container + DNS []string `json:"Dns"` // List of DNS server to lookup + DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for + DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for + ExtraHosts []string // List of extra hosts + GroupAdd []string // List of additional groups that the container process will run as + IpcMode IpcMode // IPC namespace to use for the container + Links []string // List of links (in the name:alias form) + OomScoreAdj int // Container preference for OOM-killing + OomKillDisable bool // Whether to disable OOM Killer or not + PidMode PidMode // PID namespace to use for the container + Privileged bool // Is the container in privileged mode + PublishAllPorts bool // Should docker publish all exposed port for the container + ReadonlyRootfs bool // Is the container root filesystem in read-only + SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. + Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container + UTSMode UTSMode // UTS namespace to use for the container + ShmSize *int64 // Total shm memory usage + + // Applicable to Windows + ConsoleSize [2]int // Initial console size + Isolation IsolationLevel // Isolation level of the container (eg default, hyperv) + + // Contains container's resources (cgroups, ulimits) + Resources +} diff --git a/api/types/container/hostconfig_unix.go b/api/types/container/hostconfig_unix.go new file mode 100644 index 0000000000..775e903f1c --- /dev/null +++ b/api/types/container/hostconfig_unix.go @@ -0,0 +1,87 @@ +// +build !windows + +package container + +import "strings" + +// IsValid indicates is an isolation level is valid +func (i IsolationLevel) IsValid() bool { + return i.IsDefault() +} + +// IsPrivate indicates whether container uses it's private network stack. +func (n NetworkMode) IsPrivate() bool { + return !(n.IsHost() || n.IsContainer()) +} + +// IsDefault indicates whether container uses the default network stack. +func (n NetworkMode) IsDefault() bool { + return n == "default" +} + +// NetworkName returns the name of the network stack. +func (n NetworkMode) NetworkName() string { + if n.IsBridge() { + return "bridge" + } else if n.IsHost() { + return "host" + } else if n.IsContainer() { + return "container" + } else if n.IsNone() { + return "none" + } else if n.IsDefault() { + return "default" + } else if n.IsUserDefined() { + return n.UserDefined() + } + return "" +} + +// IsBridge indicates whether container uses the bridge network stack +func (n NetworkMode) IsBridge() bool { + return n == "bridge" +} + +// IsHost indicates whether container uses the host network stack. +func (n NetworkMode) IsHost() bool { + return n == "host" +} + +// IsContainer indicates whether container uses a container network stack. +func (n NetworkMode) IsContainer() bool { + parts := strings.SplitN(string(n), ":", 2) + return len(parts) > 1 && parts[0] == "container" +} + +// IsNone indicates whether container isn't using a network stack. +func (n NetworkMode) IsNone() bool { + return n == "none" +} + +// ConnectedContainer is the id of the container which network this container is connected to. +func (n NetworkMode) ConnectedContainer() string { + parts := strings.SplitN(string(n), ":", 2) + if len(parts) > 1 { + return parts[1] + } + return "" +} + +// IsUserDefined indicates user-created network +func (n NetworkMode) IsUserDefined() bool { + return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() +} + +// IsPreDefinedNetwork indicates if a network is predefined by the daemon +func IsPreDefinedNetwork(network string) bool { + n := NetworkMode(network) + return n.IsBridge() || n.IsHost() || n.IsNone() +} + +//UserDefined indicates user-created network +func (n NetworkMode) UserDefined() string { + if n.IsUserDefined() { + return string(n) + } + return "" +} diff --git a/api/types/container/hostconfig_windows.go b/api/types/container/hostconfig_windows.go new file mode 100644 index 0000000000..16267ff416 --- /dev/null +++ b/api/types/container/hostconfig_windows.go @@ -0,0 +1,75 @@ +package container + +import ( + "fmt" + "strings" +) + +// IsDefault indicates whether container uses the default network stack. +func (n NetworkMode) IsDefault() bool { + return n == "default" +} + +// IsHyperV indicates the use of a Hyper-V partition for isolation +func (i IsolationLevel) IsHyperV() bool { + return strings.ToLower(string(i)) == "hyperv" +} + +// IsProcess indicates the use of process isolation +func (i IsolationLevel) IsProcess() bool { + return strings.ToLower(string(i)) == "process" +} + +// IsValid indicates is an isolation level is valid +func (i IsolationLevel) IsValid() bool { + return i.IsDefault() || i.IsHyperV() || i.IsProcess() +} + +// DefaultDaemonNetworkMode returns the default network stack the daemon should +// use. +func DefaultDaemonNetworkMode() NetworkMode { + return NetworkMode("default") +} + +// NetworkName returns the name of the network stack. +func (n NetworkMode) NetworkName() string { + if n.IsDefault() { + return "default" + } + return "" +} + +// IsPreDefinedNetwork indicates if a network is predefined by the daemon +func IsPreDefinedNetwork(network string) bool { + return false +} + +// ValidateNetMode ensures that the various combinations of requested +// network settings are valid. +func ValidateNetMode(c *Config, hc *HostConfig) error { + // We may not be passed a host config, such as in the case of docker commit + if hc == nil { + return nil + } + parts := strings.Split(string(hc.NetworkMode), ":") + switch mode := parts[0]; mode { + case "default", "none": + default: + return fmt.Errorf("invalid --net: %s", hc.NetworkMode) + } + return nil +} + +// ValidateIsolationLevel performs platform specific validation of the +// isolation level in the hostconfig structure. Windows supports 'default' (or +// blank), 'process', or 'hyperv'. +func ValidateIsolationLevel(hc *HostConfig) error { + // We may not be passed a host config, such as in the case of docker commit + if hc == nil { + return nil + } + if !hc.Isolation.IsValid() { + return fmt.Errorf("invalid --isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation) + } + return nil +} diff --git a/api/types/types.go b/api/types/types.go index 8cc73ef7a7..9965cce118 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -4,10 +4,10 @@ import ( "os" "time" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/registry" "github.com/docker/docker/pkg/version" - "github.com/docker/docker/runconfig" "github.com/docker/go-connections/nat" ) @@ -103,10 +103,10 @@ type ImageInspect struct { Comment string Created string Container string - ContainerConfig *runconfig.Config + ContainerConfig *container.Config DockerVersion string Author string - Config *runconfig.Config + Config *container.Config Architecture string Os string Size int64 @@ -283,7 +283,7 @@ type ContainerJSONBase struct { ProcessLabel string AppArmorProfile string ExecIDs []string - HostConfig *runconfig.HostConfig + HostConfig *container.HostConfig GraphDriver GraphDriverData SizeRw *int64 `json:",omitempty"` SizeRootFs *int64 `json:",omitempty"` @@ -293,7 +293,7 @@ type ContainerJSONBase struct { type ContainerJSON struct { *ContainerJSONBase Mounts []MountPoint - Config *runconfig.Config + Config *container.Config NetworkSettings *NetworkSettings } diff --git a/api/types/versions/v1p19/types.go b/api/types/versions/v1p19/types.go index 66777bf2c5..dc13150545 100644 --- a/api/types/versions/v1p19/types.go +++ b/api/types/versions/v1p19/types.go @@ -3,8 +3,8 @@ package v1p19 import ( "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/versions/v1p20" - "github.com/docker/docker/runconfig" "github.com/docker/go-connections/nat" ) @@ -20,7 +20,7 @@ type ContainerJSON struct { // ContainerConfig is a backcompatibility struct for APIs prior to 1.20. type ContainerConfig struct { - *runconfig.Config + *container.Config MacAddress string NetworkDisabled bool diff --git a/api/types/versions/v1p20/types.go b/api/types/versions/v1p20/types.go index 6579dcfb7e..fa395ac1f6 100644 --- a/api/types/versions/v1p20/types.go +++ b/api/types/versions/v1p20/types.go @@ -3,7 +3,7 @@ package v1p20 import ( "github.com/docker/docker/api/types" - "github.com/docker/docker/runconfig" + "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" ) @@ -17,7 +17,7 @@ type ContainerJSON struct { // ContainerConfig is a backcompatibility struct used in ContainerJSON for the API 1.20 type ContainerConfig struct { - *runconfig.Config + *container.Config MacAddress string NetworkDisabled bool diff --git a/builder/builder.go b/builder/builder.go index 97e0ad092b..90ab204f8e 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -10,7 +10,7 @@ import ( "time" "github.com/docker/docker/api/types" - "github.com/docker/docker/runconfig" + "github.com/docker/docker/api/types/container" ) // Context represents a file system tree. @@ -113,7 +113,7 @@ type Backend interface { // Kill stops the container execution abruptly. ContainerKill(containerID string, sig uint64) error // Start starts a new container - ContainerStart(containerID string, hostConfig *runconfig.HostConfig) error + ContainerStart(containerID string, hostConfig *container.HostConfig) error // ContainerWait stops processing until the given container is stopped. ContainerWait(containerID string, timeout time.Duration) (int, error) @@ -135,5 +135,5 @@ type Backend interface { type ImageCache interface { // GetCachedImage returns a reference to a cached image whose parent equals `parent` // and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error. - GetCachedImage(parentID string, cfg *runconfig.Config) (imageID string, err error) + GetCachedImage(parentID string, cfg *container.Config) (imageID string, err error) } diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go index b4f7a6a779..0db8c41880 100644 --- a/builder/dockerfile/builder.go +++ b/builder/dockerfile/builder.go @@ -10,11 +10,11 @@ import ( "sync" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder" "github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/ulimit" - "github.com/docker/docker/runconfig" ) var validCommitCommands = map[string]bool{ @@ -52,7 +52,7 @@ type Config struct { ForceRemove bool Pull bool BuildArgs map[string]string // build-time args received in build context for expansion/substitution and commands in 'run'. - Isolation runconfig.IsolationLevel + Isolation container.IsolationLevel // resource constraints // TODO: factor out to be reused with Run ? @@ -81,7 +81,7 @@ type Builder struct { context builder.Context dockerfile *parser.Node - runConfig *runconfig.Config // runconfig for cmd, run, entrypoint etc. + runConfig *container.Config // runconfig for cmd, run, entrypoint etc. flags *BFlags tmpContainers map[string]struct{} image string // imageID @@ -114,7 +114,7 @@ func NewBuilder(config *Config, docker builder.Backend, context builder.Context, Stderr: os.Stderr, docker: docker, context: context, - runConfig: new(runconfig.Config), + runConfig: new(container.Config), tmpContainers: map[string]struct{}{}, cancelled: make(chan struct{}), id: stringid.GenerateNonCryptoID(), @@ -206,7 +206,7 @@ func (b *Builder) Cancel() { // - call parse.Parse() to get AST root from Dockerfile entries // - do build by calling builder.dispatch() to call all entries' handling routines // TODO: remove? -func BuildFromConfig(config *runconfig.Config, changes []string) (*runconfig.Config, error) { +func BuildFromConfig(config *container.Config, changes []string) (*container.Config, error) { ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n"))) if err != nil { return nil, err diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go index 2371861eeb..ce5f457a5e 100644 --- a/builder/dockerfile/internals.go +++ b/builder/dockerfile/internals.go @@ -21,6 +21,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/api" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/builder" "github.com/docker/docker/builder/dockerfile/parser" @@ -34,7 +35,6 @@ import ( "github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/tarsum" "github.com/docker/docker/pkg/urlutil" - "github.com/docker/docker/runconfig" ) func (b *Builder) commit(id string, autoCmd *strslice.StrSlice, comment string) error { @@ -476,7 +476,7 @@ func (b *Builder) create() (string, error) { } b.runConfig.Image = b.image - resources := runconfig.Resources{ + resources := container.Resources{ CgroupParent: b.CgroupParent, CPUShares: b.CPUShares, CPUPeriod: b.CPUPeriod, @@ -489,7 +489,7 @@ func (b *Builder) create() (string, error) { } // TODO: why not embed a hostconfig in builder? - hostConfig := &runconfig.HostConfig{ + hostConfig := &container.HostConfig{ Isolation: b.Isolation, ShmSize: b.ShmSize, Resources: resources, diff --git a/builder/image.go b/builder/image.go index c8d5fc15d9..4de620fae6 100644 --- a/builder/image.go +++ b/builder/image.go @@ -1,9 +1,9 @@ package builder -import "github.com/docker/docker/runconfig" +import "github.com/docker/docker/api/types/container" // Image represents a Docker image used by the builder. type Image interface { ID() string - Config() *runconfig.Config + Config() *container.Config } diff --git a/container/container.go b/container/container.go index cc0ca97f2a..ebe70b44ea 100644 --- a/container/container.go +++ b/container/container.go @@ -11,6 +11,7 @@ import ( "time" "github.com/Sirupsen/logrus" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon/exec" "github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/daemon/logger" @@ -43,7 +44,7 @@ type CommonContainer struct { Created time.Time Path string Args []string - Config *runconfig.Config + Config *containertypes.Config ImageID image.ID `json:"Image"` NetworkSettings *network.Settings LogPath string @@ -56,8 +57,8 @@ type CommonContainer struct { HasBeenStartedBefore bool HasBeenManuallyStopped bool // used for unless-stopped restart policy MountPoints map[string]*volume.MountPoint - HostConfig *runconfig.HostConfig `json:"-"` // do not serialize the host config in the json, otherwise we'll make the container unportable - Command *execdriver.Command `json:"-"` + HostConfig *containertypes.HostConfig `json:"-"` // do not serialize the host config in the json, otherwise we'll make the container unportable + Command *execdriver.Command `json:"-"` monitor *containerMonitor ExecCommands *exec.Store `json:"-"` // logDriver for closing @@ -139,7 +140,7 @@ func (container *Container) ToDiskLocking() error { // readHostConfig reads the host configuration from disk for the container. func (container *Container) readHostConfig() error { - container.HostConfig = &runconfig.HostConfig{} + container.HostConfig = &containertypes.HostConfig{} // If the hostconfig file does not exist, do not read it. // (We still have to initialize container.HostConfig, // but that's OK, since we just did that above.) @@ -261,7 +262,7 @@ func (container *Container) exposes(p nat.Port) bool { } // GetLogConfig returns the log configuration for the container. -func (container *Container) GetLogConfig(defaultConfig runconfig.LogConfig) runconfig.LogConfig { +func (container *Container) GetLogConfig(defaultConfig containertypes.LogConfig) containertypes.LogConfig { cfg := container.HostConfig.LogConfig if cfg.Type != "" || len(cfg.Config) > 0 { // container has log driver configured if cfg.Type == "" { @@ -274,7 +275,7 @@ func (container *Container) GetLogConfig(defaultConfig runconfig.LogConfig) runc } // StartLogger starts a new logger driver for the container. -func (container *Container) StartLogger(cfg runconfig.LogConfig) (logger.Logger, error) { +func (container *Container) StartLogger(cfg containertypes.LogConfig) (logger.Logger, error) { c, err := logger.GetLogDriver(cfg.Type) if err != nil { return nil, derr.ErrorCodeLoggingFactory.WithArgs(err) diff --git a/container/container_unit_test.go b/container/container_unit_test.go index abc1033168..f14dc12e97 100644 --- a/container/container_unit_test.go +++ b/container/container_unit_test.go @@ -3,14 +3,14 @@ package container import ( "testing" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/signal" - "github.com/docker/docker/runconfig" ) func TestContainerStopSignal(t *testing.T) { c := &Container{ CommonContainer: CommonContainer{ - Config: &runconfig.Config{}, + Config: &container.Config{}, }, } @@ -26,7 +26,7 @@ func TestContainerStopSignal(t *testing.T) { c = &Container{ CommonContainer: CommonContainer{ - Config: &runconfig.Config{StopSignal: "SIGKILL"}, + Config: &container.Config{StopSignal: "SIGKILL"}, }, } s = c.StopSignal() diff --git a/container/monitor.go b/container/monitor.go index 3c29ba362e..8098f23bae 100644 --- a/container/monitor.go +++ b/container/monitor.go @@ -9,11 +9,11 @@ import ( "time" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon/execdriver" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/promise" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" ) @@ -51,7 +51,7 @@ type containerMonitor struct { container *Container // restartPolicy is the current policy being applied to the container monitor - restartPolicy runconfig.RestartPolicy + restartPolicy container.RestartPolicy // failureCount is the number of times the container has failed to // start in a row @@ -79,7 +79,7 @@ type containerMonitor struct { // StartMonitor initializes a containerMonitor for this container with the provided supervisor and restart policy // and starts the container's process. -func (container *Container) StartMonitor(s supervisor, policy runconfig.RestartPolicy) error { +func (container *Container) StartMonitor(s supervisor, policy container.RestartPolicy) error { container.monitor = &containerMonitor{ supervisor: s, container: container, diff --git a/daemon/config.go b/daemon/config.go index a842bda244..b6477a6f33 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -1,9 +1,9 @@ package daemon import ( + "github.com/docker/docker/api/types/container" "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/runconfig" ) const ( @@ -27,7 +27,7 @@ type CommonConfig struct { GraphDriver string GraphOptions []string Labels []string - LogConfig runconfig.LogConfig + LogConfig container.LogConfig Mtu int Pidfile string RemappedRoot string diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go index 18de732983..6c4f17704a 100644 --- a/daemon/container_operations_unix.go +++ b/daemon/container_operations_unix.go @@ -13,6 +13,7 @@ import ( "time" "github.com/Sirupsen/logrus" + containertypes "github.com/docker/docker/api/types/container" networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/container" "github.com/docker/docker/daemon/execdriver" @@ -460,7 +461,7 @@ func (daemon *Daemon) updateNetworkSettings(container *container.Container, n li container.NetworkSettings = &network.Settings{Networks: make(map[string]*networktypes.EndpointSettings)} } - if !container.HostConfig.NetworkMode.IsHost() && runconfig.NetworkMode(n.Type()).IsHost() { + if !container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() { return runconfig.ErrConflictHostNetwork } @@ -474,12 +475,12 @@ func (daemon *Daemon) updateNetworkSettings(container *container.Container, n li // Avoid duplicate config return nil } - if !runconfig.NetworkMode(sn.Type()).IsPrivate() || - !runconfig.NetworkMode(n.Type()).IsPrivate() { + if !containertypes.NetworkMode(sn.Type()).IsPrivate() || + !containertypes.NetworkMode(n.Type()).IsPrivate() { return runconfig.ErrConflictSharedNetwork } - if runconfig.NetworkMode(sn.Name()).IsNone() || - runconfig.NetworkMode(n.Name()).IsNone() { + if containertypes.NetworkMode(sn.Name()).IsNone() || + containertypes.NetworkMode(n.Name()).IsNone() { return runconfig.ErrConflictNoNetwork } } @@ -493,7 +494,7 @@ func (daemon *Daemon) updateEndpointNetworkSettings(container *container.Contain return err } - if container.HostConfig.NetworkMode == runconfig.NetworkMode("bridge") { + if container.HostConfig.NetworkMode == containertypes.NetworkMode("bridge") { container.NetworkSettings.Bridge = daemon.configStore.Bridge.Iface } @@ -625,7 +626,7 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName return runconfig.ErrConflictSharedNetwork } - if runconfig.NetworkMode(idOrName).IsBridge() && + if containertypes.NetworkMode(idOrName).IsBridge() && daemon.configStore.DisableBridge { container.Config.NetworkDisabled = true return nil @@ -706,7 +707,7 @@ func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n li return derr.ErrorCodeNotRunning.WithArgs(container.ID) } - if container.HostConfig.NetworkMode.IsHost() && runconfig.NetworkMode(n.Type()).IsHost() { + if container.HostConfig.NetworkMode.IsHost() && containertypes.NetworkMode(n.Type()).IsHost() { return runconfig.ErrConflictHostNetwork } @@ -955,7 +956,7 @@ func killProcessDirectly(container *container.Container) error { return nil } -func getDevicesFromPath(deviceMapping runconfig.DeviceMapping) (devs []*configs.Device, err error) { +func getDevicesFromPath(deviceMapping containertypes.DeviceMapping) (devs []*configs.Device, err error) { device, err := devices.DeviceFromPath(deviceMapping.PathOnHost, deviceMapping.CgroupPermissions) // if there was no error, return the device if err == nil { diff --git a/daemon/container_operations_windows.go b/daemon/container_operations_windows.go index 37524d31ea..ebbefa3eb4 100644 --- a/daemon/container_operations_windows.go +++ b/daemon/container_operations_windows.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/container" "github.com/docker/docker/daemon/execdriver" + "github.com/docker/docker/daemon/execdriver/windows" derr "github.com/docker/docker/errors" "github.com/docker/docker/layer" "github.com/docker/libnetwork" @@ -103,6 +104,16 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro } layerFolder := m["dir"] + var hvPartition bool + // Work out the isolation (whether it is a hypervisor partition) + if c.HostConfig.Isolation.IsDefault() { + // Not specified by caller. Take daemon default + hvPartition = windows.DefaultIsolation.IsHyperV() + } else { + // Take value specified by caller + hvPartition = c.HostConfig.Isolation.IsHyperV() + } + c.Command = &execdriver.Command{ CommonCommand: execdriver.CommonCommand{ ID: c.ID, @@ -119,8 +130,9 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro LayerFolder: layerFolder, LayerPaths: layerPaths, Hostname: c.Config.Hostname, - Isolation: c.HostConfig.Isolation, + Isolation: string(c.HostConfig.Isolation), ArgsEscaped: c.Config.ArgsEscaped, + HvPartition: hvPartition, } return nil diff --git a/daemon/create.go b/daemon/create.go index 4767874d8c..aa3d97896e 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -3,12 +3,12 @@ package daemon import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" derr "github.com/docker/docker/errors" "github.com/docker/docker/image" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/runconfig" "github.com/docker/docker/volume" "github.com/opencontainers/runc/libcontainer/label" ) @@ -25,7 +25,7 @@ func (daemon *Daemon) ContainerCreate(params types.ContainerCreateConfig) (types } if params.HostConfig == nil { - params.HostConfig = &runconfig.HostConfig{} + params.HostConfig = &containertypes.HostConfig{} } err = daemon.adaptContainerSettings(params.HostConfig, params.AdjustCPUShares) if err != nil { @@ -111,7 +111,7 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig) (*container.Con return container, nil } -func (daemon *Daemon) generateSecurityOpt(ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) { +func (daemon *Daemon) generateSecurityOpt(ipcMode containertypes.IpcMode, pidMode containertypes.PidMode) ([]string, error) { if ipcMode.IsHost() || pidMode.IsHost() { return label.DisableSecOpt(), nil } diff --git a/daemon/create_unix.go b/daemon/create_unix.go index 741df132b7..25548d231e 100644 --- a/daemon/create_unix.go +++ b/daemon/create_unix.go @@ -6,17 +6,17 @@ import ( "os" "path/filepath" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" derr "github.com/docker/docker/errors" "github.com/docker/docker/image" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/runconfig" "github.com/docker/docker/volume" "github.com/opencontainers/runc/libcontainer/label" ) // createContainerPlatformSpecificSettings performs platform specific container create functionality -func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *runconfig.Config, hostConfig *runconfig.HostConfig, img *image.Image) error { +func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig, img *image.Image) error { if err := daemon.Mount(container); err != nil { return err } diff --git a/daemon/create_windows.go b/daemon/create_windows.go index f150fcbab8..33e54141e2 100644 --- a/daemon/create_windows.go +++ b/daemon/create_windows.go @@ -3,15 +3,15 @@ package daemon import ( "fmt" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/image" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/runconfig" "github.com/docker/docker/volume" ) // createContainerPlatformSpecificSettings performs platform specific container create functionality -func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *runconfig.Config, hostConfig *runconfig.HostConfig, img *image.Image) error { +func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig, img *image.Image) error { for spec := range config.Volumes { mp, err := volume.ParseMountSpec(spec, hostConfig.VolumeDriver) diff --git a/daemon/daemon.go b/daemon/daemon.go index 1df4cb80c9..59bff4013f 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -21,6 +21,7 @@ import ( "github.com/docker/distribution/digest" "github.com/docker/docker/api" "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/strslice" @@ -148,7 +149,7 @@ type Daemon struct { driver graphdriver.Driver execDriver execdriver.Driver statsCollector *statsCollector - defaultLogConfig runconfig.LogConfig + defaultLogConfig containertypes.LogConfig RegistryService *registry.Service EventsService *events.Events netController libnetwork.NetworkController @@ -390,7 +391,7 @@ func (daemon *Daemon) restore() error { return nil } -func (daemon *Daemon) mergeAndVerifyConfig(config *runconfig.Config, img *image.Image) error { +func (daemon *Daemon) mergeAndVerifyConfig(config *containertypes.Config, img *image.Image) error { if img != nil && img.Config != nil { if err := runconfig.Merge(config, img.Config); err != nil { return err @@ -472,7 +473,7 @@ func (daemon *Daemon) generateNewName(id string) (string, error) { return name, nil } -func (daemon *Daemon) generateHostname(id string, config *runconfig.Config) { +func (daemon *Daemon) generateHostname(id string, config *containertypes.Config) { // Generate default hostname if config.Hostname == "" { config.Hostname = id[:12] @@ -488,7 +489,7 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *strslice.StrSlice, return cmdSlice[0], cmdSlice[1:] } -func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID image.ID) (*container.Container, error) { +func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID image.ID) (*container.Container, error) { var ( id string err error @@ -507,7 +508,7 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID base.Path = entrypoint base.Args = args //FIXME: de-duplicate from config base.Config = config - base.HostConfig = &runconfig.HostConfig{} + base.HostConfig = &containertypes.HostConfig{} base.ImageID = imgID base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName} base.Name = name @@ -1366,7 +1367,7 @@ func (daemon *Daemon) GetRemappedUIDGID() (int, int) { // of the image with imgID, that had the same config when it was // created. nil is returned if a child cannot be found. An error is // returned if the parent image cannot be found. -func (daemon *Daemon) ImageGetCached(imgID image.ID, config *runconfig.Config) (*image.Image, error) { +func (daemon *Daemon) ImageGetCached(imgID image.ID, config *containertypes.Config) (*image.Image, error) { // Retrieve all images imgs := daemon.Map() @@ -1402,7 +1403,7 @@ func tempDir(rootDir string, rootUID, rootGID int) (string, error) { return tmpDir, idtools.MkdirAllAs(tmpDir, 0700, rootUID, rootGID) } -func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *runconfig.HostConfig) error { +func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error { container.Lock() if err := parseSecurityOpt(container, hostConfig); err != nil { container.Unlock() @@ -1444,7 +1445,7 @@ func setDefaultMtu(config *Config) { // verifyContainerSettings performs validation of the hostconfig and config // structures. -func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) { +func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config) ([]string, error) { // First perform verification of settings common across all platforms. if config != nil { diff --git a/daemon/daemon_experimental.go b/daemon/daemon_experimental.go index 33d3168f11..d50a8fb283 100644 --- a/daemon/daemon_experimental.go +++ b/daemon/daemon_experimental.go @@ -9,9 +9,9 @@ import ( "runtime" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/directory" "github.com/docker/docker/pkg/idtools" - "github.com/docker/docker/runconfig" ) func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) { @@ -99,7 +99,7 @@ func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error return nil } -func (daemon *Daemon) verifyExperimentalContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) { +func (daemon *Daemon) verifyExperimentalContainerSettings(hostConfig *container.HostConfig, config *container.Config) ([]string, error) { if hostConfig.Privileged && daemon.configStore.RemappedRoot != "" { return nil, fmt.Errorf("Privileged mode is incompatible with user namespace mappings") } diff --git a/daemon/daemon_stub.go b/daemon/daemon_stub.go index 8fbb0508e9..20b2263071 100644 --- a/daemon/daemon_stub.go +++ b/daemon/daemon_stub.go @@ -5,9 +5,9 @@ package daemon import ( "os" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/system" - "github.com/docker/docker/runconfig" ) func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) { @@ -23,6 +23,6 @@ func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error return nil } -func (daemon *Daemon) verifyExperimentalContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) { +func (daemon *Daemon) verifyExperimentalContainerSettings(hostConfig *container.HostConfig, config *container.Config) ([]string, error) { return nil, nil } diff --git a/daemon/daemon_test.go b/daemon/daemon_test.go index 8802d5c65c..c09191b9ce 100644 --- a/daemon/daemon_test.go +++ b/daemon/daemon_test.go @@ -7,10 +7,10 @@ import ( "path/filepath" "testing" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/pkg/graphdb" "github.com/docker/docker/pkg/truncindex" - "github.com/docker/docker/runconfig" "github.com/docker/docker/volume" volumedrivers "github.com/docker/docker/volume/drivers" "github.com/docker/docker/volume/local" @@ -141,7 +141,7 @@ func initDaemonWithVolumeStore(tmp string) (*Daemon, error) { func TestParseSecurityOpt(t *testing.T) { container := &container.Container{} - config := &runconfig.HostConfig{} + config := &containertypes.HostConfig{} // test apparmor config.SecurityOpt = []string{"apparmor:test_profile"} diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index a9c0dcc766..f9782a183e 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -13,6 +13,7 @@ import ( "github.com/Sirupsen/logrus" pblkiodev "github.com/docker/docker/api/types/blkiodev" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/daemon/graphdriver" derr "github.com/docker/docker/errors" @@ -43,7 +44,7 @@ const ( linuxMinMemory = 4194304 ) -func getBlkioWeightDevices(config *runconfig.HostConfig) ([]*blkiodev.WeightDevice, error) { +func getBlkioWeightDevices(config *containertypes.HostConfig) ([]*blkiodev.WeightDevice, error) { var stat syscall.Stat_t var blkioWeightDevices []*blkiodev.WeightDevice @@ -58,7 +59,7 @@ func getBlkioWeightDevices(config *runconfig.HostConfig) ([]*blkiodev.WeightDevi return blkioWeightDevices, nil } -func parseSecurityOpt(container *container.Container, config *runconfig.HostConfig) error { +func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error { var ( labelOpts []string err error @@ -85,7 +86,7 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf return err } -func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioReadIOpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { var blkioReadIOpsDevice []*blkiodev.ThrottleDevice var stat syscall.Stat_t @@ -100,7 +101,7 @@ func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.Throttle return blkioReadIOpsDevice, nil } -func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioWriteIOpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { var blkioWriteIOpsDevice []*blkiodev.ThrottleDevice var stat syscall.Stat_t @@ -115,7 +116,7 @@ func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.Throttl return blkioWriteIOpsDevice, nil } -func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioReadBpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { var blkioReadBpsDevice []*blkiodev.ThrottleDevice var stat syscall.Stat_t @@ -130,7 +131,7 @@ func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleD return blkioReadBpsDevice, nil } -func getBlkioWriteBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioWriteBpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { var blkioWriteBpsDevice []*blkiodev.ThrottleDevice var stat syscall.Stat_t @@ -175,7 +176,7 @@ func checkKernel() error { // adaptContainerSettings is called during container creation to modify any // settings necessary in the HostConfig structure. -func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, adjustCPUShares bool) error { +func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error { if adjustCPUShares && hostConfig.CPUShares > 0 { // Handle unsupported CPUShares if hostConfig.CPUShares < linuxMinCPUShares { @@ -209,7 +210,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a return nil } -func verifyContainerResources(resources *runconfig.Resources) ([]string, error) { +func verifyContainerResources(resources *containertypes.Resources) ([]string, error) { warnings := []string{} sysInfo := sysinfo.New(true) @@ -349,7 +350,7 @@ func verifyContainerResources(resources *runconfig.Resources) ([]string, error) // verifyPlatformContainerSettings performs platform-specific validation of the // hostconfig and config structures. -func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) { +func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config) ([]string, error) { warnings := []string{} sysInfo := sysinfo.New(true) @@ -680,7 +681,7 @@ func setupInitLayer(initLayer string, rootUID, rootGID int) error { } // registerLinks writes the links to a file. -func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *runconfig.HostConfig) error { +func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error { if hostConfig == nil || hostConfig.Links == nil { return nil } diff --git a/daemon/daemon_unix_test.go b/daemon/daemon_unix_test.go index 5d92782d99..083b2bd45b 100644 --- a/daemon/daemon_unix_test.go +++ b/daemon/daemon_unix_test.go @@ -7,7 +7,7 @@ import ( "os" "testing" - "github.com/docker/docker/runconfig" + "github.com/docker/docker/api/types/container" ) func TestAdjustCPUShares(t *testing.T) { @@ -21,8 +21,8 @@ func TestAdjustCPUShares(t *testing.T) { root: tmp, } - hostConfig := &runconfig.HostConfig{ - Resources: runconfig.Resources{CPUShares: linuxMinCPUShares - 1}, + hostConfig := &container.HostConfig{ + Resources: container.Resources{CPUShares: linuxMinCPUShares - 1}, } daemon.adaptContainerSettings(hostConfig, true) if hostConfig.CPUShares != linuxMinCPUShares { @@ -59,8 +59,8 @@ func TestAdjustCPUSharesNoAdjustment(t *testing.T) { root: tmp, } - hostConfig := &runconfig.HostConfig{ - Resources: runconfig.Resources{CPUShares: linuxMinCPUShares - 1}, + hostConfig := &container.HostConfig{ + Resources: container.Resources{CPUShares: linuxMinCPUShares - 1}, } daemon.adaptContainerSettings(hostConfig, false) if hostConfig.CPUShares != linuxMinCPUShares-1 { diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index 2735702f7e..477509c3ba 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/Sirupsen/logrus" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/dockerversion" @@ -18,7 +19,6 @@ import ( // register the windows graph driver "github.com/docker/docker/daemon/graphdriver/windows" "github.com/docker/docker/pkg/system" - "github.com/docker/docker/runconfig" "github.com/docker/libnetwork" blkiodev "github.com/opencontainers/runc/libcontainer/configs" ) @@ -30,27 +30,27 @@ const ( windowsMaxCPUShares = 10000 ) -func getBlkioWeightDevices(config *runconfig.HostConfig) ([]*blkiodev.WeightDevice, error) { +func getBlkioWeightDevices(config *containertypes.HostConfig) ([]*blkiodev.WeightDevice, error) { return nil, nil } -func parseSecurityOpt(container *container.Container, config *runconfig.HostConfig) error { +func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error { return nil } -func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioReadIOpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { return nil, nil } -func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioWriteIOpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { return nil, nil } -func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioReadBpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { return nil, nil } -func getBlkioWriteBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { +func getBlkioWriteBpsDevices(config *containertypes.HostConfig) ([]*blkiodev.ThrottleDevice, error) { return nil, nil } @@ -64,7 +64,7 @@ func checkKernel() error { // adaptContainerSettings is called during container creation to modify any // settings necessary in the HostConfig structure. -func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, adjustCPUShares bool) error { +func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error { if hostConfig == nil { return nil } @@ -82,7 +82,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a // verifyPlatformContainerSettings performs platform-specific validation of the // hostconfig and config structures. -func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) { +func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config) ([]string, error) { return nil, nil } @@ -131,7 +131,7 @@ func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkC // registerLinks sets up links between containers and writes the // configuration out for persistence. As of Windows TP4, links are not supported. -func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *runconfig.HostConfig) error { +func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error { return nil } diff --git a/daemon/daemonbuilder/builder.go b/daemon/daemonbuilder/builder.go index ab4122994b..fec37a6a84 100644 --- a/daemon/daemonbuilder/builder.go +++ b/daemon/daemonbuilder/builder.go @@ -11,6 +11,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/api" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder" "github.com/docker/docker/daemon" "github.com/docker/docker/image" @@ -21,7 +22,6 @@ import ( "github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/reference" "github.com/docker/docker/registry" - "github.com/docker/docker/runconfig" ) // Docker implements builder.Backend for the docker Daemon object. @@ -182,7 +182,7 @@ func (d Docker) BuilderCopy(cID string, destPath string, src builder.FileInfo, d // GetCachedImage returns a reference to a cached image whose parent equals `parent` // and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error. -func (d Docker) GetCachedImage(imgID string, cfg *runconfig.Config) (string, error) { +func (d Docker) GetCachedImage(imgID string, cfg *container.Config) (string, error) { cache, err := d.Daemon.ImageGetCached(image.ID(imgID), cfg) if cache == nil || err != nil { return "", err diff --git a/daemon/daemonbuilder/image.go b/daemon/daemonbuilder/image.go index ab5ab9a322..34dbe3007c 100644 --- a/daemon/daemonbuilder/image.go +++ b/daemon/daemonbuilder/image.go @@ -1,8 +1,8 @@ package daemonbuilder import ( + "github.com/docker/docker/api/types/container" "github.com/docker/docker/image" - "github.com/docker/docker/runconfig" ) type imgWrap struct { @@ -13,6 +13,6 @@ func (img imgWrap) ID() string { return string(img.inner.ID()) } -func (img imgWrap) Config() *runconfig.Config { +func (img imgWrap) Config() *container.Config { return img.inner.Config } diff --git a/daemon/delete_test.go b/daemon/delete_test.go index 1ccba815e8..487bb5d4e3 100644 --- a/daemon/delete_test.go +++ b/daemon/delete_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" - "github.com/docker/docker/runconfig" ) func TestContainerDoubleDelete(t *testing.T) { @@ -26,7 +26,7 @@ func TestContainerDoubleDelete(t *testing.T) { CommonContainer: container.CommonContainer{ ID: "test", State: container.NewState(), - Config: &runconfig.Config{}, + Config: &containertypes.Config{}, }, } daemon.containers.Add(container.ID, container) diff --git a/daemon/execdriver/driver_windows.go b/daemon/execdriver/driver_windows.go index 5ea52d0675..ec482cd30f 100644 --- a/daemon/execdriver/driver_windows.go +++ b/daemon/execdriver/driver_windows.go @@ -1,9 +1,6 @@ package execdriver -import ( - "github.com/docker/docker/runconfig" - "github.com/docker/go-connections/nat" -) +import "github.com/docker/go-connections/nat" // Mount contains information for a mount operation. type Mount struct { @@ -52,12 +49,13 @@ type Command struct { // Fields below here are platform specific - FirstStart bool `json:"first_start"` // Optimisation for first boot of Windows - Hostname string `json:"hostname"` // Windows sets the hostname in the execdriver - LayerFolder string `json:"layer_folder"` // Layer folder for a command - LayerPaths []string `json:"layer_paths"` // Layer paths for a command - Isolation runconfig.IsolationLevel `json:"isolation"` // Isolation level for the container - ArgsEscaped bool `json:"args_escaped"` // True if args are already escaped + FirstStart bool `json:"first_start"` // Optimisation for first boot of Windows + Hostname string `json:"hostname"` // Windows sets the hostname in the execdriver + LayerFolder string `json:"layer_folder"` // Layer folder for a command + LayerPaths []string `json:"layer_paths"` // Layer paths for a command + Isolation string `json:"isolation"` // Isolation level for the container + ArgsEscaped bool `json:"args_escaped"` // True if args are already escaped + HvPartition bool `json:"hv_partition"` // True if it's an hypervisor partition } // ExitStatus provides exit reasons for a container. diff --git a/daemon/execdriver/windows/info.go b/daemon/execdriver/windows/info.go index c85cd8a299..5a92f5d6dc 100644 --- a/daemon/execdriver/windows/info.go +++ b/daemon/execdriver/windows/info.go @@ -3,14 +3,14 @@ package windows import ( + "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon/execdriver" - "github.com/docker/docker/runconfig" ) type info struct { ID string driver *Driver - isolation runconfig.IsolationLevel + isolation container.IsolationLevel } // Info implements the exec driver Driver interface. @@ -18,7 +18,7 @@ func (d *Driver) Info(id string) execdriver.Info { return &info{ ID: id, driver: d, - isolation: defaultIsolation, + isolation: DefaultIsolation, } } diff --git a/daemon/execdriver/windows/run.go b/daemon/execdriver/windows/run.go index b2f0966857..95d91dbc28 100644 --- a/daemon/execdriver/windows/run.go +++ b/daemon/execdriver/windows/run.go @@ -104,14 +104,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd HostName: c.Hostname, } - // Work out the isolation (whether it is a hypervisor partition) - if c.Isolation.IsDefault() { - // Not specified by caller. Take daemon default - cu.HvPartition = defaultIsolation.IsHyperV() - } else { - // Take value specified by caller - cu.HvPartition = c.Isolation.IsHyperV() - } + cu.HvPartition = c.HvPartition if cu.HvPartition { cu.SandboxPath = filepath.Dir(c.LayerFolder) diff --git a/daemon/execdriver/windows/windows.go b/daemon/execdriver/windows/windows.go index 3edb57ee51..810f452ed5 100644 --- a/daemon/execdriver/windows/windows.go +++ b/daemon/execdriver/windows/windows.go @@ -8,10 +8,10 @@ import ( "sync" "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/dockerversion" "github.com/docker/docker/pkg/parsers" - "github.com/docker/docker/runconfig" ) // This is a daemon development variable only and should not be @@ -22,11 +22,11 @@ var dummyMode bool // This allows the daemon to force kill (HCS terminate) rather than shutdown var forceKill bool -// defaultIsolation allows users to specify a default isolation mode for +// DefaultIsolation allows users to specify a default isolation mode for // when running a container on Windows. For example docker daemon -D // --exec-opt isolation=hyperv will cause Windows to always run containers // as Hyper-V containers unless otherwise specified. -var defaultIsolation runconfig.IsolationLevel = "process" +var DefaultIsolation container.IsolationLevel = "process" // Define name and version for windows var ( @@ -48,7 +48,7 @@ type Driver struct { // Name implements the exec driver Driver interface. func (d *Driver) Name() string { - return fmt.Sprintf("\n Name: %s\n Build: %s \n Default Isolation: %s", DriverName, Version, defaultIsolation) + return fmt.Sprintf("\n Name: %s\n Build: %s \n Default Isolation: %s", DriverName, Version, DefaultIsolation) } // NewDriver returns a new windows driver, called from NewDriver of execdriver. @@ -77,11 +77,11 @@ func NewDriver(root string, options []string) (*Driver, error) { } case "isolation": - if !runconfig.IsolationLevel(val).IsValid() { + if !container.IsolationLevel(val).IsValid() { return nil, fmt.Errorf("Unrecognised exec driver option 'isolation':'%s'", val) } - if runconfig.IsolationLevel(val).IsHyperV() { - defaultIsolation = "hyperv" + if container.IsolationLevel(val).IsHyperV() { + DefaultIsolation = "hyperv" } logrus.Infof("Windows default isolation level: '%s'", val) default: diff --git a/daemon/import.go b/daemon/import.go index f09ab672aa..26f8ce66fe 100644 --- a/daemon/import.go +++ b/daemon/import.go @@ -8,6 +8,7 @@ import ( "runtime" "time" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/dockerversion" "github.com/docker/docker/image" "github.com/docker/docker/layer" @@ -15,14 +16,13 @@ import ( "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/reference" - "github.com/docker/docker/runconfig" ) // ImportImage imports an image, getting the archived layer data either from // inConfig (if src is "-"), or from a URI specified in src. Progress output is // written to outStream. Repository and tag names can optionally be given in // the repo and tag arguments, respectively. -func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *runconfig.Config) error { +func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *container.Config) error { var ( sf = streamformatter.NewJSONStreamFormatter() archive io.ReadCloser diff --git a/daemon/start.go b/daemon/start.go index 639e6aec01..27279d6b37 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -4,13 +4,14 @@ import ( "runtime" "github.com/Sirupsen/logrus" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" derr "github.com/docker/docker/errors" "github.com/docker/docker/runconfig" ) // ContainerStart starts a container. -func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConfig) error { +func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig) error { container, err := daemon.GetContainer(name) if err != nil { return err diff --git a/daemon/volumes.go b/daemon/volumes.go index 33e8a20aad..4b5522d66a 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/daemon/execdriver" derr "github.com/docker/docker/errors" - "github.com/docker/docker/runconfig" "github.com/docker/docker/volume" "github.com/opencontainers/runc/libcontainer/label" ) @@ -71,7 +71,7 @@ func (m mounts) parts(i int) int { // 2. Select the volumes mounted from another containers. Overrides previously configured mount point destination. // 3. Select the bind mounts set by the client. Overrides previously configured mount point destinations. // 4. Cleanup old volumes that are about to be reassigned. -func (daemon *Daemon) registerMountPoints(container *container.Container, hostConfig *runconfig.HostConfig) error { +func (daemon *Daemon) registerMountPoints(container *container.Container, hostConfig *containertypes.HostConfig) error { binds := map[string]bool{} mountPoints := map[string]*volume.MountPoint{} diff --git a/image/image.go b/image/image.go index ee4a2884f9..c0508c1b98 100644 --- a/image/image.go +++ b/image/image.go @@ -7,7 +7,7 @@ import ( "time" "github.com/docker/distribution/digest" - "github.com/docker/docker/runconfig" + "github.com/docker/docker/api/types/container" ) // ID is the content-addressable ID of an image. @@ -30,13 +30,13 @@ type V1Image struct { // Container is the id of the container used to commit Container string `json:"container,omitempty"` // ContainerConfig is the configuration of the container that is committed into the image - ContainerConfig runconfig.Config `json:"container_config,omitempty"` + ContainerConfig container.Config `json:"container_config,omitempty"` // DockerVersion specifies version on which image is built DockerVersion string `json:"docker_version,omitempty"` // Author of the image Author string `json:"author,omitempty"` // Config is the configuration of the container received from the client - Config *runconfig.Config `json:"config,omitempty"` + Config *container.Config `json:"config,omitempty"` // Architecture is the hardware that the image is build and runs on Architecture string `json:"architecture,omitempty"` // OS is the operating system used to build and run the image diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 4e6322643a..5c33520170 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -16,10 +16,10 @@ import ( "time" "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/integration" "github.com/docker/docker/pkg/integration/checker" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/runconfig" "github.com/go-check/check" ) @@ -678,7 +678,7 @@ func UtilCreateNetworkMode(c *check.C, networkMode string) { var containerJSON types.ContainerJSON c.Assert(json.Unmarshal(body, &containerJSON), checker.IsNil) - c.Assert(containerJSON.HostConfig.NetworkMode, checker.Equals, runconfig.NetworkMode(networkMode), check.Commentf("Mismatched NetworkMode")) + c.Assert(containerJSON.HostConfig.NetworkMode, checker.Equals, containertypes.NetworkMode(networkMode), check.Commentf("Mismatched NetworkMode")) } func (s *DockerSuite) TestContainerApiCreateWithCpuSharesCpuset(c *check.C) { diff --git a/integration-cli/docker_cli_inspect_test.go b/integration-cli/docker_cli_inspect_test.go index 2da0b3ca3d..d471936be4 100644 --- a/integration-cli/docker_cli_inspect_test.go +++ b/integration-cli/docker_cli_inspect_test.go @@ -9,8 +9,8 @@ import ( "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/integration/checker" - "github.com/docker/docker/runconfig" "github.com/go-check/check" ) @@ -281,7 +281,7 @@ func (s *DockerSuite) TestInspectTimesAsRFC3339Nano(c *check.C) { func (s *DockerSuite) TestInspectLogConfigNoType(c *check.C) { testRequires(c, DaemonIsLinux) dockerCmd(c, "create", "--name=test", "--log-opt", "max-file=42", "busybox") - var logConfig runconfig.LogConfig + var logConfig container.LogConfig out, err := inspectFieldJSON("test", "HostConfig.LogConfig") c.Assert(err, checker.IsNil, check.Commentf("%v", out)) diff --git a/runconfig/compare.go b/runconfig/compare.go index ebb8ead6c1..81f16b0a35 100644 --- a/runconfig/compare.go +++ b/runconfig/compare.go @@ -1,8 +1,10 @@ package runconfig +import "github.com/docker/docker/api/types/container" + // Compare two Config struct. Do not compare the "Image" nor "Hostname" fields // If OpenStdin is set, then it differs -func Compare(a, b *Config) bool { +func Compare(a, b *container.Config) bool { if a == nil || b == nil || a.OpenStdin || b.OpenStdin { return false diff --git a/runconfig/compare_test.go b/runconfig/compare_test.go index 25f2d34df0..ed7528d67b 100644 --- a/runconfig/compare_test.go +++ b/runconfig/compare_test.go @@ -3,6 +3,7 @@ package runconfig import ( "testing" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/docker/go-connections/nat" ) @@ -43,11 +44,11 @@ func TestCompare(t *testing.T) { labels2 := map[string]string{"LABEL1": "value1", "LABEL2": "value3"} labels3 := map[string]string{"LABEL1": "value1", "LABEL2": "value2", "LABEL3": "value3"} - sameConfigs := map[*Config]*Config{ + sameConfigs := map[*container.Config]*container.Config{ // Empty config - &Config{}: {}, + &container.Config{}: {}, // Does not compare hostname, domainname & image - &Config{ + &container.Config{ Hostname: "host1", Domainname: "domain1", Image: "image1", @@ -59,23 +60,23 @@ func TestCompare(t *testing.T) { User: "user", }, // only OpenStdin - &Config{OpenStdin: false}: {OpenStdin: false}, + &container.Config{OpenStdin: false}: {OpenStdin: false}, // only env - &Config{Env: envs1}: {Env: envs1}, + &container.Config{Env: envs1}: {Env: envs1}, // only cmd - &Config{Cmd: cmd1}: {Cmd: cmd1}, + &container.Config{Cmd: cmd1}: {Cmd: cmd1}, // only labels - &Config{Labels: labels1}: {Labels: labels1}, + &container.Config{Labels: labels1}: {Labels: labels1}, // only exposedPorts - &Config{ExposedPorts: ports1}: {ExposedPorts: ports1}, + &container.Config{ExposedPorts: ports1}: {ExposedPorts: ports1}, // only entrypoints - &Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint1}, + &container.Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint1}, // only volumes - &Config{Volumes: volumes1}: {Volumes: volumes1}, + &container.Config{Volumes: volumes1}: {Volumes: volumes1}, } - differentConfigs := map[*Config]*Config{ + differentConfigs := map[*container.Config]*container.Config{ nil: nil, - &Config{ + &container.Config{ Hostname: "host1", Domainname: "domain1", Image: "image1", @@ -87,30 +88,30 @@ func TestCompare(t *testing.T) { User: "user2", }, // only OpenStdin - &Config{OpenStdin: false}: {OpenStdin: true}, - &Config{OpenStdin: true}: {OpenStdin: false}, + &container.Config{OpenStdin: false}: {OpenStdin: true}, + &container.Config{OpenStdin: true}: {OpenStdin: false}, // only env - &Config{Env: envs1}: {Env: envs2}, + &container.Config{Env: envs1}: {Env: envs2}, // only cmd - &Config{Cmd: cmd1}: {Cmd: cmd2}, + &container.Config{Cmd: cmd1}: {Cmd: cmd2}, // not the same number of parts - &Config{Cmd: cmd1}: {Cmd: cmd3}, + &container.Config{Cmd: cmd1}: {Cmd: cmd3}, // only labels - &Config{Labels: labels1}: {Labels: labels2}, + &container.Config{Labels: labels1}: {Labels: labels2}, // not the same number of labels - &Config{Labels: labels1}: {Labels: labels3}, + &container.Config{Labels: labels1}: {Labels: labels3}, // only exposedPorts - &Config{ExposedPorts: ports1}: {ExposedPorts: ports2}, + &container.Config{ExposedPorts: ports1}: {ExposedPorts: ports2}, // not the same number of ports - &Config{ExposedPorts: ports1}: {ExposedPorts: ports3}, + &container.Config{ExposedPorts: ports1}: {ExposedPorts: ports3}, // only entrypoints - &Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint2}, + &container.Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint2}, // not the same number of parts - &Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint3}, + &container.Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint3}, // only volumes - &Config{Volumes: volumes1}: {Volumes: volumes2}, + &container.Config{Volumes: volumes1}: {Volumes: volumes2}, // not the same number of labels - &Config{Volumes: volumes1}: {Volumes: volumes3}, + &container.Config{Volumes: volumes1}: {Volumes: volumes3}, } for config1, config2 := range sameConfigs { if !Compare(config1, config2) { diff --git a/runconfig/config.go b/runconfig/config.go index d162126509..d12457393c 100644 --- a/runconfig/config.go +++ b/runconfig/config.go @@ -5,48 +5,15 @@ import ( "fmt" "io" - "github.com/docker/docker/api/types/strslice" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/volume" - "github.com/docker/go-connections/nat" ) -// Config contains the configuration data about a container. -// It should hold only portable information about the container. -// Here, "portable" means "independent from the host we are running on". -// Non-portable information *should* appear in HostConfig. -// All fields added to this struct must be marked `omitempty` to keep getting -// predictable hashes from the old `v1Compatibility` configuration. -type Config struct { - Hostname string // Hostname - Domainname string // Domainname - User string // User that will run the command(s) inside the container - AttachStdin bool // Attach the standard input, makes possible user interaction - AttachStdout bool // Attach the standard output - AttachStderr bool // Attach the standard error - ExposedPorts map[nat.Port]struct{} `json:",omitempty"` // List of exposed ports - PublishService string `json:",omitempty"` // Name of the network service exposed by the container - Tty bool // Attach standard streams to a tty, including stdin if it is not closed. - OpenStdin bool // Open stdin - StdinOnce bool // If true, close stdin after the 1 attached client disconnects. - Env []string // List of environment variable to set in the container - Cmd *strslice.StrSlice // Command to run when starting the container - ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific) - Image string // Name of the image as it was passed by the operator (eg. could be symbolic) - Volumes map[string]struct{} // List of volumes (mounts) used for the container - WorkingDir string // Current directory (PWD) in the command will be launched - Entrypoint *strslice.StrSlice // Entrypoint to run when starting the container - NetworkDisabled bool `json:",omitempty"` // Is network disabled - MacAddress string `json:",omitempty"` // Mac Address of the container - OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile - Labels map[string]string // List of labels set to this container - StopSignal string `json:",omitempty"` // Signal to stop a container -} - // DecodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper // struct and returns both a Config and an HostConfig struct // Be aware this function is not checking whether the resulted structs are nil, // it's your business to do so -func DecodeContainerConfig(src io.Reader) (*Config, *HostConfig, error) { +func DecodeContainerConfig(src io.Reader) (*container.Config, *container.HostConfig, error) { var w ContainerConfigWrapper decoder := json.NewDecoder(src) @@ -85,7 +52,7 @@ func DecodeContainerConfig(src io.Reader) (*Config, *HostConfig, error) { // validateVolumesAndBindSettings validates each of the volumes and bind settings // passed by the caller to ensure they are valid. -func validateVolumesAndBindSettings(c *Config, hc *HostConfig) error { +func validateVolumesAndBindSettings(c *container.Config, hc *container.HostConfig) error { // Ensure all volumes and binds are valid. for spec := range c.Volumes { diff --git a/runconfig/config_test.go b/runconfig/config_test.go index e09b13ac26..7a1c785c2f 100644 --- a/runconfig/config_test.go +++ b/runconfig/config_test.go @@ -9,6 +9,7 @@ import ( "strings" "testing" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" ) @@ -101,16 +102,16 @@ func TestDecodeContainerConfigIsolation(t *testing.T) { // callDecodeContainerConfigIsolation is a utility function to call // DecodeContainerConfig for validating isolation levels -func callDecodeContainerConfigIsolation(isolation string) (*Config, *HostConfig, error) { +func callDecodeContainerConfigIsolation(isolation string) (*container.Config, *container.HostConfig, error) { var ( b []byte err error ) w := ContainerConfigWrapper{ - Config: &Config{}, - HostConfig: &HostConfig{ + Config: &container.Config{}, + HostConfig: &container.HostConfig{ NetworkMode: "none", - Isolation: IsolationLevel(isolation)}, + Isolation: container.IsolationLevel(isolation)}, } if b, err = json.Marshal(w); err != nil { return nil, nil, fmt.Errorf("Error on marshal %s", err.Error()) diff --git a/runconfig/config_unix.go b/runconfig/config_unix.go index 18b2fee7c8..05af155f5d 100644 --- a/runconfig/config_unix.go +++ b/runconfig/config_unix.go @@ -2,18 +2,20 @@ package runconfig +import "github.com/docker/docker/api/types/container" + // ContainerConfigWrapper is a Config wrapper that hold the container Config (portable) // and the corresponding HostConfig (non-portable). type ContainerConfigWrapper struct { - *Config - InnerHostConfig *HostConfig `json:"HostConfig,omitempty"` - Cpuset string `json:",omitempty"` // Deprecated. Exported for backwards compatibility. - *HostConfig // Deprecated. Exported to read attributes from json that are not in the inner host config structure. + *container.Config + InnerHostConfig *container.HostConfig `json:"HostConfig,omitempty"` + Cpuset string `json:",omitempty"` // Deprecated. Exported for backwards compatibility. + *container.HostConfig // Deprecated. Exported to read attributes from json that are not in the inner host config structure. } // getHostConfig gets the HostConfig of the Config. // It's mostly there to handle Deprecated fields of the ContainerConfigWrapper -func (w *ContainerConfigWrapper) getHostConfig() *HostConfig { +func (w *ContainerConfigWrapper) getHostConfig() *container.HostConfig { hc := w.HostConfig if hc == nil && w.InnerHostConfig != nil { diff --git a/runconfig/config_windows.go b/runconfig/config_windows.go index 2ab8e19a27..6ff7afcdaf 100644 --- a/runconfig/config_windows.go +++ b/runconfig/config_windows.go @@ -1,13 +1,15 @@ package runconfig +import "github.com/docker/docker/api/types/container" + // ContainerConfigWrapper is a Config wrapper that hold the container Config (portable) // and the corresponding HostConfig (non-portable). type ContainerConfigWrapper struct { - *Config - HostConfig *HostConfig `json:"HostConfig,omitempty"` + *container.Config + HostConfig *container.HostConfig `json:"HostConfig,omitempty"` } // getHostConfig gets the HostConfig of the Config. -func (w *ContainerConfigWrapper) getHostConfig() *HostConfig { +func (w *ContainerConfigWrapper) getHostConfig() *container.HostConfig { return w.HostConfig } diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go index 3b9cf226f3..2b81d02c20 100644 --- a/runconfig/hostconfig.go +++ b/runconfig/hostconfig.go @@ -3,240 +3,13 @@ package runconfig import ( "encoding/json" "io" - "strings" - "github.com/docker/docker/api/types/blkiodev" - "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/pkg/ulimit" - "github.com/docker/go-connections/nat" + "github.com/docker/docker/api/types/container" ) -// KeyValuePair is a structure that hold a value for a key. -type KeyValuePair struct { - Key string - Value string -} - -// NetworkMode represents the container network stack. -type NetworkMode string - -// IsolationLevel represents the isolation level of a container. The supported -// values are platform specific -type IsolationLevel string - -// IsDefault indicates the default isolation level of a container. On Linux this -// is the native driver. On Windows, this is a Windows Server Container. -func (i IsolationLevel) IsDefault() bool { - return strings.ToLower(string(i)) == "default" || string(i) == "" -} - -// IpcMode represents the container ipc stack. -type IpcMode string - -// IsPrivate indicates whether the container uses it's private ipc stack. -func (n IpcMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsHost indicates whether the container uses the host's ipc stack. -func (n IpcMode) IsHost() bool { - return n == "host" -} - -// IsContainer indicates whether the container uses a container's ipc stack. -func (n IpcMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// Valid indicates whether the ipc stack is valid. -func (n IpcMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - case "container": - if len(parts) != 2 || parts[1] == "" { - return false - } - default: - return false - } - return true -} - -// Container returns the name of the container ipc stack is going to be used. -func (n IpcMode) Container() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// UTSMode represents the UTS namespace of the container. -type UTSMode string - -// IsPrivate indicates whether the container uses it's private UTS namespace. -func (n UTSMode) IsPrivate() bool { - return !(n.IsHost()) -} - -// IsHost indicates whether the container uses the host's UTS namespace. -func (n UTSMode) IsHost() bool { - return n == "host" -} - -// Valid indicates whether the UTS namespace is valid. -func (n UTSMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true -} - -// PidMode represents the pid stack of the container. -type PidMode string - -// IsPrivate indicates whether the container uses it's private pid stack. -func (n PidMode) IsPrivate() bool { - return !(n.IsHost()) -} - -// IsHost indicates whether the container uses the host's pid stack. -func (n PidMode) IsHost() bool { - return n == "host" -} - -// Valid indicates whether the pid stack is valid. -func (n PidMode) Valid() bool { - parts := strings.Split(string(n), ":") - switch mode := parts[0]; mode { - case "", "host": - default: - return false - } - return true -} - -// DeviceMapping represents the device mapping between the host and the container. -type DeviceMapping struct { - PathOnHost string - PathInContainer string - CgroupPermissions string -} - -// RestartPolicy represents the restart policies of the container. -type RestartPolicy struct { - Name string - MaximumRetryCount int -} - -// IsNone indicates whether the container has the "no" restart policy. -// This means the container will not automatically restart when exiting. -func (rp *RestartPolicy) IsNone() bool { - return rp.Name == "no" -} - -// IsAlways indicates whether the container has the "always" restart policy. -// This means the container will automatically restart regardless of the exit status. -func (rp *RestartPolicy) IsAlways() bool { - return rp.Name == "always" -} - -// IsOnFailure indicates whether the container has the "on-failure" restart policy. -// This means the contain will automatically restart of exiting with a non-zero exit status. -func (rp *RestartPolicy) IsOnFailure() bool { - return rp.Name == "on-failure" -} - -// IsUnlessStopped indicates whether the container has the -// "unless-stopped" restart policy. This means the container will -// automatically restart unless user has put it to stopped state. -func (rp *RestartPolicy) IsUnlessStopped() bool { - return rp.Name == "unless-stopped" -} - -// LogConfig represents the logging configuration of the container. -type LogConfig struct { - Type string - Config map[string]string -} - -// Resources contains container's resources (cgroups config, ulimits...) -type Resources struct { - // Applicable to all platforms - CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) - - // Applicable to UNIX platforms - CgroupParent string // Parent cgroup. - BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) - BlkioWeightDevice []*blkiodev.WeightDevice - BlkioDeviceReadBps []*blkiodev.ThrottleDevice - BlkioDeviceWriteBps []*blkiodev.ThrottleDevice - BlkioDeviceReadIOps []*blkiodev.ThrottleDevice - BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice - CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period - CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota - CpusetCpus string // CpusetCpus 0-2, 0,1 - CpusetMems string // CpusetMems 0-2, 0,1 - Devices []DeviceMapping // List of devices to map inside the container - KernelMemory int64 // Kernel memory limit (in bytes) - Memory int64 // Memory limit (in bytes) - MemoryReservation int64 // Memory soft limit (in bytes) - MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap - MemorySwappiness *int64 // Tuning container memory swappiness behaviour - OomKillDisable bool // Whether to disable OOM Killer or not - Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container -} - -// HostConfig the non-portable Config structure of a container. -// Here, "non-portable" means "dependent of the host we are running on". -// Portable information *should* appear in Config. -type HostConfig struct { - // Applicable to all platforms - Binds []string // List of volume bindings for this container - ContainerIDFile string // File (path) where the containerId is written - LogConfig LogConfig // Configuration of the logs for this container - NetworkMode NetworkMode // Network mode to use for the container - PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host - RestartPolicy RestartPolicy // Restart policy to be used for the container - VolumeDriver string // Name of the volume driver used to mount volumes - VolumesFrom []string // List of volumes to take from other container - - // Applicable to UNIX platforms - CapAdd *strslice.StrSlice // List of kernel capabilities to add to the container - CapDrop *strslice.StrSlice // List of kernel capabilities to remove from the container - DNS []string `json:"Dns"` // List of DNS server to lookup - DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for - DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for - ExtraHosts []string // List of extra hosts - GroupAdd []string // List of additional groups that the container process will run as - IpcMode IpcMode // IPC namespace to use for the container - Links []string // List of links (in the name:alias form) - OomScoreAdj int // Container preference for OOM-killing - PidMode PidMode // PID namespace to use for the container - Privileged bool // Is the container in privileged mode - PublishAllPorts bool // Should docker publish all exposed port for the container - ReadonlyRootfs bool // Is the container root filesystem in read-only - SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. - Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container - UTSMode UTSMode // UTS namespace to use for the container - ShmSize *int64 // Total shm memory usage - - // Applicable to Windows - ConsoleSize [2]int // Initial console size - Isolation IsolationLevel // Isolation level of the container (eg default, hyperv) - - // Contains container's resources (cgroups, ulimits) - Resources -} - // 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) (*HostConfig, error) { +func DecodeHostConfig(src io.Reader) (*container.HostConfig, error) { decoder := json.NewDecoder(src) var w ContainerConfigWrapper @@ -252,10 +25,10 @@ func DecodeHostConfig(src io.Reader) (*HostConfig, error) { // 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 // docker daemon. -func SetDefaultNetModeIfBlank(hc *HostConfig) *HostConfig { +func SetDefaultNetModeIfBlank(hc *container.HostConfig) *container.HostConfig { if hc != nil { - if hc.NetworkMode == NetworkMode("") { - hc.NetworkMode = NetworkMode("default") + if hc.NetworkMode == container.NetworkMode("") { + hc.NetworkMode = container.NetworkMode("default") } } return hc diff --git a/runconfig/hostconfig_test.go b/runconfig/hostconfig_test.go index 9fe3fa782d..941c16d6e8 100644 --- a/runconfig/hostconfig_test.go +++ b/runconfig/hostconfig_test.go @@ -7,11 +7,13 @@ import ( "fmt" "io/ioutil" "testing" + + "github.com/docker/docker/api/types/container" ) // TODO Windows: This will need addressing for a Windows daemon. func TestNetworkModeTest(t *testing.T) { - networkModes := map[NetworkMode][]bool{ + networkModes := map[container.NetworkMode][]bool{ // private, bridge, host, container, none, default "": {true, false, false, false, false, false}, "something:weird": {true, false, false, false, false, false}, @@ -22,7 +24,7 @@ func TestNetworkModeTest(t *testing.T) { "none": {true, false, false, false, true, false}, "default": {true, false, false, false, false, true}, } - networkModeNames := map[NetworkMode]string{ + networkModeNames := map[container.NetworkMode]string{ "": "", "something:weird": "something:weird", "bridge": "bridge", @@ -58,7 +60,7 @@ func TestNetworkModeTest(t *testing.T) { } func TestIpcModeTest(t *testing.T) { - ipcModes := map[IpcMode][]bool{ + ipcModes := map[container.IpcMode][]bool{ // private, host, container, valid "": {true, false, false, true}, "something:weird": {true, false, false, false}, @@ -82,7 +84,7 @@ func TestIpcModeTest(t *testing.T) { t.Fatalf("IpcMode.Valid for %v should have been %v but was %v", ipcMode, state[3], ipcMode.Valid()) } } - containerIpcModes := map[IpcMode]string{ + containerIpcModes := map[container.IpcMode]string{ "": "", "something": "", "something:weird": "weird", @@ -99,7 +101,7 @@ func TestIpcModeTest(t *testing.T) { } func TestUTSModeTest(t *testing.T) { - utsModes := map[UTSMode][]bool{ + utsModes := map[container.UTSMode][]bool{ // private, host, valid "": {true, false, true}, "something:weird": {true, false, false}, @@ -120,7 +122,7 @@ func TestUTSModeTest(t *testing.T) { } func TestPidModeTest(t *testing.T) { - pidModes := map[PidMode][]bool{ + pidModes := map[container.PidMode][]bool{ // private, host, valid "": {true, false, true}, "something:weird": {true, false, false}, @@ -141,13 +143,13 @@ func TestPidModeTest(t *testing.T) { } func TestRestartPolicy(t *testing.T) { - restartPolicies := map[RestartPolicy][]bool{ + restartPolicies := map[container.RestartPolicy][]bool{ // none, always, failure - RestartPolicy{}: {false, false, false}, - RestartPolicy{"something", 0}: {false, false, false}, - RestartPolicy{"no", 0}: {true, false, false}, - RestartPolicy{"always", 0}: {false, true, false}, - RestartPolicy{"on-failure", 0}: {false, false, true}, + container.RestartPolicy{}: {false, false, false}, + container.RestartPolicy{"something", 0}: {false, false, false}, + container.RestartPolicy{"no", 0}: {true, false, false}, + container.RestartPolicy{"always", 0}: {false, true, false}, + container.RestartPolicy{"on-failure", 0}: {false, false, true}, } for restartPolicy, state := range restartPolicies { if restartPolicy.IsNone() != state[0] { @@ -161,28 +163,6 @@ func TestRestartPolicy(t *testing.T) { } } } - -func TestMergeConfigs(t *testing.T) { - expectedHostname := "hostname" - expectedContainerIDFile := "containerIdFile" - config := &Config{ - Hostname: expectedHostname, - } - hostConfig := &HostConfig{ - ContainerIDFile: expectedContainerIDFile, - } - containerConfigWrapper := MergeConfigs(config, hostConfig) - if containerConfigWrapper.Config.Hostname != expectedHostname { - t.Fatalf("containerConfigWrapper config hostname expected %v got %v", expectedHostname, containerConfigWrapper.Config.Hostname) - } - if containerConfigWrapper.InnerHostConfig.ContainerIDFile != expectedContainerIDFile { - t.Fatalf("containerConfigWrapper hostconfig containerIdfile expected %v got %v", expectedContainerIDFile, containerConfigWrapper.InnerHostConfig.ContainerIDFile) - } - if containerConfigWrapper.Cpuset != "" { - t.Fatalf("Expected empty Cpuset, got %v", containerConfigWrapper.Cpuset) - } -} - func TestDecodeHostConfig(t *testing.T) { fixtures := []struct { file string diff --git a/runconfig/hostconfig_unix.go b/runconfig/hostconfig_unix.go index 7aad5a33f0..4c28799395 100644 --- a/runconfig/hostconfig_unix.go +++ b/runconfig/hostconfig_unix.go @@ -6,109 +6,25 @@ import ( "fmt" "runtime" "strings" + + "github.com/docker/docker/api/types/container" ) -// IsValid indicates is an isolation level is valid -func (i IsolationLevel) IsValid() bool { - return i.IsDefault() -} - -// IsPrivate indicates whether container uses it's private network stack. -func (n NetworkMode) IsPrivate() bool { - return !(n.IsHost() || n.IsContainer()) -} - -// IsDefault indicates whether container uses the default network stack. -func (n NetworkMode) IsDefault() bool { - return n == "default" -} - // DefaultDaemonNetworkMode returns the default network stack the daemon should // use. -func DefaultDaemonNetworkMode() NetworkMode { - return NetworkMode("bridge") -} - -// NetworkName returns the name of the network stack. -func (n NetworkMode) NetworkName() string { - if n.IsBridge() { - return "bridge" - } else if n.IsHost() { - return "host" - } else if n.IsContainer() { - return "container" - } else if n.IsNone() { - return "none" - } else if n.IsDefault() { - return "default" - } else if n.IsUserDefined() { - return n.UserDefined() - } - return "" -} - -// IsBridge indicates whether container uses the bridge network stack -func (n NetworkMode) IsBridge() bool { - return n == "bridge" -} - -// IsHost indicates whether container uses the host network stack. -func (n NetworkMode) IsHost() bool { - return n == "host" -} - -// IsContainer indicates whether container uses a container network stack. -func (n NetworkMode) IsContainer() bool { - parts := strings.SplitN(string(n), ":", 2) - return len(parts) > 1 && parts[0] == "container" -} - -// IsNone indicates whether container isn't using a network stack. -func (n NetworkMode) IsNone() bool { - return n == "none" -} - -// ConnectedContainer is the id of the container which network this container is connected to. -func (n NetworkMode) ConnectedContainer() string { - parts := strings.SplitN(string(n), ":", 2) - if len(parts) > 1 { - return parts[1] - } - return "" -} - -// IsUserDefined indicates user-created network -func (n NetworkMode) IsUserDefined() bool { - return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() +func DefaultDaemonNetworkMode() container.NetworkMode { + return container.NetworkMode("bridge") } // IsPreDefinedNetwork indicates if a network is predefined by the daemon func IsPreDefinedNetwork(network string) bool { - n := NetworkMode(network) + n := container.NetworkMode(network) return n.IsBridge() || n.IsHost() || n.IsNone() } -//UserDefined indicates user-created network -func (n NetworkMode) UserDefined() string { - if n.IsUserDefined() { - return string(n) - } - return "" -} - -// MergeConfigs merges the specified container Config and HostConfig. -// It creates a ContainerConfigWrapper. -func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrapper { - return &ContainerConfigWrapper{ - config, - hostConfig, - "", nil, - } -} - // ValidateNetMode ensures that the various combinations of requested // network settings are valid. -func ValidateNetMode(c *Config, hc *HostConfig) error { +func ValidateNetMode(c *container.Config, hc *container.HostConfig) error { // We may not be passed a host config, such as in the case of docker commit if hc == nil { return nil @@ -161,7 +77,7 @@ func ValidateNetMode(c *Config, hc *HostConfig) error { // ValidateIsolationLevel performs platform specific validation of the // isolation level in the hostconfig structure. Linux only supports "default" // which is LXC container isolation -func ValidateIsolationLevel(hc *HostConfig) error { +func ValidateIsolationLevel(hc *container.HostConfig) error { // We may not be passed a host config, such as in the case of docker commit if hc == nil { return nil diff --git a/runconfig/hostconfig_windows.go b/runconfig/hostconfig_windows.go index 211c93b281..3cade744ad 100644 --- a/runconfig/hostconfig_windows.go +++ b/runconfig/hostconfig_windows.go @@ -3,49 +3,14 @@ package runconfig import ( "fmt" "strings" + + "github.com/docker/docker/api/types/container" ) -// IsDefault indicates whether container uses the default network stack. -func (n NetworkMode) IsDefault() bool { - return n == "default" -} - -// IsHyperV indicates the use of a Hyper-V partition for isolation -func (i IsolationLevel) IsHyperV() bool { - return strings.ToLower(string(i)) == "hyperv" -} - -// IsProcess indicates the use of process isolation -func (i IsolationLevel) IsProcess() bool { - return strings.ToLower(string(i)) == "process" -} - -// IsValid indicates is an isolation level is valid -func (i IsolationLevel) IsValid() bool { - return i.IsDefault() || i.IsHyperV() || i.IsProcess() -} - // DefaultDaemonNetworkMode returns the default network stack the daemon should // use. -func DefaultDaemonNetworkMode() NetworkMode { - return NetworkMode("default") -} - -// NetworkName returns the name of the network stack. -func (n NetworkMode) NetworkName() string { - if n.IsDefault() { - return "default" - } - return "" -} - -// MergeConfigs merges the specified container Config and HostConfig. -// It creates a ContainerConfigWrapper. -func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrapper { - return &ContainerConfigWrapper{ - config, - hostConfig, - } +func DefaultDaemonNetworkMode() container.NetworkMode { + return container.NetworkMode("default") } // IsPreDefinedNetwork indicates if a network is predefined by the daemon @@ -55,7 +20,7 @@ func IsPreDefinedNetwork(network string) bool { // ValidateNetMode ensures that the various combinations of requested // network settings are valid. -func ValidateNetMode(c *Config, hc *HostConfig) error { +func ValidateNetMode(c *container.Config, hc *container.HostConfig) error { // We may not be passed a host config, such as in the case of docker commit if hc == nil { return nil @@ -72,7 +37,7 @@ func ValidateNetMode(c *Config, hc *HostConfig) error { // ValidateIsolationLevel performs platform specific validation of the // isolation level in the hostconfig structure. Windows supports 'default' (or // blank), 'process', or 'hyperv'. -func ValidateIsolationLevel(hc *HostConfig) error { +func ValidateIsolationLevel(hc *container.HostConfig) error { // We may not be passed a host config, such as in the case of docker commit if hc == nil { return nil diff --git a/runconfig/merge.go b/runconfig/merge.go index 6dfd646a7c..d2e953df27 100644 --- a/runconfig/merge.go +++ b/runconfig/merge.go @@ -3,6 +3,7 @@ package runconfig import ( "strings" + "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" ) @@ -11,7 +12,7 @@ import ( // by the cli. // It will mutate the specified user configuration (userConf) with the image // configuration where the user configuration is incomplete. -func Merge(userConf, imageConf *Config) error { +func Merge(userConf, imageConf *container.Config) error { if userConf.User == "" { userConf.User = imageConf.User } diff --git a/runconfig/merge_test.go b/runconfig/merge_test.go index fe2022de80..2499dbb252 100644 --- a/runconfig/merge_test.go +++ b/runconfig/merge_test.go @@ -3,6 +3,7 @@ package runconfig import ( "testing" + "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" ) @@ -13,7 +14,7 @@ func TestMerge(t *testing.T) { portsImage := make(nat.PortSet) portsImage[newPortNoError("tcp", "1111")] = struct{}{} portsImage[newPortNoError("tcp", "2222")] = struct{}{} - configImage := &Config{ + configImage := &container.Config{ ExposedPorts: portsImage, Env: []string{"VAR1=1", "VAR2=2"}, Volumes: volumesImage, @@ -24,7 +25,7 @@ func TestMerge(t *testing.T) { portsUser[newPortNoError("tcp", "3333")] = struct{}{} volumesUser := make(map[string]struct{}) volumesUser["/test3"] = struct{}{} - configUser := &Config{ + configUser := &container.Config{ ExposedPorts: portsUser, Env: []string{"VAR2=3", "VAR3=3"}, Volumes: volumesUser, @@ -64,7 +65,7 @@ func TestMerge(t *testing.T) { if err != nil { t.Error(err) } - configImage2 := &Config{ + configImage2 := &container.Config{ ExposedPorts: ports, } diff --git a/runconfig/parse.go b/runconfig/parse.go index 4d7927f105..6c7060d543 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" @@ -47,7 +48,7 @@ var ( // Parse parses the specified args for the specified command and generates a Config, // a HostConfig and returns them with the specified command. // If the specified args are not valid, it will return an error. -func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) { +func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.HostConfig, *flag.FlagSet, error) { var ( // FIXME: use utils.ListOpts for attach and volumes? flAttach = opts.NewListOpts(opts.ValidateAttach) @@ -300,7 +301,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe } // parse device mappings - deviceMappings := []DeviceMapping{} + deviceMappings := []container.DeviceMapping{} for _, device := range flDevices.GetAll() { deviceMapping, err := ParseDevice(device) if err != nil { @@ -321,17 +322,17 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe return nil, nil, cmd, err } - ipcMode := IpcMode(*flIpcMode) + ipcMode := container.IpcMode(*flIpcMode) if !ipcMode.Valid() { return nil, nil, cmd, fmt.Errorf("--ipc: invalid IPC mode") } - pidMode := PidMode(*flPidMode) + pidMode := container.PidMode(*flPidMode) if !pidMode.Valid() { return nil, nil, cmd, fmt.Errorf("--pid: invalid PID mode") } - utsMode := UTSMode(*flUTSMode) + utsMode := container.UTSMode(*flUTSMode) if !utsMode.Valid() { return nil, nil, cmd, fmt.Errorf("--uts: invalid UTS mode") } @@ -346,7 +347,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe return nil, nil, cmd, err } - resources := Resources{ + resources := container.Resources{ CgroupParent: *flCgroupParent, Memory: flMemory, MemoryReservation: MemoryReservation, @@ -369,7 +370,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe Devices: deviceMappings, } - config := &Config{ + config := &container.Config{ Hostname: hostname, Domainname: domainname, ExposedPorts: ports, @@ -394,7 +395,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe StopSignal: *flStopSignal, } - hostConfig := &HostConfig{ + hostConfig := &container.HostConfig{ Binds: binds, ContainerIDFile: *flContainerIDFile, OomScoreAdj: *flOomScoreAdj, @@ -412,7 +413,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe DNSOptions: flDNSOptions.GetAllOrEmpty(), ExtraHosts: flExtraHosts.GetAll(), VolumesFrom: flVolumesFrom.GetAll(), - NetworkMode: NetworkMode(*flNetMode), + NetworkMode: container.NetworkMode(*flNetMode), IpcMode: ipcMode, PidMode: pidMode, UTSMode: utsMode, @@ -422,9 +423,9 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe RestartPolicy: restartPolicy, SecurityOpt: flSecurityOpt.GetAll(), ReadonlyRootfs: *flReadonlyRootfs, - LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts}, + LogConfig: container.LogConfig{Type: *flLoggingDriver, Config: loggingOpts}, VolumeDriver: *flVolumeDriver, - Isolation: IsolationLevel(*flIsolation), + Isolation: container.IsolationLevel(*flIsolation), ShmSize: parsedShm, Resources: resources, Tmpfs: tmpfs, @@ -477,8 +478,8 @@ func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]st } // ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect -func ParseRestartPolicy(policy string) (RestartPolicy, error) { - p := RestartPolicy{} +func ParseRestartPolicy(policy string) (container.RestartPolicy, error) { + p := container.RestartPolicy{} if policy == "" { return p, nil @@ -516,20 +517,8 @@ func ParseRestartPolicy(policy string) (RestartPolicy, error) { return p, nil } -func parseKeyValueOpts(opts opts.ListOpts) ([]KeyValuePair, error) { - out := make([]KeyValuePair, opts.Len()) - for i, o := range opts.GetAll() { - k, v, err := parsers.ParseKeyValueOpt(o) - if err != nil { - return nil, err - } - out[i] = KeyValuePair{Key: k, Value: v} - } - return out, nil -} - -// ParseDevice parses a device mapping string to a DeviceMapping struct -func ParseDevice(device string) (DeviceMapping, error) { +// ParseDevice parses a device mapping string to a container.DeviceMapping struct +func ParseDevice(device string) (container.DeviceMapping, error) { src := "" dst := "" permissions := "rwm" @@ -548,14 +537,14 @@ func ParseDevice(device string) (DeviceMapping, error) { case 1: src = arr[0] default: - return DeviceMapping{}, fmt.Errorf("Invalid device specification: %s", device) + return container.DeviceMapping{}, fmt.Errorf("Invalid device specification: %s", device) } if dst == "" { dst = src } - deviceMapping := DeviceMapping{ + deviceMapping := container.DeviceMapping{ PathOnHost: src, PathInContainer: dst, CgroupPermissions: permissions, diff --git a/runconfig/parse_test.go b/runconfig/parse_test.go index 437d1393b9..7c48abe603 100644 --- a/runconfig/parse_test.go +++ b/runconfig/parse_test.go @@ -10,23 +10,24 @@ import ( "strings" "testing" + "github.com/docker/docker/api/types/container" flag "github.com/docker/docker/pkg/mflag" "github.com/docker/go-connections/nat" ) -func parseRun(args []string) (*Config, *HostConfig, *flag.FlagSet, error) { +func parseRun(args []string) (*container.Config, *container.HostConfig, *flag.FlagSet, error) { cmd := flag.NewFlagSet("run", flag.ContinueOnError) cmd.SetOutput(ioutil.Discard) cmd.Usage = nil return Parse(cmd, args) } -func parse(t *testing.T, args string) (*Config, *HostConfig, error) { +func parse(t *testing.T, args string) (*container.Config, *container.HostConfig, error) { config, hostConfig, _, err := parseRun(strings.Split(args+" ubuntu bash", " ")) return config, hostConfig, err } -func mustParse(t *testing.T, args string) (*Config, *HostConfig) { +func mustParse(t *testing.T, args string) (*container.Config, *container.HostConfig) { config, hostConfig, err := parse(t, args) if err != nil { t.Fatal(err) @@ -280,18 +281,18 @@ func TestDecodeContainerConfigVolumes(t *testing.T) { // passed into it. It returns a config and a hostconfig which can be // validated to ensure DecodeContainerConfig has manipulated the structures // correctly. -func callDecodeContainerConfig(volumes []string, binds []string) (*Config, *HostConfig, error) { +func callDecodeContainerConfig(volumes []string, binds []string) (*container.Config, *container.HostConfig, error) { var ( b []byte err error - c *Config - h *HostConfig + c *container.Config + h *container.HostConfig ) w := ContainerConfigWrapper{ - Config: &Config{ + Config: &container.Config{ Volumes: map[string]struct{}{}, }, - HostConfig: &HostConfig{ + HostConfig: &container.HostConfig{ NetworkMode: "none", Binds: binds, }, @@ -450,7 +451,7 @@ func TestParseWithExpose(t *testing.T) { } func TestParseDevice(t *testing.T) { - valids := map[string]DeviceMapping{ + valids := map[string]container.DeviceMapping{ "/dev/snd": { PathOnHost: "/dev/snd", PathInContainer: "/dev/snd", @@ -546,7 +547,7 @@ func TestParseRestartPolicy(t *testing.T) { "on-failure:invalid": `strconv.ParseInt: parsing "invalid": invalid syntax`, "on-failure:2:5": "restart count format is not valid, usage: 'on-failure:N' or 'on-failure'", } - valids := map[string]RestartPolicy{ + valids := map[string]container.RestartPolicy{ "": {}, "always": { Name: "always",