add better generate
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
This commit is contained in:
parent
3fc6abf56b
commit
cdd93563f5
5655 changed files with 1187011 additions and 392 deletions
81
vendor/github.com/docker/docker-ce/components/engine/runconfig/config.go
generated
vendored
Normal file
81
vendor/github.com/docker/docker-ce/components/engine/runconfig/config.go
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
networktypes "github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
)
|
||||
|
||||
// ContainerDecoder implements httputils.ContainerDecoder
|
||||
// calling DecodeContainerConfig.
|
||||
type ContainerDecoder struct{}
|
||||
|
||||
// DecodeConfig makes ContainerDecoder to implement httputils.ContainerDecoder
|
||||
func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
|
||||
return decodeContainerConfig(src)
|
||||
}
|
||||
|
||||
// DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder
|
||||
func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
|
||||
return decodeHostConfig(src)
|
||||
}
|
||||
|
||||
// decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
|
||||
// struct and returns both a Config and a 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) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
|
||||
var w ContainerConfigWrapper
|
||||
|
||||
decoder := json.NewDecoder(src)
|
||||
if err := decoder.Decode(&w); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
hc := w.getHostConfig()
|
||||
|
||||
// Perform platform-specific processing of Volumes and Binds.
|
||||
if w.Config != nil && hc != nil {
|
||||
|
||||
// Initialize the volumes map if currently nil
|
||||
if w.Config.Volumes == nil {
|
||||
w.Config.Volumes = make(map[string]struct{})
|
||||
}
|
||||
}
|
||||
|
||||
// Certain parameters need daemon-side validation that cannot be done
|
||||
// on the client, as only the daemon knows what is valid for the platform.
|
||||
if err := validateNetMode(w.Config, hc); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// Validate isolation
|
||||
if err := validateIsolation(hc); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// Validate QoS
|
||||
if err := validateQoS(hc); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// Validate Resources
|
||||
if err := validateResources(hc, sysinfo.New(true)); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// Validate Privileged
|
||||
if err := validatePrivileged(hc); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
// Validate ReadonlyRootfs
|
||||
if err := validateReadonlyRootfs(hc); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
return w.Config, hc, w.NetworkingConfig, nil
|
||||
}
|
190
vendor/github.com/docker/docker-ce/components/engine/runconfig/config_test.go
generated
vendored
Normal file
190
vendor/github.com/docker/docker-ce/components/engine/runconfig/config_test.go
generated
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
networktypes "github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
)
|
||||
|
||||
type f struct {
|
||||
file string
|
||||
entrypoint strslice.StrSlice
|
||||
}
|
||||
|
||||
func TestDecodeContainerConfig(t *testing.T) {
|
||||
|
||||
var (
|
||||
fixtures []f
|
||||
image string
|
||||
)
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
image = "ubuntu"
|
||||
fixtures = []f{
|
||||
{"fixtures/unix/container_config_1_14.json", strslice.StrSlice{}},
|
||||
{"fixtures/unix/container_config_1_17.json", strslice.StrSlice{"bash"}},
|
||||
{"fixtures/unix/container_config_1_19.json", strslice.StrSlice{"bash"}},
|
||||
}
|
||||
} else {
|
||||
image = "windows"
|
||||
fixtures = []f{
|
||||
{"fixtures/windows/container_config_1_19.json", strslice.StrSlice{"cmd"}},
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range fixtures {
|
||||
b, err := ioutil.ReadFile(f.file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c, h, _, err := decodeContainerConfig(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
|
||||
}
|
||||
|
||||
if c.Image != image {
|
||||
t.Fatalf("Expected %s image, found %s\n", image, c.Image)
|
||||
}
|
||||
|
||||
if len(c.Entrypoint) != len(f.entrypoint) {
|
||||
t.Fatalf("Expected %v, found %v\n", f.entrypoint, c.Entrypoint)
|
||||
}
|
||||
|
||||
if h != nil && h.Memory != 1000 {
|
||||
t.Fatalf("Expected memory to be 1000, found %d\n", h.Memory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestDecodeContainerConfigIsolation validates isolation passed
|
||||
// to the daemon in the hostConfig structure. Note this is platform specific
|
||||
// as to what level of container isolation is supported.
|
||||
func TestDecodeContainerConfigIsolation(t *testing.T) {
|
||||
|
||||
// An Invalid isolation level
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation("invalid"); err != nil {
|
||||
if !strings.Contains(err.Error(), `Invalid isolation: "invalid"`) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Blank isolation (== default)
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation(""); err != nil {
|
||||
t.Fatal("Blank isolation should have succeeded")
|
||||
}
|
||||
|
||||
// Default isolation
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation("default"); err != nil {
|
||||
t.Fatal("default isolation should have succeeded")
|
||||
}
|
||||
|
||||
// Process isolation (Valid on Windows only)
|
||||
if runtime.GOOS == "windows" {
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation("process"); err != nil {
|
||||
t.Fatal("process isolation should have succeeded")
|
||||
}
|
||||
} else {
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation("process"); err != nil {
|
||||
if !strings.Contains(err.Error(), `Invalid isolation: "process"`) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hyper-V Containers isolation (Valid on Windows only)
|
||||
if runtime.GOOS == "windows" {
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation("hyperv"); err != nil {
|
||||
t.Fatal("hyperv isolation should have succeeded")
|
||||
}
|
||||
} else {
|
||||
if _, _, _, err := callDecodeContainerConfigIsolation("hyperv"); err != nil {
|
||||
if !strings.Contains(err.Error(), `Invalid isolation: "hyperv"`) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// callDecodeContainerConfigIsolation is a utility function to call
|
||||
// DecodeContainerConfig for validating isolation
|
||||
func callDecodeContainerConfigIsolation(isolation string) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
)
|
||||
w := ContainerConfigWrapper{
|
||||
Config: &container.Config{},
|
||||
HostConfig: &container.HostConfig{
|
||||
NetworkMode: "none",
|
||||
Isolation: container.Isolation(isolation)},
|
||||
}
|
||||
if b, err = json.Marshal(w); err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("Error on marshal %s", err.Error())
|
||||
}
|
||||
return decodeContainerConfig(bytes.NewReader(b))
|
||||
}
|
||||
|
||||
type decodeConfigTestcase struct {
|
||||
doc string
|
||||
wrapper ContainerConfigWrapper
|
||||
expectedErr string
|
||||
expectedConfig *container.Config
|
||||
expectedHostConfig *container.HostConfig
|
||||
goos string
|
||||
}
|
||||
|
||||
func runDecodeContainerConfigTestCase(testcase decodeConfigTestcase) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
raw := marshal(t, testcase.wrapper, testcase.doc)
|
||||
config, hostConfig, _, err := decodeContainerConfig(bytes.NewReader(raw))
|
||||
if testcase.expectedErr != "" {
|
||||
if !assert.Check(t, is.ErrorContains(err, "")) {
|
||||
return
|
||||
}
|
||||
assert.Check(t, is.Contains(err.Error(), testcase.expectedErr))
|
||||
return
|
||||
}
|
||||
assert.Check(t, err)
|
||||
assert.Check(t, is.DeepEqual(testcase.expectedConfig, config))
|
||||
assert.Check(t, is.DeepEqual(testcase.expectedHostConfig, hostConfig))
|
||||
}
|
||||
}
|
||||
|
||||
func marshal(t *testing.T, w ContainerConfigWrapper, doc string) []byte {
|
||||
b, err := json.Marshal(w)
|
||||
assert.NilError(t, err, "%s: failed to encode config wrapper", doc)
|
||||
return b
|
||||
}
|
||||
|
||||
func containerWrapperWithVolume(volume string) ContainerConfigWrapper {
|
||||
return ContainerConfigWrapper{
|
||||
Config: &container.Config{
|
||||
Volumes: map[string]struct{}{
|
||||
volume: {},
|
||||
},
|
||||
},
|
||||
HostConfig: &container.HostConfig{},
|
||||
}
|
||||
}
|
||||
|
||||
func containerWrapperWithBind(bind string) ContainerConfigWrapper {
|
||||
return ContainerConfigWrapper{
|
||||
Config: &container.Config{
|
||||
Volumes: map[string]struct{}{},
|
||||
},
|
||||
HostConfig: &container.HostConfig{
|
||||
Binds: []string{bind},
|
||||
},
|
||||
}
|
||||
}
|
59
vendor/github.com/docker/docker-ce/components/engine/runconfig/config_unix.go
generated
vendored
Normal file
59
vendor/github.com/docker/docker-ce/components/engine/runconfig/config_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
// +build !windows
|
||||
|
||||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/api/types/container"
|
||||
networktypes "github.com/docker/docker/api/types/network"
|
||||
)
|
||||
|
||||
// ContainerConfigWrapper is a Config wrapper that holds the container Config (portable)
|
||||
// and the corresponding HostConfig (non-portable).
|
||||
type ContainerConfigWrapper struct {
|
||||
*container.Config
|
||||
InnerHostConfig *container.HostConfig `json:"HostConfig,omitempty"`
|
||||
Cpuset string `json:",omitempty"` // Deprecated. Exported for backwards compatibility.
|
||||
NetworkingConfig *networktypes.NetworkingConfig `json:"NetworkingConfig,omitempty"`
|
||||
*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() *container.HostConfig {
|
||||
hc := w.HostConfig
|
||||
|
||||
if hc == nil && w.InnerHostConfig != nil {
|
||||
hc = w.InnerHostConfig
|
||||
} else if w.InnerHostConfig != nil {
|
||||
if hc.Memory != 0 && w.InnerHostConfig.Memory == 0 {
|
||||
w.InnerHostConfig.Memory = hc.Memory
|
||||
}
|
||||
if hc.MemorySwap != 0 && w.InnerHostConfig.MemorySwap == 0 {
|
||||
w.InnerHostConfig.MemorySwap = hc.MemorySwap
|
||||
}
|
||||
if hc.CPUShares != 0 && w.InnerHostConfig.CPUShares == 0 {
|
||||
w.InnerHostConfig.CPUShares = hc.CPUShares
|
||||
}
|
||||
if hc.CpusetCpus != "" && w.InnerHostConfig.CpusetCpus == "" {
|
||||
w.InnerHostConfig.CpusetCpus = hc.CpusetCpus
|
||||
}
|
||||
|
||||
if hc.VolumeDriver != "" && w.InnerHostConfig.VolumeDriver == "" {
|
||||
w.InnerHostConfig.VolumeDriver = hc.VolumeDriver
|
||||
}
|
||||
|
||||
hc = w.InnerHostConfig
|
||||
}
|
||||
|
||||
if hc != nil {
|
||||
if w.Cpuset != "" && hc.CpusetCpus == "" {
|
||||
hc.CpusetCpus = w.Cpuset
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure NetworkMode has an acceptable value. We do this to ensure
|
||||
// backwards compatible API behavior.
|
||||
SetDefaultNetModeIfBlank(hc)
|
||||
|
||||
return hc
|
||||
}
|
19
vendor/github.com/docker/docker-ce/components/engine/runconfig/config_windows.go
generated
vendored
Normal file
19
vendor/github.com/docker/docker-ce/components/engine/runconfig/config_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/api/types/container"
|
||||
networktypes "github.com/docker/docker/api/types/network"
|
||||
)
|
||||
|
||||
// ContainerConfigWrapper is a Config wrapper that holds the container Config (portable)
|
||||
// and the corresponding HostConfig (non-portable).
|
||||
type ContainerConfigWrapper struct {
|
||||
*container.Config
|
||||
HostConfig *container.HostConfig `json:"HostConfig,omitempty"`
|
||||
NetworkingConfig *networktypes.NetworkingConfig `json:"NetworkingConfig,omitempty"`
|
||||
}
|
||||
|
||||
// getHostConfig gets the HostConfig of the Config.
|
||||
func (w *ContainerConfigWrapper) getHostConfig() *container.HostConfig {
|
||||
return w.HostConfig
|
||||
}
|
42
vendor/github.com/docker/docker-ce/components/engine/runconfig/errors.go
generated
vendored
Normal file
42
vendor/github.com/docker/docker-ce/components/engine/runconfig/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
const (
|
||||
// ErrConflictContainerNetworkAndLinks conflict between --net=container and links
|
||||
ErrConflictContainerNetworkAndLinks validationError = "conflicting options: container type network can't be used with links. This would result in undefined behavior"
|
||||
// ErrConflictSharedNetwork conflict between private and other networks
|
||||
ErrConflictSharedNetwork validationError = "container sharing network namespace with another container or host cannot be connected to any other network"
|
||||
// ErrConflictHostNetwork conflict from being disconnected from host network or connected to host network.
|
||||
ErrConflictHostNetwork validationError = "container cannot be disconnected from host network or connected to host network"
|
||||
// ErrConflictNoNetwork conflict between private and other networks
|
||||
ErrConflictNoNetwork validationError = "container cannot be connected to multiple networks with one of the networks in private (none) mode"
|
||||
// ErrConflictNetworkAndDNS conflict between --dns and the network mode
|
||||
ErrConflictNetworkAndDNS validationError = "conflicting options: dns and the network mode"
|
||||
// ErrConflictNetworkHostname conflict between the hostname and the network mode
|
||||
ErrConflictNetworkHostname validationError = "conflicting options: hostname and the network mode"
|
||||
// ErrConflictHostNetworkAndLinks conflict between --net=host and links
|
||||
ErrConflictHostNetworkAndLinks validationError = "conflicting options: host type networking can't be used with links. This would result in undefined behavior"
|
||||
// ErrConflictContainerNetworkAndMac conflict between the mac address and the network mode
|
||||
ErrConflictContainerNetworkAndMac validationError = "conflicting options: mac-address and the network mode"
|
||||
// ErrConflictNetworkHosts conflict between add-host and the network mode
|
||||
ErrConflictNetworkHosts validationError = "conflicting options: custom host-to-IP mapping and the network mode"
|
||||
// ErrConflictNetworkPublishPorts conflict between the publish options and the network mode
|
||||
ErrConflictNetworkPublishPorts validationError = "conflicting options: port publishing and the container type network mode"
|
||||
// ErrConflictNetworkExposePorts conflict between the expose option and the network mode
|
||||
ErrConflictNetworkExposePorts validationError = "conflicting options: port exposing and the container type network mode"
|
||||
// ErrUnsupportedNetworkAndIP conflict between network mode and requested ip address
|
||||
ErrUnsupportedNetworkAndIP validationError = "user specified IP address is supported on user defined networks only"
|
||||
// ErrUnsupportedNetworkNoSubnetAndIP conflict between network with no configured subnet and requested ip address
|
||||
ErrUnsupportedNetworkNoSubnetAndIP validationError = "user specified IP address is supported only when connecting to networks with user configured subnets"
|
||||
// ErrUnsupportedNetworkAndAlias conflict between network mode and alias
|
||||
ErrUnsupportedNetworkAndAlias validationError = "network-scoped alias is supported only for containers in user defined networks"
|
||||
// ErrConflictUTSHostname conflict between the hostname and the UTS mode
|
||||
ErrConflictUTSHostname validationError = "conflicting options: hostname and the UTS mode"
|
||||
)
|
||||
|
||||
type validationError string
|
||||
|
||||
func (e validationError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func (e validationError) InvalidParameter() {}
|
30
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_config_1_14.json
generated
vendored
Normal file
30
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_config_1_14.json
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"Hostname":"",
|
||||
"Domainname": "",
|
||||
"User":"",
|
||||
"Memory": 1000,
|
||||
"MemorySwap":0,
|
||||
"CpuShares": 512,
|
||||
"Cpuset": "0,1",
|
||||
"AttachStdin":false,
|
||||
"AttachStdout":true,
|
||||
"AttachStderr":true,
|
||||
"PortSpecs":null,
|
||||
"Tty":false,
|
||||
"OpenStdin":false,
|
||||
"StdinOnce":false,
|
||||
"Env":null,
|
||||
"Cmd":[
|
||||
"bash"
|
||||
],
|
||||
"Image":"ubuntu",
|
||||
"Volumes":{
|
||||
"/tmp": {}
|
||||
},
|
||||
"WorkingDir":"",
|
||||
"NetworkDisabled": false,
|
||||
"ExposedPorts":{
|
||||
"22/tcp": {}
|
||||
},
|
||||
"RestartPolicy": { "Name": "always" }
|
||||
}
|
50
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_config_1_17.json
generated
vendored
Normal file
50
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_config_1_17.json
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"Memory": 1000,
|
||||
"MemorySwap": 0,
|
||||
"CpuShares": 512,
|
||||
"Cpuset": "0,1",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": null,
|
||||
"Cmd": [
|
||||
"date"
|
||||
],
|
||||
"Entrypoint": "bash",
|
||||
"Image": "ubuntu",
|
||||
"Volumes": {
|
||||
"/tmp": {}
|
||||
},
|
||||
"WorkingDir": "",
|
||||
"NetworkDisabled": false,
|
||||
"MacAddress": "12:34:56:78:9a:bc",
|
||||
"ExposedPorts": {
|
||||
"22/tcp": {}
|
||||
},
|
||||
"SecurityOpt": [""],
|
||||
"HostConfig": {
|
||||
"Binds": ["/tmp:/tmp"],
|
||||
"Links": ["redis3:redis"],
|
||||
"LxcConf": {"lxc.utsname":"docker"},
|
||||
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
|
||||
"PublishAllPorts": false,
|
||||
"Privileged": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"Dns": ["8.8.8.8"],
|
||||
"DnsSearch": [""],
|
||||
"DnsOptions": [""],
|
||||
"ExtraHosts": null,
|
||||
"VolumesFrom": ["parent", "other:ro"],
|
||||
"CapAdd": ["NET_ADMIN"],
|
||||
"CapDrop": ["MKNOD"],
|
||||
"RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
|
||||
"NetworkMode": "bridge",
|
||||
"Devices": []
|
||||
}
|
||||
}
|
58
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_config_1_19.json
generated
vendored
Normal file
58
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_config_1_19.json
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": null,
|
||||
"Cmd": [
|
||||
"date"
|
||||
],
|
||||
"Entrypoint": "bash",
|
||||
"Image": "ubuntu",
|
||||
"Labels": {
|
||||
"com.example.vendor": "Acme",
|
||||
"com.example.license": "GPL",
|
||||
"com.example.version": "1.0"
|
||||
},
|
||||
"Volumes": {
|
||||
"/tmp": {}
|
||||
},
|
||||
"WorkingDir": "",
|
||||
"NetworkDisabled": false,
|
||||
"MacAddress": "12:34:56:78:9a:bc",
|
||||
"ExposedPorts": {
|
||||
"22/tcp": {}
|
||||
},
|
||||
"HostConfig": {
|
||||
"Binds": ["/tmp:/tmp"],
|
||||
"Links": ["redis3:redis"],
|
||||
"LxcConf": {"lxc.utsname":"docker"},
|
||||
"Memory": 1000,
|
||||
"MemorySwap": 0,
|
||||
"CpuShares": 512,
|
||||
"CpusetCpus": "0,1",
|
||||
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
|
||||
"PublishAllPorts": false,
|
||||
"Privileged": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"Dns": ["8.8.8.8"],
|
||||
"DnsSearch": [""],
|
||||
"DnsOptions": [""],
|
||||
"ExtraHosts": null,
|
||||
"VolumesFrom": ["parent", "other:ro"],
|
||||
"CapAdd": ["NET_ADMIN"],
|
||||
"CapDrop": ["MKNOD"],
|
||||
"RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
|
||||
"NetworkMode": "bridge",
|
||||
"Devices": [],
|
||||
"Ulimits": [{}],
|
||||
"LogConfig": { "Type": "json-file", "Config": {} },
|
||||
"SecurityOpt": [""],
|
||||
"CgroupParent": ""
|
||||
}
|
||||
}
|
18
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_hostconfig_1_14.json
generated
vendored
Normal file
18
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_hostconfig_1_14.json
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"Binds": ["/tmp:/tmp"],
|
||||
"ContainerIDFile": "",
|
||||
"LxcConf": [],
|
||||
"Privileged": false,
|
||||
"PortBindings": {
|
||||
"80/tcp": [
|
||||
{
|
||||
"HostIp": "0.0.0.0",
|
||||
"HostPort": "49153"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Links": ["/name:alias"],
|
||||
"PublishAllPorts": false,
|
||||
"CapAdd": ["NET_ADMIN"],
|
||||
"CapDrop": ["MKNOD"]
|
||||
}
|
30
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_hostconfig_1_19.json
generated
vendored
Normal file
30
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/unix/container_hostconfig_1_19.json
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"Binds": ["/tmp:/tmp"],
|
||||
"Links": ["redis3:redis"],
|
||||
"LxcConf": {"lxc.utsname":"docker"},
|
||||
"Memory": 0,
|
||||
"MemorySwap": 0,
|
||||
"CpuShares": 512,
|
||||
"CpuPeriod": 100000,
|
||||
"CpusetCpus": "0,1",
|
||||
"CpusetMems": "0,1",
|
||||
"BlkioWeight": 300,
|
||||
"OomKillDisable": false,
|
||||
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
|
||||
"PublishAllPorts": false,
|
||||
"Privileged": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"Dns": ["8.8.8.8"],
|
||||
"DnsSearch": [""],
|
||||
"ExtraHosts": null,
|
||||
"VolumesFrom": ["parent", "other:ro"],
|
||||
"CapAdd": ["NET_ADMIN"],
|
||||
"CapDrop": ["MKNOD"],
|
||||
"RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
|
||||
"NetworkMode": "bridge",
|
||||
"Devices": [],
|
||||
"Ulimits": [{}],
|
||||
"LogConfig": { "Type": "json-file", "Config": {} },
|
||||
"SecurityOpt": [""],
|
||||
"CgroupParent": ""
|
||||
}
|
58
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/windows/container_config_1_19.json
generated
vendored
Normal file
58
vendor/github.com/docker/docker-ce/components/engine/runconfig/fixtures/windows/container_config_1_19.json
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": null,
|
||||
"Cmd": [
|
||||
"date"
|
||||
],
|
||||
"Entrypoint": "cmd",
|
||||
"Image": "windows",
|
||||
"Labels": {
|
||||
"com.example.vendor": "Acme",
|
||||
"com.example.license": "GPL",
|
||||
"com.example.version": "1.0"
|
||||
},
|
||||
"Volumes": {
|
||||
"c:/windows": {}
|
||||
},
|
||||
"WorkingDir": "",
|
||||
"NetworkDisabled": false,
|
||||
"MacAddress": "12:34:56:78:9a:bc",
|
||||
"ExposedPorts": {
|
||||
"22/tcp": {}
|
||||
},
|
||||
"HostConfig": {
|
||||
"Binds": ["c:/windows:d:/tmp"],
|
||||
"Links": ["redis3:redis"],
|
||||
"LxcConf": {"lxc.utsname":"docker"},
|
||||
"Memory": 1000,
|
||||
"MemorySwap": 0,
|
||||
"CpuShares": 512,
|
||||
"CpusetCpus": "0,1",
|
||||
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
|
||||
"PublishAllPorts": false,
|
||||
"Privileged": false,
|
||||
"ReadonlyRootfs": false,
|
||||
"Dns": ["8.8.8.8"],
|
||||
"DnsSearch": [""],
|
||||
"DnsOptions": [""],
|
||||
"ExtraHosts": null,
|
||||
"VolumesFrom": ["parent", "other:ro"],
|
||||
"CapAdd": ["NET_ADMIN"],
|
||||
"CapDrop": ["MKNOD"],
|
||||
"RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
|
||||
"NetworkMode": "default",
|
||||
"Devices": [],
|
||||
"Ulimits": [{}],
|
||||
"LogConfig": { "Type": "json-file", "Config": {} },
|
||||
"SecurityOpt": [""],
|
||||
"CgroupParent": ""
|
||||
}
|
||||
}
|
79
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig.go
generated
vendored
Normal file
79
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig.go
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
)
|
||||
|
||||
// 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) (*container.HostConfig, error) {
|
||||
decoder := json.NewDecoder(src)
|
||||
|
||||
var w ContainerConfigWrapper
|
||||
if err := decoder.Decode(&w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hc := w.getHostConfig()
|
||||
return hc, nil
|
||||
}
|
||||
|
||||
// SetDefaultNetModeIfBlank changes the NetworkMode in a HostConfig structure
|
||||
// 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 *container.HostConfig) {
|
||||
if hc != nil {
|
||||
if hc.NetworkMode == container.NetworkMode("") {
|
||||
hc.NetworkMode = container.NetworkMode("default")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validateNetContainerMode ensures that the various combinations of requested
|
||||
// network settings wrt container mode are valid.
|
||||
func validateNetContainerMode(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
|
||||
}
|
||||
parts := strings.Split(string(hc.NetworkMode), ":")
|
||||
if parts[0] == "container" {
|
||||
if len(parts) < 2 || parts[1] == "" {
|
||||
return validationError("Invalid network mode: invalid container format container:<name|id>")
|
||||
}
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && c.Hostname != "" {
|
||||
return ErrConflictNetworkHostname
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.Links) > 0 {
|
||||
return ErrConflictContainerNetworkAndLinks
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
|
||||
return ErrConflictNetworkAndDNS
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
|
||||
return ErrConflictNetworkHosts
|
||||
}
|
||||
|
||||
if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && c.MacAddress != "" {
|
||||
return ErrConflictContainerNetworkAndMac
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts) {
|
||||
return ErrConflictNetworkPublishPorts
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && len(c.ExposedPorts) > 0 {
|
||||
return ErrConflictNetworkExposePorts
|
||||
}
|
||||
return nil
|
||||
}
|
273
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_test.go
generated
vendored
Normal file
273
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_test.go
generated
vendored
Normal file
|
@ -0,0 +1,273 @@
|
|||
// +build !windows
|
||||
|
||||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
is "github.com/gotestyourself/gotestyourself/assert/cmp"
|
||||
)
|
||||
|
||||
// TODO Windows: This will need addressing for a Windows daemon.
|
||||
func TestNetworkModeTest(t *testing.T) {
|
||||
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},
|
||||
"bridge": {true, true, false, false, false, false},
|
||||
DefaultDaemonNetworkMode(): {true, true, false, false, false, false},
|
||||
"host": {false, false, true, false, false, false},
|
||||
"container:name": {false, false, false, true, false, false},
|
||||
"none": {true, false, false, false, true, false},
|
||||
"default": {true, false, false, false, false, true},
|
||||
}
|
||||
networkModeNames := map[container.NetworkMode]string{
|
||||
"": "",
|
||||
"something:weird": "something:weird",
|
||||
"bridge": "bridge",
|
||||
DefaultDaemonNetworkMode(): "bridge",
|
||||
"host": "host",
|
||||
"container:name": "container",
|
||||
"none": "none",
|
||||
"default": "default",
|
||||
}
|
||||
for networkMode, state := range networkModes {
|
||||
if networkMode.IsPrivate() != state[0] {
|
||||
t.Fatalf("NetworkMode.IsPrivate for %v should have been %v but was %v", networkMode, state[0], networkMode.IsPrivate())
|
||||
}
|
||||
if networkMode.IsBridge() != state[1] {
|
||||
t.Fatalf("NetworkMode.IsBridge for %v should have been %v but was %v", networkMode, state[1], networkMode.IsBridge())
|
||||
}
|
||||
if networkMode.IsHost() != state[2] {
|
||||
t.Fatalf("NetworkMode.IsHost for %v should have been %v but was %v", networkMode, state[2], networkMode.IsHost())
|
||||
}
|
||||
if networkMode.IsContainer() != state[3] {
|
||||
t.Fatalf("NetworkMode.IsContainer for %v should have been %v but was %v", networkMode, state[3], networkMode.IsContainer())
|
||||
}
|
||||
if networkMode.IsNone() != state[4] {
|
||||
t.Fatalf("NetworkMode.IsNone for %v should have been %v but was %v", networkMode, state[4], networkMode.IsNone())
|
||||
}
|
||||
if networkMode.IsDefault() != state[5] {
|
||||
t.Fatalf("NetworkMode.IsDefault for %v should have been %v but was %v", networkMode, state[5], networkMode.IsDefault())
|
||||
}
|
||||
if networkMode.NetworkName() != networkModeNames[networkMode] {
|
||||
t.Fatalf("Expected name %v, got %v", networkModeNames[networkMode], networkMode.NetworkName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIpcModeTest(t *testing.T) {
|
||||
ipcModes := map[container.IpcMode]struct {
|
||||
private bool
|
||||
host bool
|
||||
container bool
|
||||
shareable bool
|
||||
valid bool
|
||||
ctrName string
|
||||
}{
|
||||
"": {valid: true},
|
||||
"private": {private: true, valid: true},
|
||||
"something:weird": {},
|
||||
":weird": {},
|
||||
"host": {host: true, valid: true},
|
||||
"container": {},
|
||||
"container:": {container: true, valid: true, ctrName: ""},
|
||||
"container:name": {container: true, valid: true, ctrName: "name"},
|
||||
"container:name1:name2": {container: true, valid: true, ctrName: "name1:name2"},
|
||||
"shareable": {shareable: true, valid: true},
|
||||
}
|
||||
|
||||
for ipcMode, state := range ipcModes {
|
||||
assert.Check(t, is.Equal(state.private, ipcMode.IsPrivate()), "IpcMode.IsPrivate() parsing failed for %q", ipcMode)
|
||||
assert.Check(t, is.Equal(state.host, ipcMode.IsHost()), "IpcMode.IsHost() parsing failed for %q", ipcMode)
|
||||
assert.Check(t, is.Equal(state.container, ipcMode.IsContainer()), "IpcMode.IsContainer() parsing failed for %q", ipcMode)
|
||||
assert.Check(t, is.Equal(state.shareable, ipcMode.IsShareable()), "IpcMode.IsShareable() parsing failed for %q", ipcMode)
|
||||
assert.Check(t, is.Equal(state.valid, ipcMode.Valid()), "IpcMode.Valid() parsing failed for %q", ipcMode)
|
||||
assert.Check(t, is.Equal(state.ctrName, ipcMode.Container()), "IpcMode.Container() parsing failed for %q", ipcMode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUTSModeTest(t *testing.T) {
|
||||
utsModes := map[container.UTSMode][]bool{
|
||||
// private, host, valid
|
||||
"": {true, false, true},
|
||||
"something:weird": {true, false, false},
|
||||
"host": {false, true, true},
|
||||
"host:name": {true, false, true},
|
||||
}
|
||||
for utsMode, state := range utsModes {
|
||||
if utsMode.IsPrivate() != state[0] {
|
||||
t.Fatalf("UtsMode.IsPrivate for %v should have been %v but was %v", utsMode, state[0], utsMode.IsPrivate())
|
||||
}
|
||||
if utsMode.IsHost() != state[1] {
|
||||
t.Fatalf("UtsMode.IsHost for %v should have been %v but was %v", utsMode, state[1], utsMode.IsHost())
|
||||
}
|
||||
if utsMode.Valid() != state[2] {
|
||||
t.Fatalf("UtsMode.Valid for %v should have been %v but was %v", utsMode, state[2], utsMode.Valid())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsernsModeTest(t *testing.T) {
|
||||
usrensMode := map[container.UsernsMode][]bool{
|
||||
// private, host, valid
|
||||
"": {true, false, true},
|
||||
"something:weird": {true, false, false},
|
||||
"host": {false, true, true},
|
||||
"host:name": {true, false, true},
|
||||
}
|
||||
for usernsMode, state := range usrensMode {
|
||||
if usernsMode.IsPrivate() != state[0] {
|
||||
t.Fatalf("UsernsMode.IsPrivate for %v should have been %v but was %v", usernsMode, state[0], usernsMode.IsPrivate())
|
||||
}
|
||||
if usernsMode.IsHost() != state[1] {
|
||||
t.Fatalf("UsernsMode.IsHost for %v should have been %v but was %v", usernsMode, state[1], usernsMode.IsHost())
|
||||
}
|
||||
if usernsMode.Valid() != state[2] {
|
||||
t.Fatalf("UsernsMode.Valid for %v should have been %v but was %v", usernsMode, state[2], usernsMode.Valid())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPidModeTest(t *testing.T) {
|
||||
pidModes := map[container.PidMode][]bool{
|
||||
// private, host, valid
|
||||
"": {true, false, true},
|
||||
"something:weird": {true, false, false},
|
||||
"host": {false, true, true},
|
||||
"host:name": {true, false, true},
|
||||
}
|
||||
for pidMode, state := range pidModes {
|
||||
if pidMode.IsPrivate() != state[0] {
|
||||
t.Fatalf("PidMode.IsPrivate for %v should have been %v but was %v", pidMode, state[0], pidMode.IsPrivate())
|
||||
}
|
||||
if pidMode.IsHost() != state[1] {
|
||||
t.Fatalf("PidMode.IsHost for %v should have been %v but was %v", pidMode, state[1], pidMode.IsHost())
|
||||
}
|
||||
if pidMode.Valid() != state[2] {
|
||||
t.Fatalf("PidMode.Valid for %v should have been %v but was %v", pidMode, state[2], pidMode.Valid())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRestartPolicy(t *testing.T) {
|
||||
restartPolicies := map[container.RestartPolicy][]bool{
|
||||
// none, always, failure
|
||||
{}: {true, false, false},
|
||||
{Name: "something", MaximumRetryCount: 0}: {false, false, false},
|
||||
{Name: "no", MaximumRetryCount: 0}: {true, false, false},
|
||||
{Name: "always", MaximumRetryCount: 0}: {false, true, false},
|
||||
{Name: "on-failure", MaximumRetryCount: 0}: {false, false, true},
|
||||
}
|
||||
for restartPolicy, state := range restartPolicies {
|
||||
if restartPolicy.IsNone() != state[0] {
|
||||
t.Fatalf("RestartPolicy.IsNone for %v should have been %v but was %v", restartPolicy, state[0], restartPolicy.IsNone())
|
||||
}
|
||||
if restartPolicy.IsAlways() != state[1] {
|
||||
t.Fatalf("RestartPolicy.IsAlways for %v should have been %v but was %v", restartPolicy, state[1], restartPolicy.IsAlways())
|
||||
}
|
||||
if restartPolicy.IsOnFailure() != state[2] {
|
||||
t.Fatalf("RestartPolicy.IsOnFailure for %v should have been %v but was %v", restartPolicy, state[2], restartPolicy.IsOnFailure())
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestDecodeHostConfig(t *testing.T) {
|
||||
fixtures := []struct {
|
||||
file string
|
||||
}{
|
||||
{"fixtures/unix/container_hostconfig_1_14.json"},
|
||||
{"fixtures/unix/container_hostconfig_1_19.json"},
|
||||
}
|
||||
|
||||
for _, f := range fixtures {
|
||||
b, err := ioutil.ReadFile(f.file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
c, err := decodeHostConfig(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
|
||||
}
|
||||
|
||||
assert.Check(t, !c.Privileged)
|
||||
|
||||
if l := len(c.Binds); l != 1 {
|
||||
t.Fatalf("Expected 1 bind, found %d\n", l)
|
||||
}
|
||||
|
||||
if len(c.CapAdd) != 1 && c.CapAdd[0] != "NET_ADMIN" {
|
||||
t.Fatalf("Expected CapAdd NET_ADMIN, got %v", c.CapAdd)
|
||||
}
|
||||
|
||||
if len(c.CapDrop) != 1 && c.CapDrop[0] != "NET_ADMIN" {
|
||||
t.Fatalf("Expected CapDrop NET_ADMIN, got %v", c.CapDrop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateResources(t *testing.T) {
|
||||
type resourceTest struct {
|
||||
ConfigCPURealtimePeriod int64
|
||||
ConfigCPURealtimeRuntime int64
|
||||
SysInfoCPURealtimePeriod bool
|
||||
SysInfoCPURealtimeRuntime bool
|
||||
ErrorExpected bool
|
||||
FailureMsg string
|
||||
}
|
||||
|
||||
tests := []resourceTest{
|
||||
{
|
||||
ConfigCPURealtimePeriod: 1000,
|
||||
ConfigCPURealtimeRuntime: 1000,
|
||||
SysInfoCPURealtimePeriod: true,
|
||||
SysInfoCPURealtimeRuntime: true,
|
||||
ErrorExpected: false,
|
||||
FailureMsg: "Expected valid configuration",
|
||||
},
|
||||
{
|
||||
ConfigCPURealtimePeriod: 5000,
|
||||
ConfigCPURealtimeRuntime: 5000,
|
||||
SysInfoCPURealtimePeriod: false,
|
||||
SysInfoCPURealtimeRuntime: true,
|
||||
ErrorExpected: true,
|
||||
FailureMsg: "Expected failure when cpu-rt-period is set but kernel doesn't support it",
|
||||
},
|
||||
{
|
||||
ConfigCPURealtimePeriod: 5000,
|
||||
ConfigCPURealtimeRuntime: 5000,
|
||||
SysInfoCPURealtimePeriod: true,
|
||||
SysInfoCPURealtimeRuntime: false,
|
||||
ErrorExpected: true,
|
||||
FailureMsg: "Expected failure when cpu-rt-runtime is set but kernel doesn't support it",
|
||||
},
|
||||
{
|
||||
ConfigCPURealtimePeriod: 5000,
|
||||
ConfigCPURealtimeRuntime: 10000,
|
||||
SysInfoCPURealtimePeriod: true,
|
||||
SysInfoCPURealtimeRuntime: false,
|
||||
ErrorExpected: true,
|
||||
FailureMsg: "Expected failure when cpu-rt-runtime is greater than cpu-rt-period",
|
||||
},
|
||||
}
|
||||
|
||||
for _, rt := range tests {
|
||||
var hc container.HostConfig
|
||||
hc.Resources.CPURealtimePeriod = rt.ConfigCPURealtimePeriod
|
||||
hc.Resources.CPURealtimeRuntime = rt.ConfigCPURealtimeRuntime
|
||||
|
||||
var si sysinfo.SysInfo
|
||||
si.CPURealtimePeriod = rt.SysInfoCPURealtimePeriod
|
||||
si.CPURealtimeRuntime = rt.SysInfoCPURealtimeRuntime
|
||||
|
||||
if err := validateResources(&hc, &si); (err != nil) != rt.ErrorExpected {
|
||||
t.Fatal(rt.FailureMsg, err)
|
||||
}
|
||||
}
|
||||
}
|
110
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_unix.go
generated
vendored
Normal file
110
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
// +build !windows
|
||||
|
||||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
)
|
||||
|
||||
// DefaultDaemonNetworkMode returns the default network stack the daemon should
|
||||
// use.
|
||||
func DefaultDaemonNetworkMode() container.NetworkMode {
|
||||
return container.NetworkMode("bridge")
|
||||
}
|
||||
|
||||
// IsPreDefinedNetwork indicates if a network is predefined by the daemon
|
||||
func IsPreDefinedNetwork(network string) bool {
|
||||
n := container.NetworkMode(network)
|
||||
return n.IsBridge() || n.IsHost() || n.IsNone() || n.IsDefault()
|
||||
}
|
||||
|
||||
// validateNetMode ensures that the various combinations of requested
|
||||
// network settings are valid.
|
||||
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
|
||||
}
|
||||
|
||||
err := validateNetContainerMode(c, hc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hc.UTSMode.IsHost() && c.Hostname != "" {
|
||||
return ErrConflictUTSHostname
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsHost() && len(hc.Links) > 0 {
|
||||
return ErrConflictHostNetworkAndLinks
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateIsolation performs platform specific validation of
|
||||
// isolation in the hostconfig structure. Linux only supports "default"
|
||||
// which is LXC container isolation
|
||||
func validateIsolation(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
|
||||
}
|
||||
if !hc.Isolation.IsValid() {
|
||||
return fmt.Errorf("Invalid isolation: %q - %s only supports 'default'", hc.Isolation, runtime.GOOS)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateQoS performs platform specific validation of the QoS settings
|
||||
func validateQoS(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
|
||||
}
|
||||
|
||||
if hc.IOMaximumBandwidth != 0 {
|
||||
return fmt.Errorf("Invalid QoS settings: %s does not support configuration of maximum bandwidth", runtime.GOOS)
|
||||
}
|
||||
|
||||
if hc.IOMaximumIOps != 0 {
|
||||
return fmt.Errorf("Invalid QoS settings: %s does not support configuration of maximum IOPs", runtime.GOOS)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateResources performs platform specific validation of the resource settings
|
||||
// cpu-rt-runtime and cpu-rt-period can not be greater than their parent, cpu-rt-runtime requires sys_nice
|
||||
func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
|
||||
// We may not be passed a host config, such as in the case of docker commit
|
||||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if hc.Resources.CPURealtimePeriod > 0 && !si.CPURealtimePeriod {
|
||||
return fmt.Errorf("Your kernel does not support cgroup cpu real-time period")
|
||||
}
|
||||
|
||||
if hc.Resources.CPURealtimeRuntime > 0 && !si.CPURealtimeRuntime {
|
||||
return fmt.Errorf("Your kernel does not support cgroup cpu real-time runtime")
|
||||
}
|
||||
|
||||
if hc.Resources.CPURealtimePeriod != 0 && hc.Resources.CPURealtimeRuntime != 0 && hc.Resources.CPURealtimeRuntime > hc.Resources.CPURealtimePeriod {
|
||||
return fmt.Errorf("cpu real-time runtime cannot be higher than cpu real-time period")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validatePrivileged performs platform specific validation of the Privileged setting
|
||||
func validatePrivileged(hc *container.HostConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateReadonlyRootfs performs platform specific validation of the ReadonlyRootfs setting
|
||||
func validateReadonlyRootfs(hc *container.HostConfig) error {
|
||||
return nil
|
||||
}
|
96
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_windows.go
generated
vendored
Normal file
96
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
)
|
||||
|
||||
// DefaultDaemonNetworkMode returns the default network stack the daemon should
|
||||
// use.
|
||||
func DefaultDaemonNetworkMode() container.NetworkMode {
|
||||
return container.NetworkMode("nat")
|
||||
}
|
||||
|
||||
// IsPreDefinedNetwork indicates if a network is predefined by the daemon
|
||||
func IsPreDefinedNetwork(network string) bool {
|
||||
return !container.NetworkMode(network).IsUserDefined()
|
||||
}
|
||||
|
||||
// validateNetMode ensures that the various combinations of requested
|
||||
// network settings are valid.
|
||||
func validateNetMode(c *container.Config, hc *container.HostConfig) error {
|
||||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := validateNetContainerMode(c, hc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hc.NetworkMode.IsContainer() && hc.Isolation.IsHyperV() {
|
||||
return fmt.Errorf("Using the network stack of another container is not supported while using Hyper-V Containers")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateIsolation performs platform specific validation of the
|
||||
// isolation in the hostconfig structure. Windows supports 'default' (or
|
||||
// blank), 'process', or 'hyperv'.
|
||||
func validateIsolation(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
|
||||
}
|
||||
if !hc.Isolation.IsValid() {
|
||||
return fmt.Errorf("Invalid isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateQoS performs platform specific validation of the Qos settings
|
||||
func validateQoS(hc *container.HostConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateResources performs platform specific validation of the resource settings
|
||||
func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
|
||||
// We may not be passed a host config, such as in the case of docker commit
|
||||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
if hc.Resources.CPURealtimePeriod != 0 {
|
||||
return fmt.Errorf("Windows does not support CPU real-time period")
|
||||
}
|
||||
if hc.Resources.CPURealtimeRuntime != 0 {
|
||||
return fmt.Errorf("Windows does not support CPU real-time runtime")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validatePrivileged performs platform specific validation of the Privileged setting
|
||||
func validatePrivileged(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
|
||||
}
|
||||
if hc.Privileged {
|
||||
return fmt.Errorf("Windows does not support privileged mode")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateReadonlyRootfs performs platform specific validation of the ReadonlyRootfs setting
|
||||
func validateReadonlyRootfs(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
|
||||
}
|
||||
if hc.ReadonlyRootfs {
|
||||
return fmt.Errorf("Windows does not support root filesystem in read-only mode")
|
||||
}
|
||||
return nil
|
||||
}
|
17
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_windows_test.go
generated
vendored
Normal file
17
vendor/github.com/docker/docker-ce/components/engine/runconfig/hostconfig_windows_test.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// +build windows
|
||||
|
||||
package runconfig // import "github.com/docker/docker/runconfig"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
)
|
||||
|
||||
func TestValidatePrivileged(t *testing.T) {
|
||||
expected := "Windows does not support privileged mode"
|
||||
err := validatePrivileged(&container.HostConfig{Privileged: true})
|
||||
if err == nil || err.Error() != expected {
|
||||
t.Fatalf("Expected %s", expected)
|
||||
}
|
||||
}
|
20
vendor/github.com/docker/docker-ce/components/engine/runconfig/opts/parse.go
generated
vendored
Normal file
20
vendor/github.com/docker/docker-ce/components/engine/runconfig/opts/parse.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
package opts // import "github.com/docker/docker/runconfig/opts"
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue