Merge pull request #18762 from calavera/runconfig_to_types

Move container configuration types to api/types/container.
This commit is contained in:
Alexander Morozov 2015-12-22 14:22:08 -08:00
commit 030347c3c9
107 changed files with 1971 additions and 802 deletions

View file

@ -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,10 +19,10 @@ 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 runconfig.ExecConfig) (types.HijackedResponse, error)
ContainerExecCreate(config runconfig.ExecConfig) (types.ContainerExecCreateResponse, error)
ContainerExecAttach(execID string, config types.ExecConfig) (types.HijackedResponse, error)
ContainerExecCreate(config types.ExecConfig) (types.ContainerExecCreateResponse, error)
ContainerExecInspect(execID string) (types.ContainerExecInspect, error)
ContainerExecResize(options types.ResizeOptions) error
ContainerExecStart(execID string, config types.ExecStartCheck) error

View file

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

View file

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

View file

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

View file

@ -4,11 +4,10 @@ import (
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/docker/docker/runconfig"
)
// ContainerExecCreate creates a new exec configuration to run an exec process.
func (cli *Client) ContainerExecCreate(config runconfig.ExecConfig) (types.ContainerExecCreateResponse, error) {
func (cli *Client) ContainerExecCreate(config types.ExecConfig) (types.ContainerExecCreateResponse, error) {
var response types.ContainerExecCreateResponse
resp, err := cli.post("/containers/"+config.Container+"/exec", nil, config, nil)
if err != nil {
@ -30,7 +29,7 @@ func (cli *Client) ContainerExecStart(execID string, config types.ExecStartCheck
// It returns a types.HijackedConnection with the hijacked connection
// and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close.
func (cli *Client) ContainerExecAttach(execID string, config runconfig.ExecConfig) (types.HijackedResponse, error) {
func (cli *Client) ContainerExecAttach(execID string, config types.ExecConfig) (types.HijackedResponse, error) {
headers := map[string][]string{"Content-Type": {"application/json"}}
return cli.postHijacked("/exec/"+execID+"/start", nil, config, headers)
}

View file

@ -7,9 +7,10 @@ import (
"net/url"
"regexp"
"strconv"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-units"
)
@ -72,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)
}
@ -101,7 +102,7 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro
}
query.Set("ulimits", string(ulimitsJSON))
buildArgs := runconfig.ConvertKVStringsToMap(options.BuildArgs)
buildArgs := convertKVStringsToMap(options.BuildArgs)
buildArgsJSON, err := json.Marshal(buildArgs)
if err != nil {
return query, err
@ -119,3 +120,18 @@ func getDockerOS(serverHeader string) string {
}
return osType
}
// convertKVStringsToMap converts ["key=value"] to {"key":"value"}
func convertKVStringsToMap(values []string) map[string]string {
result := make(map[string]string, len(values))
for _, value := range values {
kv := strings.SplitN(value, "=", 2)
if len(kv) == 1 {
result[kv[0]] = ""
} else {
result[kv[0]] = kv[1]
}
}
return result
}

View file

@ -6,7 +6,7 @@ import (
Cli "github.com/docker/docker/cli"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/nat"
"github.com/docker/go-connections/nat"
)
// CmdPort lists port mappings for a container.

View file

@ -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

View file

@ -5,16 +5,16 @@ 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.
type execBackend interface {
ContainerExecCreate(config *runconfig.ExecConfig) (string, error)
ContainerExecCreate(config *types.ExecConfig) (string, error)
ContainerExecInspect(id string) (*exec.Config, error)
ContainerExecResize(name string, height, width int) error
ContainerExecStart(name string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error
@ -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)

View file

@ -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

View file

@ -11,7 +11,6 @@ import (
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/runconfig"
"golang.org/x/net/context"
)
@ -33,7 +32,7 @@ func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.Re
}
name := vars["name"]
execConfig := &runconfig.ExecConfig{}
execConfig := &types.ExecConfig{}
if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil {
return err
}

View file

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

View file

@ -1,8 +1,6 @@
package blkiodev
import (
"fmt"
)
import "fmt"
// WeightDevice is a structure that hold device:weight pair
type WeightDevice struct {

View file

@ -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.

View file

@ -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,5 +31,19 @@ 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
// for the exec feature of docker.
type ExecConfig struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
Container string // Name of the container (to execute in)
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard output
AttachStdout bool // Attach the standard error
Detach bool // Execute in detach mode
Cmd []string // Execution commands and args
}

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,4 @@
package stringutils
package strslice
import (
"encoding/json"
@ -65,7 +65,7 @@ func (e *StrSlice) ToString() string {
return strings.Join(s, " ")
}
// NewStrSlice creates an StrSlice based on the specified parts (as strings).
func NewStrSlice(parts ...string) *StrSlice {
// New creates an StrSlice based on the specified parts (as strings).
func New(parts ...string) *StrSlice {
return &StrSlice{parts}
}

View file

@ -1,4 +1,4 @@
package stringutils
package strslice
import (
"encoding/json"
@ -93,9 +93,9 @@ func TestStrSliceUnmarshalSlice(t *testing.T) {
func TestStrSliceToString(t *testing.T) {
slices := map[*StrSlice]string{
NewStrSlice(""): "",
NewStrSlice("one"): "one",
NewStrSlice("one", "two"): "one two",
New(""): "",
New("one"): "one",
New("one", "two"): "one two",
}
for s, expected := range slices {
toString := s.ToString()
@ -108,10 +108,10 @@ func TestStrSliceToString(t *testing.T) {
func TestStrSliceLen(t *testing.T) {
var emptyStrSlice *StrSlice
slices := map[*StrSlice]int{
NewStrSlice(""): 1,
NewStrSlice("one"): 1,
NewStrSlice("one", "two"): 2,
emptyStrSlice: 0,
New(""): 1,
New("one"): 1,
New("one", "two"): 2,
emptyStrSlice: 0,
}
for s, expected := range slices {
if s.Len() != expected {
@ -123,9 +123,9 @@ func TestStrSliceLen(t *testing.T) {
func TestStrSliceSlice(t *testing.T) {
var emptyStrSlice *StrSlice
slices := map[*StrSlice][]string{
NewStrSlice("one"): {"one"},
NewStrSlice("one", "two"): {"one", "two"},
emptyStrSlice: nil,
New("one"): {"one"},
New("one", "two"): {"one", "two"},
emptyStrSlice: nil,
}
for s, expected := range slices {
if !reflect.DeepEqual(s.Slice(), expected) {

View file

@ -4,11 +4,11 @@ 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/nat"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/nat"
)
// ContainerCreateResponse contains the information returned to a client on the
@ -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
}

View file

@ -3,9 +3,9 @@ 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/pkg/nat"
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/nat"
)
// ContainerJSON is a backcompatibility struct for APIs prior to 1.20.
@ -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

View file

@ -3,8 +3,8 @@ package v1p20
import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
)
// ContainerJSON is a backcompatibility struct for the API 1.20
@ -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

View file

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

View file

@ -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

View file

@ -18,14 +18,14 @@ import (
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/builder"
derr "github.com/docker/docker/errors"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/nat"
)
const (
@ -330,7 +330,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
// stash the config environment
env := b.runConfig.Env
defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
defer func(env []string) { b.runConfig.Env = env }(env)
// derive the net build-time environment for this run. We let config
@ -373,7 +373,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
if len(cmdBuildEnv) > 0 {
sort.Strings(cmdBuildEnv)
tmpEnv := append([]string{fmt.Sprintf("|%d", len(cmdBuildEnv))}, cmdBuildEnv...)
saveCmd = stringutils.NewStrSlice(append(tmpEnv, saveCmd.Slice()...)...)
saveCmd = strslice.New(append(tmpEnv, saveCmd.Slice()...)...)
}
b.runConfig.Cmd = saveCmd
@ -431,7 +431,7 @@ func cmd(b *Builder, args []string, attributes map[string]bool, original string)
}
}
b.runConfig.Cmd = stringutils.NewStrSlice(cmdSlice...)
b.runConfig.Cmd = strslice.New(cmdSlice...)
if err := b.commit("", b.runConfig.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
return err
@ -462,16 +462,16 @@ func entrypoint(b *Builder, args []string, attributes map[string]bool, original
switch {
case attributes["json"]:
// ENTRYPOINT ["echo", "hi"]
b.runConfig.Entrypoint = stringutils.NewStrSlice(parsed...)
b.runConfig.Entrypoint = strslice.New(parsed...)
case len(parsed) == 0:
// ENTRYPOINT []
b.runConfig.Entrypoint = nil
default:
// ENTRYPOINT echo hi
if runtime.GOOS != "windows" {
b.runConfig.Entrypoint = stringutils.NewStrSlice("/bin/sh", "-c", parsed[0])
b.runConfig.Entrypoint = strslice.New("/bin/sh", "-c", parsed[0])
} else {
b.runConfig.Entrypoint = stringutils.NewStrSlice("cmd", "/S", "/C", parsed[0])
b.runConfig.Entrypoint = strslice.New("cmd", "/S", "/C", parsed[0])
}
}

View file

@ -21,6 +21,8 @@ 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"
"github.com/docker/docker/pkg/archive"
@ -30,14 +32,12 @@ import (
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/stringutils"
"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 *stringutils.StrSlice, comment string) error {
func (b *Builder) commit(id string, autoCmd *strslice.StrSlice, comment string) error {
if b.disableCommit {
return nil
}
@ -48,11 +48,11 @@ func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin
if id == "" {
cmd := b.runConfig.Cmd
if runtime.GOOS != "windows" {
b.runConfig.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", "#(nop) "+comment)
b.runConfig.Cmd = strslice.New("/bin/sh", "-c", "#(nop) "+comment)
} else {
b.runConfig.Cmd = stringutils.NewStrSlice("cmd", "/S /C", "REM (nop) "+comment)
b.runConfig.Cmd = strslice.New("cmd", "/S /C", "REM (nop) "+comment)
}
defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
hit, err := b.probeCache()
if err != nil {
@ -171,11 +171,11 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD
cmd := b.runConfig.Cmd
if runtime.GOOS != "windows" {
b.runConfig.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
b.runConfig.Cmd = strslice.New("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
} else {
b.runConfig.Cmd = stringutils.NewStrSlice("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
b.runConfig.Cmd = strslice.New("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
}
defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
if hit, err := b.probeCache(); err != nil {
return err
@ -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,

View file

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

View file

@ -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"
@ -19,12 +20,12 @@ import (
derr "github.com/docker/docker/errors"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/docker/go-connections/nat"
"github.com/opencontainers/runc/libcontainer/label"
)
@ -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)

View file

@ -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()

View file

@ -17,11 +17,11 @@ import (
"github.com/docker/docker/daemon/execdriver"
derr "github.com/docker/docker/errors"
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/utils"
"github.com/docker/docker/volume"
"github.com/docker/go-connections/nat"
"github.com/docker/libnetwork"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"

View file

@ -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,

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

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

View file

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

View file

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

View file

@ -21,8 +21,10 @@ 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"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/events"
"github.com/docker/docker/daemon/exec"
@ -48,12 +50,10 @@ import (
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/namesgenerator"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/pkg/sysinfo"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/truncindex"
@ -64,6 +64,7 @@ import (
volumedrivers "github.com/docker/docker/volume/drivers"
"github.com/docker/docker/volume/local"
"github.com/docker/docker/volume/store"
"github.com/docker/go-connections/nat"
"github.com/docker/libnetwork"
lntypes "github.com/docker/libnetwork/types"
"github.com/docker/libtrust"
@ -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,14 +473,14 @@ 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]
}
}
func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *stringutils.StrSlice, configCmd *stringutils.StrSlice) (string, []string) {
func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *strslice.StrSlice, configCmd *strslice.StrSlice) (string, []string) {
cmdSlice := configCmd.Slice()
if configEntrypoint.Len() != 0 {
eSlice := configEntrypoint.Slice()
@ -488,7 +489,7 @@ func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *stringutils.StrSlic
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 {

View file

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

View file

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

View file

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

23
daemon/daemon_unix.go Executable file → Normal file
View file

@ -12,12 +12,13 @@ import (
"syscall"
"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"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
pblkiodev "github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/sysinfo"
@ -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
}

View file

@ -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 {

View file

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

View file

@ -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

View file

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

View file

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

View file

@ -6,14 +6,14 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/exec"
"github.com/docker/docker/daemon/execdriver"
derr "github.com/docker/docker/errors"
"github.com/docker/docker/pkg/pools"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/runconfig"
)
func (d *Daemon) registerExecCommand(container *container.Container, config *exec.Config) {
@ -79,14 +79,14 @@ func (d *Daemon) getActiveContainer(name string) (*container.Container, error) {
}
// ContainerExecCreate sets up an exec in a running container.
func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
func (d *Daemon) ContainerExecCreate(config *types.ExecConfig) (string, error) {
container, err := d.getActiveContainer(config.Container)
if err != nil {
return "", err
}
cmd := stringutils.NewStrSlice(config.Cmd...)
entrypoint, args := d.getEntrypointAndArgs(stringutils.NewStrSlice(), cmd)
cmd := strslice.New(config.Cmd...)
entrypoint, args := d.getEntrypointAndArgs(strslice.New(), cmd)
processConfig := &execdriver.ProcessConfig{
CommonProcessConfig: execdriver.CommonProcessConfig{

View file

@ -3,14 +3,14 @@
package daemon
import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/runconfig"
)
// setPlatformSpecificExecProcessConfig sets platform-specific fields in the
// ProcessConfig structure.
func setPlatformSpecificExecProcessConfig(config *runconfig.ExecConfig, container *container.Container, pc *execdriver.ProcessConfig) {
func setPlatformSpecificExecProcessConfig(config *types.ExecConfig, container *container.Container, pc *execdriver.ProcessConfig) {
user := config.User
if len(user) == 0 {
user = container.Config.User

View file

@ -1,12 +1,12 @@
package daemon
import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/runconfig"
)
// setPlatformSpecificExecProcessConfig sets platform-specific fields in the
// ProcessConfig structure. This is a no-op on Windows
func setPlatformSpecificExecProcessConfig(config *runconfig.ExecConfig, container *container.Container, pc *execdriver.ProcessConfig) {
func setPlatformSpecificExecProcessConfig(config *types.ExecConfig, container *container.Container, pc *execdriver.ProcessConfig) {
}

View file

@ -1,9 +1,6 @@
package execdriver
import (
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/runconfig"
)
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.

View file

@ -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,
}
}

View file

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

View file

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

View file

@ -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

View file

@ -5,7 +5,7 @@ import (
"path"
"strings"
"github.com/docker/docker/pkg/nat"
"github.com/docker/go-connections/nat"
)
// Link struct holds informations about parent/child linked container

View file

@ -5,7 +5,7 @@ import (
"strings"
"testing"
"github.com/docker/docker/pkg/nat"
"github.com/docker/go-connections/nat"
)
// Just to make life easier

View file

@ -12,7 +12,7 @@ import (
"github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/graphdb"
"github.com/docker/docker/pkg/nat"
"github.com/docker/go-connections/nat"
)
// iterationAction represents possible outcomes happening during the container iteration.

View file

@ -2,7 +2,7 @@ package network
import (
networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/docker/pkg/nat"
"github.com/docker/go-connections/nat"
)
// Settings stores configuration details about the daemon network config

View file

@ -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

View file

@ -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{}

View file

@ -21,6 +21,7 @@ clone git github.com/tchap/go-patricia v2.1.0
clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b
clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://github.com/golang/net.git
clone git github.com/docker/go-units v0.2.0
clone git github.com/docker/go-connections 96cdf8190a45946d0f19576732e2a410c6f84a31
#get libnetwork packages
clone git github.com/docker/libnetwork bbd6e6d8ca1e7c9b42f6f53277b0bde72847ff90

View file

@ -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

View file

@ -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) {

View file

@ -13,8 +13,8 @@ import (
"io/ioutil"
"github.com/docker/docker/pkg/integration/checker"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-connections/nat"
"github.com/go-check/check"
)

View file

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

View file

@ -20,8 +20,8 @@ import (
"github.com/docker/docker/pkg/integration/checker"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/nat"
"github.com/docker/libnetwork/resolvconf"
"github.com/go-check/check"
)

View file

@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/api/types/blkiodev"
"github.com/docker/go-units"
)

View file

@ -3,7 +3,7 @@ package opts
import (
"fmt"
"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/api/types/blkiodev"
)
// ThrottledeviceOpt defines a map of ThrottleDevices

View file

@ -3,7 +3,7 @@ package opts
import (
"fmt"
"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/api/types/blkiodev"
)
// WeightdeviceOpt defines a map of WeightDevices

View file

@ -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

View file

@ -3,8 +3,9 @@ package runconfig
import (
"testing"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/go-connections/nat"
)
// Just to make life easier
@ -33,21 +34,21 @@ func TestCompare(t *testing.T) {
volumes3["/test3"] = struct{}{}
envs1 := []string{"ENV1=value1", "ENV2=value2"}
envs2 := []string{"ENV1=value1", "ENV3=value3"}
entrypoint1 := stringutils.NewStrSlice("/bin/sh", "-c")
entrypoint2 := stringutils.NewStrSlice("/bin/sh", "-d")
entrypoint3 := stringutils.NewStrSlice("/bin/sh", "-c", "echo")
cmd1 := stringutils.NewStrSlice("/bin/sh", "-c")
cmd2 := stringutils.NewStrSlice("/bin/sh", "-d")
cmd3 := stringutils.NewStrSlice("/bin/sh", "-c", "echo")
entrypoint1 := strslice.New("/bin/sh", "-c")
entrypoint2 := strslice.New("/bin/sh", "-d")
entrypoint3 := strslice.New("/bin/sh", "-c", "echo")
cmd1 := strslice.New("/bin/sh", "-c")
cmd2 := strslice.New("/bin/sh", "-d")
cmd3 := strslice.New("/bin/sh", "-c", "echo")
labels1 := map[string]string{"LABEL1": "value1", "LABEL2": "value2"}
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) {

View file

@ -5,48 +5,15 @@ import (
"fmt"
"io"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/volume"
)
// 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 *stringutils.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 *stringutils.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 {

View file

@ -9,12 +9,13 @@ import (
"strings"
"testing"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/strslice"
)
type f struct {
file string
entrypoint *stringutils.StrSlice
entrypoint *strslice.StrSlice
}
func TestDecodeContainerConfig(t *testing.T) {
@ -27,14 +28,14 @@ func TestDecodeContainerConfig(t *testing.T) {
if runtime.GOOS != "windows" {
image = "ubuntu"
fixtures = []f{
{"fixtures/unix/container_config_1_14.json", stringutils.NewStrSlice()},
{"fixtures/unix/container_config_1_17.json", stringutils.NewStrSlice("bash")},
{"fixtures/unix/container_config_1_19.json", stringutils.NewStrSlice("bash")},
{"fixtures/unix/container_config_1_14.json", strslice.New()},
{"fixtures/unix/container_config_1_17.json", strslice.New("bash")},
{"fixtures/unix/container_config_1_19.json", strslice.New("bash")},
}
} else {
image = "windows"
fixtures = []f{
{"fixtures/windows/container_config_1_19.json", stringutils.NewStrSlice("cmd")},
{"fixtures/windows/container_config_1_19.json", strslice.New("cmd")},
}
}
@ -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())

View file

@ -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 {

View file

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

View file

@ -1,28 +1,15 @@
package runconfig
import (
"github.com/docker/docker/api/types"
flag "github.com/docker/docker/pkg/mflag"
)
// ExecConfig is a small subset of the Config struct that hold the configuration
// for the exec feature of docker.
type ExecConfig struct {
User string // User that will run the command
Privileged bool // Is the container in privileged mode
Tty bool // Attach standard streams to a tty.
Container string // Name of the container (to execute in)
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStderr bool // Attach the standard output
AttachStdout bool // Attach the standard error
Detach bool // Execute in detach mode
Cmd []string // Execution commands and args
}
// ParseExec parses the specified args for the specified command and generates
// an ExecConfig from it.
// If the minimal number of specified args is not right or if specified args are
// not valid, it will return an error.
func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
func ParseExec(cmd *flag.FlagSet, args []string) (*types.ExecConfig, error) {
var (
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
@ -40,7 +27,7 @@ func ParseExec(cmd *flag.FlagSet, args []string) (*ExecConfig, error) {
parsedArgs := cmd.Args()
execCmd = parsedArgs[1:]
execConfig := &ExecConfig{
execConfig := &types.ExecConfig{
User: *flUser,
Privileged: *flPrivileged,
Tty: *flTty,

View file

@ -5,6 +5,7 @@ import (
"io/ioutil"
"testing"
"github.com/docker/docker/api/types"
flag "github.com/docker/docker/pkg/mflag"
)
@ -18,7 +19,7 @@ func TestParseExec(t *testing.T) {
&arguments{[]string{"-u"}}: fmt.Errorf("flag needs an argument: -u"),
&arguments{[]string{"--user"}}: fmt.Errorf("flag needs an argument: --user"),
}
valids := map[*arguments]*ExecConfig{
valids := map[*arguments]*types.ExecConfig{
&arguments{
[]string{"container", "command"},
}: {
@ -92,7 +93,7 @@ func TestParseExec(t *testing.T) {
}
}
func compareExecConfig(config1 *ExecConfig, config2 *ExecConfig) bool {
func compareExecConfig(config1 *types.ExecConfig, config2 *types.ExecConfig) bool {
if config1.AttachStderr != config2.AttachStderr {
return false
}

View file

@ -3,240 +3,13 @@ package runconfig
import (
"encoding/json"
"io"
"strings"
"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/pkg/ulimit"
"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 *stringutils.StrSlice // List of kernel capabilities to add to the container
CapDrop *stringutils.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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -3,7 +3,8 @@ package runconfig
import (
"strings"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
)
// Merge merges two Config, the image container configuration (defaults values),
@ -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
}

View file

@ -3,7 +3,8 @@ package runconfig
import (
"testing"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
)
func TestMerge(t *testing.T) {
@ -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,
}

View file

@ -6,14 +6,15 @@ 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"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/volume"
"github.com/docker/go-connections/nat"
"github.com/docker/go-units"
)
@ -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)
@ -249,15 +250,15 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
var (
parsedArgs = cmd.Args()
runCmd *stringutils.StrSlice
entrypoint *stringutils.StrSlice
runCmd *strslice.StrSlice
entrypoint *strslice.StrSlice
image = cmd.Arg(0)
)
if len(parsedArgs) > 1 {
runCmd = stringutils.NewStrSlice(parsedArgs[1:]...)
runCmd = strslice.New(parsedArgs[1:]...)
}
if *flEntrypoint != "" {
entrypoint = stringutils.NewStrSlice(*flEntrypoint)
entrypoint = strslice.New(*flEntrypoint)
}
var (
@ -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,19 +413,19 @@ 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,
CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...),
CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...),
CapAdd: strslice.New(flCapAdd.GetAll()...),
CapDrop: strslice.New(flCapDrop.GetAll()...),
GroupAdd: flGroupAdd.GetAll(),
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,

View file

@ -10,23 +10,24 @@ import (
"strings"
"testing"
"github.com/docker/docker/api/types/container"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/nat"
"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",

View file

@ -0,0 +1,55 @@
# Contributing to Docker
### Sign your work
The sign-off is a simple line at the end of the explanation for the patch. Your
signature certifies that you wrote the patch or otherwise have the right to pass
it on as an open-source patch. The rules are pretty simple: if you can certify
the below (from [developercertificate.org](http://developercertificate.org/)):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
Then you just add a line to every git commit message:
Signed-off-by: Joe Smith <joe.smith@email.com>
Use your real name (sorry, no pseudonyms or anonymous contributions.)
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`.

View file

@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2015 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,27 @@
# go-connections maintainers file
#
# This file describes who runs the docker/go-connections project and how.
# This is a living document - if you see something out of date or missing, speak up!
#
# It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant parser.
#
# This file is compiled into the MAINTAINERS file in docker/opensource.
#
[Org]
[Org."Core maintainers"]
people = [
"calavera",
]
[people]
# A reference list of all people associated with the project.
# All other sections should refer to people by their canonical key
# in the people section.
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
[people.calavera]
Name = "David Calavera"
Email = "david.calavera@gmail.com"
GitHub = "calavera"

View file

@ -0,0 +1,13 @@
[![GoDoc](https://godoc.org/github.com/docker/go-connections?status.svg)](https://godoc.org/github.com/docker/go-connections)
# Introduction
go-connections provides common package to work with network connections.
## Usage
See the [docs in godoc](https://godoc.org/github.com/docker/go-connections) for examples and documentation.
## License
go-connections is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.

View file

@ -0,0 +1,14 @@
dependencies:
pre:
# setup ipv6
- sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0 net.ipv6.conf.default.disable_ipv6=0 net.ipv6.conf.all.disable_ipv6=0
post:
# install golint
- go get github.com/golang/lint/golint
test:
pre:
# run analysis before tests
- go vet ./...
- test -z "$(golint ./... | tee /dev/stderr)"
- test -z "$(gofmt -s -l . | tee /dev/stderr)"

View file

@ -0,0 +1,3 @@
// Package connections provides libraries to work with network connections.
// This library is divided in several components for specific usage.
package connections

View file

@ -1,8 +1,6 @@
// Package nat is a convenience package for manipulation of strings describing network ports.
package nat
// nat is a convenience package for docker's manipulation of strings describing
// network ports.
import (
"fmt"
"net"

View file

@ -0,0 +1,216 @@
package proxy
import (
"bytes"
"fmt"
"io"
"net"
"strings"
"testing"
"time"
)
var testBuf = []byte("Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo")
var testBufSize = len(testBuf)
type EchoServer interface {
Run()
Close()
LocalAddr() net.Addr
}
type TCPEchoServer struct {
listener net.Listener
testCtx *testing.T
}
type UDPEchoServer struct {
conn net.PacketConn
testCtx *testing.T
}
func NewEchoServer(t *testing.T, proto, address string) EchoServer {
var server EchoServer
if strings.HasPrefix(proto, "tcp") {
listener, err := net.Listen(proto, address)
if err != nil {
t.Fatal(err)
}
server = &TCPEchoServer{listener: listener, testCtx: t}
} else {
socket, err := net.ListenPacket(proto, address)
if err != nil {
t.Fatal(err)
}
server = &UDPEchoServer{conn: socket, testCtx: t}
}
return server
}
func (server *TCPEchoServer) Run() {
go func() {
for {
client, err := server.listener.Accept()
if err != nil {
return
}
go func(client net.Conn) {
if _, err := io.Copy(client, client); err != nil {
server.testCtx.Logf("can't echo to the client: %v\n", err.Error())
}
client.Close()
}(client)
}
}()
}
func (server *TCPEchoServer) LocalAddr() net.Addr { return server.listener.Addr() }
func (server *TCPEchoServer) Close() { server.listener.Addr() }
func (server *UDPEchoServer) Run() {
go func() {
readBuf := make([]byte, 1024)
for {
read, from, err := server.conn.ReadFrom(readBuf)
if err != nil {
return
}
for i := 0; i != read; {
written, err := server.conn.WriteTo(readBuf[i:read], from)
if err != nil {
break
}
i += written
}
}
}()
}
func (server *UDPEchoServer) LocalAddr() net.Addr { return server.conn.LocalAddr() }
func (server *UDPEchoServer) Close() { server.conn.Close() }
func testProxyAt(t *testing.T, proto string, proxy Proxy, addr string) {
defer proxy.Close()
go proxy.Run()
client, err := net.Dial(proto, addr)
if err != nil {
t.Fatalf("Can't connect to the proxy: %v", err)
}
defer client.Close()
client.SetDeadline(time.Now().Add(10 * time.Second))
if _, err = client.Write(testBuf); err != nil {
t.Fatal(err)
}
recvBuf := make([]byte, testBufSize)
if _, err = client.Read(recvBuf); err != nil {
t.Fatal(err)
}
if !bytes.Equal(testBuf, recvBuf) {
t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf))
}
}
func testProxy(t *testing.T, proto string, proxy Proxy) {
testProxyAt(t, proto, proxy, proxy.FrontendAddr().String())
}
func TestTCP4Proxy(t *testing.T) {
backend := NewEchoServer(t, "tcp", "127.0.0.1:0")
defer backend.Close()
backend.Run()
frontendAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
if err != nil {
t.Fatal(err)
}
testProxy(t, "tcp", proxy)
}
func TestTCP6Proxy(t *testing.T) {
backend := NewEchoServer(t, "tcp", "[::1]:0")
defer backend.Close()
backend.Run()
frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0}
proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
if err != nil {
t.Fatal(err)
}
testProxy(t, "tcp", proxy)
}
func TestTCPDualStackProxy(t *testing.T) {
// If I understand `godoc -src net favoriteAddrFamily` (used by the
// net.Listen* functions) correctly this should work, but it doesn't.
t.Skip("No support for dual stack yet")
backend := NewEchoServer(t, "tcp", "[::1]:0")
defer backend.Close()
backend.Run()
frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0}
proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
if err != nil {
t.Fatal(err)
}
ipv4ProxyAddr := &net.TCPAddr{
IP: net.IPv4(127, 0, 0, 1),
Port: proxy.FrontendAddr().(*net.TCPAddr).Port,
}
testProxyAt(t, "tcp", proxy, ipv4ProxyAddr.String())
}
func TestUDP4Proxy(t *testing.T) {
backend := NewEchoServer(t, "udp", "127.0.0.1:0")
defer backend.Close()
backend.Run()
frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
if err != nil {
t.Fatal(err)
}
testProxy(t, "udp", proxy)
}
func TestUDP6Proxy(t *testing.T) {
backend := NewEchoServer(t, "udp", "[::1]:0")
defer backend.Close()
backend.Run()
frontendAddr := &net.UDPAddr{IP: net.IPv6loopback, Port: 0}
proxy, err := NewProxy(frontendAddr, backend.LocalAddr())
if err != nil {
t.Fatal(err)
}
testProxy(t, "udp", proxy)
}
func TestUDPWriteError(t *testing.T) {
frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}
// Hopefully, this port will be free: */
backendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 25587}
proxy, err := NewProxy(frontendAddr, backendAddr)
if err != nil {
t.Fatal(err)
}
defer proxy.Close()
go proxy.Run()
client, err := net.Dial("udp", "127.0.0.1:25587")
if err != nil {
t.Fatalf("Can't connect to the proxy: %v", err)
}
defer client.Close()
// Make sure the proxy doesn't stop when there is no actual backend:
client.Write(testBuf)
client.Write(testBuf)
backend := NewEchoServer(t, "udp", "127.0.0.1:25587")
defer backend.Close()
backend.Run()
client.SetDeadline(time.Now().Add(10 * time.Second))
if _, err = client.Write(testBuf); err != nil {
t.Fatal(err)
}
recvBuf := make([]byte, testBufSize)
if _, err = client.Read(recvBuf); err != nil {
t.Fatal(err)
}
if !bytes.Equal(testBuf, recvBuf) {
t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf))
}
}

View file

@ -0,0 +1,36 @@
// Package proxy provides a network Proxy interface and implementations for TCP and UDP.
package proxy
import (
"fmt"
"net"
)
// Proxy defines the behavior of a proxy. It forwards traffic back and forth
// between two endpoints : the frontend and the backend.
// It can be used to do software port-mapping between two addresses.
// e.g. forward all traffic between the frontend (host) 127.0.0.1:3000
// to the backend (container) at 172.17.42.108:4000.
type Proxy interface {
// Run starts forwarding traffic back and forth between the front
// and back-end addresses.
Run()
// Close stops forwarding traffic and close both ends of the Proxy.
Close()
// FrontendAddr returns the address on which the proxy is listening.
FrontendAddr() net.Addr
// BackendAddr returns the proxied address.
BackendAddr() net.Addr
}
// NewProxy creates a Proxy according to the specified frontendAddr and backendAddr.
func NewProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
switch frontendAddr.(type) {
case *net.UDPAddr:
return NewUDPProxy(frontendAddr.(*net.UDPAddr), backendAddr.(*net.UDPAddr))
case *net.TCPAddr:
return NewTCPProxy(frontendAddr.(*net.TCPAddr), backendAddr.(*net.TCPAddr))
default:
panic(fmt.Errorf("Unsupported protocol"))
}
}

Some files were not shown because too many files have changed in this diff Show more