package runconfig import ( "encoding/json" "io" "strings" "github.com/docker/docker/nat" "github.com/docker/docker/pkg/ulimit" ) type KeyValuePair struct { Key string Value string } type NetworkMode string // IsPrivate indicates whether container use it's private network stack func (n NetworkMode) IsPrivate() bool { return !(n.IsHost() || n.IsContainer()) } func (n NetworkMode) IsBridge() bool { return n == "bridge" } func (n NetworkMode) IsHost() bool { return n == "host" } func (n NetworkMode) IsContainer() bool { parts := strings.SplitN(string(n), ":", 2) return len(parts) > 1 && parts[0] == "container" } func (n NetworkMode) IsNone() bool { return n == "none" } type IpcMode string // IsPrivate indicates whether container use it's private ipc stack func (n IpcMode) IsPrivate() bool { return !(n.IsHost() || n.IsContainer()) } func (n IpcMode) IsHost() bool { return n == "host" } func (n IpcMode) IsContainer() bool { parts := strings.SplitN(string(n), ":", 2) return len(parts) > 1 && parts[0] == "container" } 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 } func (n IpcMode) Container() string { parts := strings.SplitN(string(n), ":", 2) if len(parts) > 1 { return parts[1] } return "" } type UTSMode string // IsPrivate indicates whether container use it's private UTS namespace func (n UTSMode) IsPrivate() bool { return !(n.IsHost()) } func (n UTSMode) IsHost() bool { return n == "host" } func (n UTSMode) Valid() bool { parts := strings.Split(string(n), ":") switch mode := parts[0]; mode { case "", "host": default: return false } return true } type PidMode string // IsPrivate indicates whether container use it's private pid stack func (n PidMode) IsPrivate() bool { return !(n.IsHost()) } func (n PidMode) IsHost() bool { return n == "host" } func (n PidMode) Valid() bool { parts := strings.Split(string(n), ":") switch mode := parts[0]; mode { case "", "host": default: return false } return true } type DeviceMapping struct { PathOnHost string PathInContainer string CgroupPermissions string } type RestartPolicy struct { Name string MaximumRetryCount int } func (rp *RestartPolicy) IsNone() bool { return rp.Name == "no" } func (rp *RestartPolicy) IsAlways() bool { return rp.Name == "always" } func (rp *RestartPolicy) IsOnFailure() bool { return rp.Name == "on-failure" } type LogConfig struct { Type string Config map[string]string } type LxcConfig struct { values []KeyValuePair } func (c *LxcConfig) MarshalJSON() ([]byte, error) { if c == nil { return []byte{}, nil } return json.Marshal(c.Slice()) } func (c *LxcConfig) UnmarshalJSON(b []byte) error { if len(b) == 0 { return nil } var kv []KeyValuePair if err := json.Unmarshal(b, &kv); err != nil { var h map[string]string if err := json.Unmarshal(b, &h); err != nil { return err } for k, v := range h { kv = append(kv, KeyValuePair{k, v}) } } c.values = kv return nil } func (c *LxcConfig) Len() int { if c == nil { return 0 } return len(c.values) } func (c *LxcConfig) Slice() []KeyValuePair { if c == nil { return nil } return c.values } func NewLxcConfig(values []KeyValuePair) *LxcConfig { return &LxcConfig{values} } type HostConfig struct { Binds []string ContainerIDFile string LxcConf *LxcConfig Memory int64 // Memory limit (in bytes) MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap CpuShares int64 // CPU shares (relative weight vs. other containers) CpuPeriod int64 CpusetCpus string // CpusetCpus 0-2, 0,1 CpusetMems string // CpusetMems 0-2, 0,1 CpuQuota int64 BlkioWeight int64 // Block IO weight (relative weight vs. other containers) OomKillDisable bool // Whether to disable OOM Killer or not Privileged bool PortBindings nat.PortMap Links []string PublishAllPorts bool Dns []string DnsSearch []string ExtraHosts []string VolumesFrom []string Devices []DeviceMapping NetworkMode NetworkMode IpcMode IpcMode PidMode PidMode UTSMode UTSMode CapAdd []string CapDrop []string RestartPolicy RestartPolicy SecurityOpt []string ReadonlyRootfs bool Ulimits []*ulimit.Ulimit LogConfig LogConfig CgroupParent string // Parent cgroup. } func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrapper { return &ContainerConfigWrapper{ config, &hostConfigWrapper{InnerHostConfig: hostConfig}, } } type hostConfigWrapper struct { InnerHostConfig *HostConfig `json:"HostConfig,omitempty"` Cpuset string `json:",omitempty"` // Deprecated. Exported for backwards compatibility. *HostConfig // Deprecated. Exported to read attrubutes from json that are not in the inner host config structure. } func (w hostConfigWrapper) GetHostConfig() *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 } hc = w.InnerHostConfig } if hc != nil && w.Cpuset != "" && hc.CpusetCpus == "" { hc.CpusetCpus = w.Cpuset } return hc } func DecodeHostConfig(src io.Reader) (*HostConfig, error) { decoder := json.NewDecoder(src) var w hostConfigWrapper if err := decoder.Decode(&w); err != nil { return nil, err } hc := w.GetHostConfig() return hc, nil }