Move Config and HostConfig from runconfig to types/container.
- Make the API client library completely standalone. - Move windows partition isolation detection to the client, so the driver doesn't use external types. Signed-off-by: David Calavera <david.calavera@gmail.com> Upstream-commit: 7ac4232e70fe7cf7318333cd0890db7f95663079 Component: engine
This commit is contained in:
@ -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
|
||||
|
||||
@ -3,6 +3,7 @@ package runconfig
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
@ -43,11 +44,11 @@ func TestCompare(t *testing.T) {
|
||||
labels2 := map[string]string{"LABEL1": "value1", "LABEL2": "value3"}
|
||||
labels3 := map[string]string{"LABEL1": "value1", "LABEL2": "value2", "LABEL3": "value3"}
|
||||
|
||||
sameConfigs := map[*Config]*Config{
|
||||
sameConfigs := map[*container.Config]*container.Config{
|
||||
// Empty config
|
||||
&Config{}: {},
|
||||
&container.Config{}: {},
|
||||
// Does not compare hostname, domainname & image
|
||||
&Config{
|
||||
&container.Config{
|
||||
Hostname: "host1",
|
||||
Domainname: "domain1",
|
||||
Image: "image1",
|
||||
@ -59,23 +60,23 @@ func TestCompare(t *testing.T) {
|
||||
User: "user",
|
||||
},
|
||||
// only OpenStdin
|
||||
&Config{OpenStdin: false}: {OpenStdin: false},
|
||||
&container.Config{OpenStdin: false}: {OpenStdin: false},
|
||||
// only env
|
||||
&Config{Env: envs1}: {Env: envs1},
|
||||
&container.Config{Env: envs1}: {Env: envs1},
|
||||
// only cmd
|
||||
&Config{Cmd: cmd1}: {Cmd: cmd1},
|
||||
&container.Config{Cmd: cmd1}: {Cmd: cmd1},
|
||||
// only labels
|
||||
&Config{Labels: labels1}: {Labels: labels1},
|
||||
&container.Config{Labels: labels1}: {Labels: labels1},
|
||||
// only exposedPorts
|
||||
&Config{ExposedPorts: ports1}: {ExposedPorts: ports1},
|
||||
&container.Config{ExposedPorts: ports1}: {ExposedPorts: ports1},
|
||||
// only entrypoints
|
||||
&Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint1},
|
||||
&container.Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint1},
|
||||
// only volumes
|
||||
&Config{Volumes: volumes1}: {Volumes: volumes1},
|
||||
&container.Config{Volumes: volumes1}: {Volumes: volumes1},
|
||||
}
|
||||
differentConfigs := map[*Config]*Config{
|
||||
differentConfigs := map[*container.Config]*container.Config{
|
||||
nil: nil,
|
||||
&Config{
|
||||
&container.Config{
|
||||
Hostname: "host1",
|
||||
Domainname: "domain1",
|
||||
Image: "image1",
|
||||
@ -87,30 +88,30 @@ func TestCompare(t *testing.T) {
|
||||
User: "user2",
|
||||
},
|
||||
// only OpenStdin
|
||||
&Config{OpenStdin: false}: {OpenStdin: true},
|
||||
&Config{OpenStdin: true}: {OpenStdin: false},
|
||||
&container.Config{OpenStdin: false}: {OpenStdin: true},
|
||||
&container.Config{OpenStdin: true}: {OpenStdin: false},
|
||||
// only env
|
||||
&Config{Env: envs1}: {Env: envs2},
|
||||
&container.Config{Env: envs1}: {Env: envs2},
|
||||
// only cmd
|
||||
&Config{Cmd: cmd1}: {Cmd: cmd2},
|
||||
&container.Config{Cmd: cmd1}: {Cmd: cmd2},
|
||||
// not the same number of parts
|
||||
&Config{Cmd: cmd1}: {Cmd: cmd3},
|
||||
&container.Config{Cmd: cmd1}: {Cmd: cmd3},
|
||||
// only labels
|
||||
&Config{Labels: labels1}: {Labels: labels2},
|
||||
&container.Config{Labels: labels1}: {Labels: labels2},
|
||||
// not the same number of labels
|
||||
&Config{Labels: labels1}: {Labels: labels3},
|
||||
&container.Config{Labels: labels1}: {Labels: labels3},
|
||||
// only exposedPorts
|
||||
&Config{ExposedPorts: ports1}: {ExposedPorts: ports2},
|
||||
&container.Config{ExposedPorts: ports1}: {ExposedPorts: ports2},
|
||||
// not the same number of ports
|
||||
&Config{ExposedPorts: ports1}: {ExposedPorts: ports3},
|
||||
&container.Config{ExposedPorts: ports1}: {ExposedPorts: ports3},
|
||||
// only entrypoints
|
||||
&Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint2},
|
||||
&container.Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint2},
|
||||
// not the same number of parts
|
||||
&Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint3},
|
||||
&container.Config{Entrypoint: entrypoint1}: {Entrypoint: entrypoint3},
|
||||
// only volumes
|
||||
&Config{Volumes: volumes1}: {Volumes: volumes2},
|
||||
&container.Config{Volumes: volumes1}: {Volumes: volumes2},
|
||||
// not the same number of labels
|
||||
&Config{Volumes: volumes1}: {Volumes: volumes3},
|
||||
&container.Config{Volumes: volumes1}: {Volumes: volumes3},
|
||||
}
|
||||
for config1, config2 := range sameConfigs {
|
||||
if !Compare(config1, config2) {
|
||||
|
||||
@ -5,48 +5,15 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
// Config contains the configuration data about a container.
|
||||
// It should hold only portable information about the container.
|
||||
// Here, "portable" means "independent from the host we are running on".
|
||||
// Non-portable information *should* appear in HostConfig.
|
||||
// All fields added to this struct must be marked `omitempty` to keep getting
|
||||
// predictable hashes from the old `v1Compatibility` configuration.
|
||||
type Config struct {
|
||||
Hostname string // Hostname
|
||||
Domainname string // Domainname
|
||||
User string // User that will run the command(s) inside the container
|
||||
AttachStdin bool // Attach the standard input, makes possible user interaction
|
||||
AttachStdout bool // Attach the standard output
|
||||
AttachStderr bool // Attach the standard error
|
||||
ExposedPorts map[nat.Port]struct{} `json:",omitempty"` // List of exposed ports
|
||||
PublishService string `json:",omitempty"` // Name of the network service exposed by the container
|
||||
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
|
||||
OpenStdin bool // Open stdin
|
||||
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
||||
Env []string // List of environment variable to set in the container
|
||||
Cmd *strslice.StrSlice // Command to run when starting the container
|
||||
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific)
|
||||
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
|
||||
Volumes map[string]struct{} // List of volumes (mounts) used for the container
|
||||
WorkingDir string // Current directory (PWD) in the command will be launched
|
||||
Entrypoint *strslice.StrSlice // Entrypoint to run when starting the container
|
||||
NetworkDisabled bool `json:",omitempty"` // Is network disabled
|
||||
MacAddress string `json:",omitempty"` // Mac Address of the container
|
||||
OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile
|
||||
Labels map[string]string // List of labels set to this container
|
||||
StopSignal string `json:",omitempty"` // Signal to stop a container
|
||||
}
|
||||
|
||||
// DecodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
|
||||
// struct and returns both a Config and an HostConfig struct
|
||||
// Be aware this function is not checking whether the resulted structs are nil,
|
||||
// it's your business to do so
|
||||
func DecodeContainerConfig(src io.Reader) (*Config, *HostConfig, error) {
|
||||
func DecodeContainerConfig(src io.Reader) (*container.Config, *container.HostConfig, error) {
|
||||
var w ContainerConfigWrapper
|
||||
|
||||
decoder := json.NewDecoder(src)
|
||||
@ -85,7 +52,7 @@ func DecodeContainerConfig(src io.Reader) (*Config, *HostConfig, error) {
|
||||
|
||||
// validateVolumesAndBindSettings validates each of the volumes and bind settings
|
||||
// passed by the caller to ensure they are valid.
|
||||
func validateVolumesAndBindSettings(c *Config, hc *HostConfig) error {
|
||||
func validateVolumesAndBindSettings(c *container.Config, hc *container.HostConfig) error {
|
||||
|
||||
// Ensure all volumes and binds are valid.
|
||||
for spec := range c.Volumes {
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
)
|
||||
|
||||
@ -101,16 +102,16 @@ func TestDecodeContainerConfigIsolation(t *testing.T) {
|
||||
|
||||
// callDecodeContainerConfigIsolation is a utility function to call
|
||||
// DecodeContainerConfig for validating isolation levels
|
||||
func callDecodeContainerConfigIsolation(isolation string) (*Config, *HostConfig, error) {
|
||||
func callDecodeContainerConfigIsolation(isolation string) (*container.Config, *container.HostConfig, error) {
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
)
|
||||
w := ContainerConfigWrapper{
|
||||
Config: &Config{},
|
||||
HostConfig: &HostConfig{
|
||||
Config: &container.Config{},
|
||||
HostConfig: &container.HostConfig{
|
||||
NetworkMode: "none",
|
||||
Isolation: IsolationLevel(isolation)},
|
||||
Isolation: container.IsolationLevel(isolation)},
|
||||
}
|
||||
if b, err = json.Marshal(w); err != nil {
|
||||
return nil, nil, fmt.Errorf("Error on marshal %s", err.Error())
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -3,240 +3,13 @@ package runconfig
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/blkiodev"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/pkg/ulimit"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
)
|
||||
|
||||
// KeyValuePair is a structure that hold a value for a key.
|
||||
type KeyValuePair struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
// NetworkMode represents the container network stack.
|
||||
type NetworkMode string
|
||||
|
||||
// IsolationLevel represents the isolation level of a container. The supported
|
||||
// values are platform specific
|
||||
type IsolationLevel string
|
||||
|
||||
// IsDefault indicates the default isolation level of a container. On Linux this
|
||||
// is the native driver. On Windows, this is a Windows Server Container.
|
||||
func (i IsolationLevel) IsDefault() bool {
|
||||
return strings.ToLower(string(i)) == "default" || string(i) == ""
|
||||
}
|
||||
|
||||
// IpcMode represents the container ipc stack.
|
||||
type IpcMode string
|
||||
|
||||
// IsPrivate indicates whether the container uses it's private ipc stack.
|
||||
func (n IpcMode) IsPrivate() bool {
|
||||
return !(n.IsHost() || n.IsContainer())
|
||||
}
|
||||
|
||||
// IsHost indicates whether the container uses the host's ipc stack.
|
||||
func (n IpcMode) IsHost() bool {
|
||||
return n == "host"
|
||||
}
|
||||
|
||||
// IsContainer indicates whether the container uses a container's ipc stack.
|
||||
func (n IpcMode) IsContainer() bool {
|
||||
parts := strings.SplitN(string(n), ":", 2)
|
||||
return len(parts) > 1 && parts[0] == "container"
|
||||
}
|
||||
|
||||
// Valid indicates whether the ipc stack is valid.
|
||||
func (n IpcMode) Valid() bool {
|
||||
parts := strings.Split(string(n), ":")
|
||||
switch mode := parts[0]; mode {
|
||||
case "", "host":
|
||||
case "container":
|
||||
if len(parts) != 2 || parts[1] == "" {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Container returns the name of the container ipc stack is going to be used.
|
||||
func (n IpcMode) Container() string {
|
||||
parts := strings.SplitN(string(n), ":", 2)
|
||||
if len(parts) > 1 {
|
||||
return parts[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// UTSMode represents the UTS namespace of the container.
|
||||
type UTSMode string
|
||||
|
||||
// IsPrivate indicates whether the container uses it's private UTS namespace.
|
||||
func (n UTSMode) IsPrivate() bool {
|
||||
return !(n.IsHost())
|
||||
}
|
||||
|
||||
// IsHost indicates whether the container uses the host's UTS namespace.
|
||||
func (n UTSMode) IsHost() bool {
|
||||
return n == "host"
|
||||
}
|
||||
|
||||
// Valid indicates whether the UTS namespace is valid.
|
||||
func (n UTSMode) Valid() bool {
|
||||
parts := strings.Split(string(n), ":")
|
||||
switch mode := parts[0]; mode {
|
||||
case "", "host":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PidMode represents the pid stack of the container.
|
||||
type PidMode string
|
||||
|
||||
// IsPrivate indicates whether the container uses it's private pid stack.
|
||||
func (n PidMode) IsPrivate() bool {
|
||||
return !(n.IsHost())
|
||||
}
|
||||
|
||||
// IsHost indicates whether the container uses the host's pid stack.
|
||||
func (n PidMode) IsHost() bool {
|
||||
return n == "host"
|
||||
}
|
||||
|
||||
// Valid indicates whether the pid stack is valid.
|
||||
func (n PidMode) Valid() bool {
|
||||
parts := strings.Split(string(n), ":")
|
||||
switch mode := parts[0]; mode {
|
||||
case "", "host":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// DeviceMapping represents the device mapping between the host and the container.
|
||||
type DeviceMapping struct {
|
||||
PathOnHost string
|
||||
PathInContainer string
|
||||
CgroupPermissions string
|
||||
}
|
||||
|
||||
// RestartPolicy represents the restart policies of the container.
|
||||
type RestartPolicy struct {
|
||||
Name string
|
||||
MaximumRetryCount int
|
||||
}
|
||||
|
||||
// IsNone indicates whether the container has the "no" restart policy.
|
||||
// This means the container will not automatically restart when exiting.
|
||||
func (rp *RestartPolicy) IsNone() bool {
|
||||
return rp.Name == "no"
|
||||
}
|
||||
|
||||
// IsAlways indicates whether the container has the "always" restart policy.
|
||||
// This means the container will automatically restart regardless of the exit status.
|
||||
func (rp *RestartPolicy) IsAlways() bool {
|
||||
return rp.Name == "always"
|
||||
}
|
||||
|
||||
// IsOnFailure indicates whether the container has the "on-failure" restart policy.
|
||||
// This means the contain will automatically restart of exiting with a non-zero exit status.
|
||||
func (rp *RestartPolicy) IsOnFailure() bool {
|
||||
return rp.Name == "on-failure"
|
||||
}
|
||||
|
||||
// IsUnlessStopped indicates whether the container has the
|
||||
// "unless-stopped" restart policy. This means the container will
|
||||
// automatically restart unless user has put it to stopped state.
|
||||
func (rp *RestartPolicy) IsUnlessStopped() bool {
|
||||
return rp.Name == "unless-stopped"
|
||||
}
|
||||
|
||||
// LogConfig represents the logging configuration of the container.
|
||||
type LogConfig struct {
|
||||
Type string
|
||||
Config map[string]string
|
||||
}
|
||||
|
||||
// Resources contains container's resources (cgroups config, ulimits...)
|
||||
type Resources struct {
|
||||
// Applicable to all platforms
|
||||
CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)
|
||||
|
||||
// Applicable to UNIX platforms
|
||||
CgroupParent string // Parent cgroup.
|
||||
BlkioWeight uint16 // Block IO weight (relative weight vs. other containers)
|
||||
BlkioWeightDevice []*blkiodev.WeightDevice
|
||||
BlkioDeviceReadBps []*blkiodev.ThrottleDevice
|
||||
BlkioDeviceWriteBps []*blkiodev.ThrottleDevice
|
||||
BlkioDeviceReadIOps []*blkiodev.ThrottleDevice
|
||||
BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice
|
||||
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
|
||||
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota
|
||||
CpusetCpus string // CpusetCpus 0-2, 0,1
|
||||
CpusetMems string // CpusetMems 0-2, 0,1
|
||||
Devices []DeviceMapping // List of devices to map inside the container
|
||||
KernelMemory int64 // Kernel memory limit (in bytes)
|
||||
Memory int64 // Memory limit (in bytes)
|
||||
MemoryReservation int64 // Memory soft limit (in bytes)
|
||||
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap
|
||||
MemorySwappiness *int64 // Tuning container memory swappiness behaviour
|
||||
OomKillDisable bool // Whether to disable OOM Killer or not
|
||||
Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container
|
||||
}
|
||||
|
||||
// HostConfig the non-portable Config structure of a container.
|
||||
// Here, "non-portable" means "dependent of the host we are running on".
|
||||
// Portable information *should* appear in Config.
|
||||
type HostConfig struct {
|
||||
// Applicable to all platforms
|
||||
Binds []string // List of volume bindings for this container
|
||||
ContainerIDFile string // File (path) where the containerId is written
|
||||
LogConfig LogConfig // Configuration of the logs for this container
|
||||
NetworkMode NetworkMode // Network mode to use for the container
|
||||
PortBindings nat.PortMap // Port mapping between the exposed port (container) and the host
|
||||
RestartPolicy RestartPolicy // Restart policy to be used for the container
|
||||
VolumeDriver string // Name of the volume driver used to mount volumes
|
||||
VolumesFrom []string // List of volumes to take from other container
|
||||
|
||||
// Applicable to UNIX platforms
|
||||
CapAdd *strslice.StrSlice // List of kernel capabilities to add to the container
|
||||
CapDrop *strslice.StrSlice // List of kernel capabilities to remove from the container
|
||||
DNS []string `json:"Dns"` // List of DNS server to lookup
|
||||
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
|
||||
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
|
||||
ExtraHosts []string // List of extra hosts
|
||||
GroupAdd []string // List of additional groups that the container process will run as
|
||||
IpcMode IpcMode // IPC namespace to use for the container
|
||||
Links []string // List of links (in the name:alias form)
|
||||
OomScoreAdj int // Container preference for OOM-killing
|
||||
PidMode PidMode // PID namespace to use for the container
|
||||
Privileged bool // Is the container in privileged mode
|
||||
PublishAllPorts bool // Should docker publish all exposed port for the container
|
||||
ReadonlyRootfs bool // Is the container root filesystem in read-only
|
||||
SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux.
|
||||
Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container
|
||||
UTSMode UTSMode // UTS namespace to use for the container
|
||||
ShmSize *int64 // Total shm memory usage
|
||||
|
||||
// Applicable to Windows
|
||||
ConsoleSize [2]int // Initial console size
|
||||
Isolation IsolationLevel // Isolation level of the container (eg default, hyperv)
|
||||
|
||||
// Contains container's resources (cgroups, ulimits)
|
||||
Resources
|
||||
}
|
||||
|
||||
// DecodeHostConfig creates a HostConfig based on the specified Reader.
|
||||
// It assumes the content of the reader will be JSON, and decodes it.
|
||||
func DecodeHostConfig(src io.Reader) (*HostConfig, error) {
|
||||
func DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
|
||||
decoder := json.NewDecoder(src)
|
||||
|
||||
var w ContainerConfigWrapper
|
||||
@ -252,10 +25,10 @@ func DecodeHostConfig(src io.Reader) (*HostConfig, error) {
|
||||
// to default if it is not populated. This ensures backwards compatibility after
|
||||
// the validation of the network mode was moved from the docker CLI to the
|
||||
// docker daemon.
|
||||
func SetDefaultNetModeIfBlank(hc *HostConfig) *HostConfig {
|
||||
func SetDefaultNetModeIfBlank(hc *container.HostConfig) *container.HostConfig {
|
||||
if hc != nil {
|
||||
if hc.NetworkMode == NetworkMode("") {
|
||||
hc.NetworkMode = NetworkMode("default")
|
||||
if hc.NetworkMode == container.NetworkMode("") {
|
||||
hc.NetworkMode = container.NetworkMode("default")
|
||||
}
|
||||
}
|
||||
return hc
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,6 +3,7 @@ package runconfig
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
@ -11,7 +12,7 @@ import (
|
||||
// by the cli.
|
||||
// It will mutate the specified user configuration (userConf) with the image
|
||||
// configuration where the user configuration is incomplete.
|
||||
func Merge(userConf, imageConf *Config) error {
|
||||
func Merge(userConf, imageConf *container.Config) error {
|
||||
if userConf.User == "" {
|
||||
userConf.User = imageConf.User
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package runconfig
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
@ -13,7 +14,7 @@ func TestMerge(t *testing.T) {
|
||||
portsImage := make(nat.PortSet)
|
||||
portsImage[newPortNoError("tcp", "1111")] = struct{}{}
|
||||
portsImage[newPortNoError("tcp", "2222")] = struct{}{}
|
||||
configImage := &Config{
|
||||
configImage := &container.Config{
|
||||
ExposedPorts: portsImage,
|
||||
Env: []string{"VAR1=1", "VAR2=2"},
|
||||
Volumes: volumesImage,
|
||||
@ -24,7 +25,7 @@ func TestMerge(t *testing.T) {
|
||||
portsUser[newPortNoError("tcp", "3333")] = struct{}{}
|
||||
volumesUser := make(map[string]struct{})
|
||||
volumesUser["/test3"] = struct{}{}
|
||||
configUser := &Config{
|
||||
configUser := &container.Config{
|
||||
ExposedPorts: portsUser,
|
||||
Env: []string{"VAR2=3", "VAR3=3"},
|
||||
Volumes: volumesUser,
|
||||
@ -64,7 +65,7 @@ func TestMerge(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
configImage2 := &Config{
|
||||
configImage2 := &container.Config{
|
||||
ExposedPorts: ports,
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/opts"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
@ -47,7 +48,7 @@ var (
|
||||
// Parse parses the specified args for the specified command and generates a Config,
|
||||
// a HostConfig and returns them with the specified command.
|
||||
// If the specified args are not valid, it will return an error.
|
||||
func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
|
||||
func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.HostConfig, *flag.FlagSet, error) {
|
||||
var (
|
||||
// FIXME: use utils.ListOpts for attach and volumes?
|
||||
flAttach = opts.NewListOpts(opts.ValidateAttach)
|
||||
@ -300,7 +301,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
}
|
||||
|
||||
// parse device mappings
|
||||
deviceMappings := []DeviceMapping{}
|
||||
deviceMappings := []container.DeviceMapping{}
|
||||
for _, device := range flDevices.GetAll() {
|
||||
deviceMapping, err := ParseDevice(device)
|
||||
if err != nil {
|
||||
@ -321,17 +322,17 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
return nil, nil, cmd, err
|
||||
}
|
||||
|
||||
ipcMode := IpcMode(*flIpcMode)
|
||||
ipcMode := container.IpcMode(*flIpcMode)
|
||||
if !ipcMode.Valid() {
|
||||
return nil, nil, cmd, fmt.Errorf("--ipc: invalid IPC mode")
|
||||
}
|
||||
|
||||
pidMode := PidMode(*flPidMode)
|
||||
pidMode := container.PidMode(*flPidMode)
|
||||
if !pidMode.Valid() {
|
||||
return nil, nil, cmd, fmt.Errorf("--pid: invalid PID mode")
|
||||
}
|
||||
|
||||
utsMode := UTSMode(*flUTSMode)
|
||||
utsMode := container.UTSMode(*flUTSMode)
|
||||
if !utsMode.Valid() {
|
||||
return nil, nil, cmd, fmt.Errorf("--uts: invalid UTS mode")
|
||||
}
|
||||
@ -346,7 +347,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
return nil, nil, cmd, err
|
||||
}
|
||||
|
||||
resources := Resources{
|
||||
resources := container.Resources{
|
||||
CgroupParent: *flCgroupParent,
|
||||
Memory: flMemory,
|
||||
MemoryReservation: MemoryReservation,
|
||||
@ -369,7 +370,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
Devices: deviceMappings,
|
||||
}
|
||||
|
||||
config := &Config{
|
||||
config := &container.Config{
|
||||
Hostname: hostname,
|
||||
Domainname: domainname,
|
||||
ExposedPorts: ports,
|
||||
@ -394,7 +395,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
StopSignal: *flStopSignal,
|
||||
}
|
||||
|
||||
hostConfig := &HostConfig{
|
||||
hostConfig := &container.HostConfig{
|
||||
Binds: binds,
|
||||
ContainerIDFile: *flContainerIDFile,
|
||||
OomScoreAdj: *flOomScoreAdj,
|
||||
@ -412,7 +413,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
DNSOptions: flDNSOptions.GetAllOrEmpty(),
|
||||
ExtraHosts: flExtraHosts.GetAll(),
|
||||
VolumesFrom: flVolumesFrom.GetAll(),
|
||||
NetworkMode: NetworkMode(*flNetMode),
|
||||
NetworkMode: container.NetworkMode(*flNetMode),
|
||||
IpcMode: ipcMode,
|
||||
PidMode: pidMode,
|
||||
UTSMode: utsMode,
|
||||
@ -422,9 +423,9 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
||||
RestartPolicy: restartPolicy,
|
||||
SecurityOpt: flSecurityOpt.GetAll(),
|
||||
ReadonlyRootfs: *flReadonlyRootfs,
|
||||
LogConfig: LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
|
||||
LogConfig: container.LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
|
||||
VolumeDriver: *flVolumeDriver,
|
||||
Isolation: IsolationLevel(*flIsolation),
|
||||
Isolation: container.IsolationLevel(*flIsolation),
|
||||
ShmSize: parsedShm,
|
||||
Resources: resources,
|
||||
Tmpfs: tmpfs,
|
||||
@ -477,8 +478,8 @@ func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]st
|
||||
}
|
||||
|
||||
// ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect
|
||||
func ParseRestartPolicy(policy string) (RestartPolicy, error) {
|
||||
p := RestartPolicy{}
|
||||
func ParseRestartPolicy(policy string) (container.RestartPolicy, error) {
|
||||
p := container.RestartPolicy{}
|
||||
|
||||
if policy == "" {
|
||||
return p, nil
|
||||
@ -516,20 +517,8 @@ func ParseRestartPolicy(policy string) (RestartPolicy, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func parseKeyValueOpts(opts opts.ListOpts) ([]KeyValuePair, error) {
|
||||
out := make([]KeyValuePair, opts.Len())
|
||||
for i, o := range opts.GetAll() {
|
||||
k, v, err := parsers.ParseKeyValueOpt(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = KeyValuePair{Key: k, Value: v}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ParseDevice parses a device mapping string to a DeviceMapping struct
|
||||
func ParseDevice(device string) (DeviceMapping, error) {
|
||||
// ParseDevice parses a device mapping string to a container.DeviceMapping struct
|
||||
func ParseDevice(device string) (container.DeviceMapping, error) {
|
||||
src := ""
|
||||
dst := ""
|
||||
permissions := "rwm"
|
||||
@ -548,14 +537,14 @@ func ParseDevice(device string) (DeviceMapping, error) {
|
||||
case 1:
|
||||
src = arr[0]
|
||||
default:
|
||||
return DeviceMapping{}, fmt.Errorf("Invalid device specification: %s", device)
|
||||
return container.DeviceMapping{}, fmt.Errorf("Invalid device specification: %s", device)
|
||||
}
|
||||
|
||||
if dst == "" {
|
||||
dst = src
|
||||
}
|
||||
|
||||
deviceMapping := DeviceMapping{
|
||||
deviceMapping := container.DeviceMapping{
|
||||
PathOnHost: src,
|
||||
PathInContainer: dst,
|
||||
CgroupPermissions: permissions,
|
||||
|
||||
@ -10,23 +10,24 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/go-connections/nat"
|
||||
)
|
||||
|
||||
func parseRun(args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
|
||||
func parseRun(args []string) (*container.Config, *container.HostConfig, *flag.FlagSet, error) {
|
||||
cmd := flag.NewFlagSet("run", flag.ContinueOnError)
|
||||
cmd.SetOutput(ioutil.Discard)
|
||||
cmd.Usage = nil
|
||||
return Parse(cmd, args)
|
||||
}
|
||||
|
||||
func parse(t *testing.T, args string) (*Config, *HostConfig, error) {
|
||||
func parse(t *testing.T, args string) (*container.Config, *container.HostConfig, error) {
|
||||
config, hostConfig, _, err := parseRun(strings.Split(args+" ubuntu bash", " "))
|
||||
return config, hostConfig, err
|
||||
}
|
||||
|
||||
func mustParse(t *testing.T, args string) (*Config, *HostConfig) {
|
||||
func mustParse(t *testing.T, args string) (*container.Config, *container.HostConfig) {
|
||||
config, hostConfig, err := parse(t, args)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -280,18 +281,18 @@ func TestDecodeContainerConfigVolumes(t *testing.T) {
|
||||
// passed into it. It returns a config and a hostconfig which can be
|
||||
// validated to ensure DecodeContainerConfig has manipulated the structures
|
||||
// correctly.
|
||||
func callDecodeContainerConfig(volumes []string, binds []string) (*Config, *HostConfig, error) {
|
||||
func callDecodeContainerConfig(volumes []string, binds []string) (*container.Config, *container.HostConfig, error) {
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
c *Config
|
||||
h *HostConfig
|
||||
c *container.Config
|
||||
h *container.HostConfig
|
||||
)
|
||||
w := ContainerConfigWrapper{
|
||||
Config: &Config{
|
||||
Config: &container.Config{
|
||||
Volumes: map[string]struct{}{},
|
||||
},
|
||||
HostConfig: &HostConfig{
|
||||
HostConfig: &container.HostConfig{
|
||||
NetworkMode: "none",
|
||||
Binds: binds,
|
||||
},
|
||||
@ -450,7 +451,7 @@ func TestParseWithExpose(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseDevice(t *testing.T) {
|
||||
valids := map[string]DeviceMapping{
|
||||
valids := map[string]container.DeviceMapping{
|
||||
"/dev/snd": {
|
||||
PathOnHost: "/dev/snd",
|
||||
PathInContainer: "/dev/snd",
|
||||
@ -546,7 +547,7 @@ func TestParseRestartPolicy(t *testing.T) {
|
||||
"on-failure:invalid": `strconv.ParseInt: parsing "invalid": invalid syntax`,
|
||||
"on-failure:2:5": "restart count format is not valid, usage: 'on-failure:N' or 'on-failure'",
|
||||
}
|
||||
valids := map[string]RestartPolicy{
|
||||
valids := map[string]container.RestartPolicy{
|
||||
"": {},
|
||||
"always": {
|
||||
Name: "always",
|
||||
|
||||
Reference in New Issue
Block a user