2014-02-11 23:04:39 -05:00
|
|
|
package runconfig
|
|
|
|
|
|
|
|
import (
|
2015-04-10 20:05:21 -04:00
|
|
|
"encoding/json"
|
|
|
|
"io"
|
2014-05-02 19:59:28 -04:00
|
|
|
"strings"
|
|
|
|
|
2014-07-24 18:19:50 -04:00
|
|
|
"github.com/docker/docker/nat"
|
2015-02-11 14:21:38 -05:00
|
|
|
"github.com/docker/docker/pkg/ulimit"
|
2014-02-11 23:04:39 -05:00
|
|
|
)
|
|
|
|
|
2015-03-29 17:17:23 -04:00
|
|
|
type KeyValuePair struct {
|
|
|
|
Key string
|
|
|
|
Value string
|
|
|
|
}
|
|
|
|
|
2014-05-02 19:59:28 -04:00
|
|
|
type NetworkMode string
|
|
|
|
|
2014-09-05 02:43:44 -04:00
|
|
|
// IsPrivate indicates whether container use it's private network stack
|
|
|
|
func (n NetworkMode) IsPrivate() bool {
|
|
|
|
return !(n.IsHost() || n.IsContainer() || n.IsNone())
|
|
|
|
}
|
|
|
|
|
2014-05-02 19:59:28 -04:00
|
|
|
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"
|
|
|
|
}
|
|
|
|
|
2014-09-04 01:50:58 -04:00
|
|
|
func (n NetworkMode) IsNone() bool {
|
|
|
|
return n == "none"
|
|
|
|
}
|
|
|
|
|
2014-11-10 16:14:17 -05:00
|
|
|
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 ""
|
|
|
|
}
|
|
|
|
|
2014-11-25 15:10:53 -05:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2014-05-31 00:00:47 -04:00
|
|
|
type DeviceMapping struct {
|
|
|
|
PathOnHost string
|
|
|
|
PathInContainer string
|
|
|
|
CgroupPermissions string
|
|
|
|
}
|
|
|
|
|
2014-08-04 19:14:43 -04:00
|
|
|
type RestartPolicy struct {
|
|
|
|
Name string
|
|
|
|
MaximumRetryCount int
|
|
|
|
}
|
|
|
|
|
2015-02-04 14:04:58 -05:00
|
|
|
type LogConfig struct {
|
|
|
|
Type string
|
|
|
|
Config map[string]string
|
|
|
|
}
|
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
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}
|
|
|
|
}
|
|
|
|
|
2014-02-11 23:04:39 -05:00
|
|
|
type HostConfig struct {
|
2014-05-02 17:06:05 -04:00
|
|
|
Binds []string
|
|
|
|
ContainerIDFile string
|
2015-04-10 20:05:21 -04:00
|
|
|
LxcConf *LxcConfig
|
move resources from Config to HostConfig
Cgroup resources are host dependent, they should be in hostConfig.
For backward compatibility, we just copy it to hostConfig, and leave it in
Config for now, so there is no regressions, but the right way to use this
throught json is to put it in HostConfig, like:
{
"Hostname": "",
...
"HostConfig": {
"CpuShares": 512,
"Memory": 314572800,
...
}
}
As we will add CpusetMems, CpusetCpus is definitely a better name, but some
users are already using Cpuset in their http APIs, we also make it compatible.
The main idea is keep using Cpuset in Config Struct, and make it has the same
value as CpusetCpus, but not always, some scenarios:
- Users use --cpuset in docker command, it can setup cpuset.cpus and can
get Cpuset field from docker inspect or other http API which will get
config info.
- Users use --cpuset-cpus in docker command, ditto.
- Users use Cpuset field in their http APIs, ditto.
- Users use CpusetCpus field in their http APIs, they won't get Cpuset field
in Config info, because by then, they should already know what happens
to Cpuset.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
2015-03-10 21:31:18 -04:00
|
|
|
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)
|
|
|
|
CpusetCpus string // CpusetCpus 0-2, 0,1
|
2015-04-14 21:33:46 -04:00
|
|
|
CpusetMems string // CpusetMems 0-2, 0,1
|
2014-05-02 17:06:05 -04:00
|
|
|
Privileged bool
|
|
|
|
PortBindings nat.PortMap
|
|
|
|
Links []string
|
|
|
|
PublishAllPorts bool
|
|
|
|
Dns []string
|
|
|
|
DnsSearch []string
|
2014-09-13 00:35:59 -04:00
|
|
|
ExtraHosts []string
|
2014-05-02 17:06:05 -04:00
|
|
|
VolumesFrom []string
|
2014-05-31 00:00:47 -04:00
|
|
|
Devices []DeviceMapping
|
2014-05-02 19:59:28 -04:00
|
|
|
NetworkMode NetworkMode
|
2014-11-10 16:14:17 -05:00
|
|
|
IpcMode IpcMode
|
2014-11-25 15:10:53 -05:00
|
|
|
PidMode PidMode
|
2014-07-10 14:41:11 -04:00
|
|
|
CapAdd []string
|
|
|
|
CapDrop []string
|
2014-08-04 19:14:43 -04:00
|
|
|
RestartPolicy RestartPolicy
|
2014-11-03 17:57:18 -05:00
|
|
|
SecurityOpt []string
|
2015-01-13 16:52:51 -05:00
|
|
|
ReadonlyRootfs bool
|
2015-02-11 14:21:38 -05:00
|
|
|
Ulimits []*ulimit.Ulimit
|
2015-02-04 14:04:58 -05:00
|
|
|
LogConfig LogConfig
|
2015-03-16 18:42:15 -04:00
|
|
|
CgroupParent string // Parent cgroup.
|
2014-02-11 23:04:39 -05:00
|
|
|
}
|
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrapper {
|
|
|
|
return &ContainerConfigWrapper{
|
|
|
|
config,
|
|
|
|
&hostConfigWrapper{InnerHostConfig: hostConfig},
|
|
|
|
}
|
2014-03-10 09:11:23 -04:00
|
|
|
}
|
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
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.
|
2014-03-10 09:11:23 -04:00
|
|
|
}
|
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
func (w hostConfigWrapper) GetHostConfig() *HostConfig {
|
|
|
|
hc := w.HostConfig
|
move resources from Config to HostConfig
Cgroup resources are host dependent, they should be in hostConfig.
For backward compatibility, we just copy it to hostConfig, and leave it in
Config for now, so there is no regressions, but the right way to use this
throught json is to put it in HostConfig, like:
{
"Hostname": "",
...
"HostConfig": {
"CpuShares": 512,
"Memory": 314572800,
...
}
}
As we will add CpusetMems, CpusetCpus is definitely a better name, but some
users are already using Cpuset in their http APIs, we also make it compatible.
The main idea is keep using Cpuset in Config Struct, and make it has the same
value as CpusetCpus, but not always, some scenarios:
- Users use --cpuset in docker command, it can setup cpuset.cpus and can
get Cpuset field from docker inspect or other http API which will get
config info.
- Users use --cpuset-cpus in docker command, ditto.
- Users use Cpuset field in their http APIs, ditto.
- Users use CpusetCpus field in their http APIs, they won't get Cpuset field
in Config info, because by then, they should already know what happens
to Cpuset.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
2015-03-10 21:31:18 -04:00
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
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
|
move resources from Config to HostConfig
Cgroup resources are host dependent, they should be in hostConfig.
For backward compatibility, we just copy it to hostConfig, and leave it in
Config for now, so there is no regressions, but the right way to use this
throught json is to put it in HostConfig, like:
{
"Hostname": "",
...
"HostConfig": {
"CpuShares": 512,
"Memory": 314572800,
...
}
}
As we will add CpusetMems, CpusetCpus is definitely a better name, but some
users are already using Cpuset in their http APIs, we also make it compatible.
The main idea is keep using Cpuset in Config Struct, and make it has the same
value as CpusetCpus, but not always, some scenarios:
- Users use --cpuset in docker command, it can setup cpuset.cpus and can
get Cpuset field from docker inspect or other http API which will get
config info.
- Users use --cpuset-cpus in docker command, ditto.
- Users use Cpuset field in their http APIs, ditto.
- Users use CpusetCpus field in their http APIs, they won't get Cpuset field
in Config info, because by then, they should already know what happens
to Cpuset.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
2015-03-10 21:31:18 -04:00
|
|
|
}
|
2015-04-10 20:05:21 -04:00
|
|
|
if hc.MemorySwap != 0 && w.InnerHostConfig.MemorySwap == 0 {
|
|
|
|
w.InnerHostConfig.MemorySwap = hc.MemorySwap
|
move resources from Config to HostConfig
Cgroup resources are host dependent, they should be in hostConfig.
For backward compatibility, we just copy it to hostConfig, and leave it in
Config for now, so there is no regressions, but the right way to use this
throught json is to put it in HostConfig, like:
{
"Hostname": "",
...
"HostConfig": {
"CpuShares": 512,
"Memory": 314572800,
...
}
}
As we will add CpusetMems, CpusetCpus is definitely a better name, but some
users are already using Cpuset in their http APIs, we also make it compatible.
The main idea is keep using Cpuset in Config Struct, and make it has the same
value as CpusetCpus, but not always, some scenarios:
- Users use --cpuset in docker command, it can setup cpuset.cpus and can
get Cpuset field from docker inspect or other http API which will get
config info.
- Users use --cpuset-cpus in docker command, ditto.
- Users use Cpuset field in their http APIs, ditto.
- Users use CpusetCpus field in their http APIs, they won't get Cpuset field
in Config info, because by then, they should already know what happens
to Cpuset.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
2015-03-10 21:31:18 -04:00
|
|
|
}
|
2015-04-10 20:05:21 -04:00
|
|
|
if hc.CpuShares != 0 && w.InnerHostConfig.CpuShares == 0 {
|
|
|
|
w.InnerHostConfig.CpuShares = hc.CpuShares
|
move resources from Config to HostConfig
Cgroup resources are host dependent, they should be in hostConfig.
For backward compatibility, we just copy it to hostConfig, and leave it in
Config for now, so there is no regressions, but the right way to use this
throught json is to put it in HostConfig, like:
{
"Hostname": "",
...
"HostConfig": {
"CpuShares": 512,
"Memory": 314572800,
...
}
}
As we will add CpusetMems, CpusetCpus is definitely a better name, but some
users are already using Cpuset in their http APIs, we also make it compatible.
The main idea is keep using Cpuset in Config Struct, and make it has the same
value as CpusetCpus, but not always, some scenarios:
- Users use --cpuset in docker command, it can setup cpuset.cpus and can
get Cpuset field from docker inspect or other http API which will get
config info.
- Users use --cpuset-cpus in docker command, ditto.
- Users use Cpuset field in their http APIs, ditto.
- Users use CpusetCpus field in their http APIs, they won't get Cpuset field
in Config info, because by then, they should already know what happens
to Cpuset.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
2015-03-10 21:31:18 -04:00
|
|
|
}
|
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
hc = w.InnerHostConfig
|
2014-03-10 09:11:23 -04:00
|
|
|
}
|
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
if hc != nil && w.Cpuset != "" && hc.CpusetCpus == "" {
|
|
|
|
hc.CpusetCpus = w.Cpuset
|
2014-02-11 23:04:39 -05:00
|
|
|
}
|
2014-08-04 19:14:43 -04:00
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
return hc
|
|
|
|
}
|
move resources from Config to HostConfig
Cgroup resources are host dependent, they should be in hostConfig.
For backward compatibility, we just copy it to hostConfig, and leave it in
Config for now, so there is no regressions, but the right way to use this
throught json is to put it in HostConfig, like:
{
"Hostname": "",
...
"HostConfig": {
"CpuShares": 512,
"Memory": 314572800,
...
}
}
As we will add CpusetMems, CpusetCpus is definitely a better name, but some
users are already using Cpuset in their http APIs, we also make it compatible.
The main idea is keep using Cpuset in Config Struct, and make it has the same
value as CpusetCpus, but not always, some scenarios:
- Users use --cpuset in docker command, it can setup cpuset.cpus and can
get Cpuset field from docker inspect or other http API which will get
config info.
- Users use --cpuset-cpus in docker command, ditto.
- Users use Cpuset field in their http APIs, ditto.
- Users use CpusetCpus field in their http APIs, they won't get Cpuset field
in Config info, because by then, they should already know what happens
to Cpuset.
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
2015-03-10 21:31:18 -04:00
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
func DecodeHostConfig(src io.Reader) (*HostConfig, error) {
|
|
|
|
decoder := json.NewDecoder(src)
|
|
|
|
|
|
|
|
var w hostConfigWrapper
|
|
|
|
if err := decoder.Decode(&w); err != nil {
|
|
|
|
return nil, err
|
2014-07-10 17:51:15 -04:00
|
|
|
}
|
2014-08-04 19:14:43 -04:00
|
|
|
|
2015-04-10 20:05:21 -04:00
|
|
|
hc := w.GetHostConfig()
|
|
|
|
|
|
|
|
return hc, nil
|
2014-02-11 23:04:39 -05:00
|
|
|
}
|