Browse code

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>

Qiang Huang authored on 2015/03/11 10:31:18
Showing 12 changed files
... ...
@@ -303,10 +303,10 @@ func populateCommand(c *Container, env []string) error {
303 303
 	}
304 304
 
305 305
 	resources := &execdriver.Resources{
306
-		Memory:     c.Config.Memory,
307
-		MemorySwap: c.Config.MemorySwap,
308
-		CpuShares:  c.Config.CpuShares,
309
-		Cpuset:     c.Config.Cpuset,
306
+		Memory:     c.hostConfig.Memory,
307
+		MemorySwap: c.hostConfig.MemorySwap,
308
+		CpuShares:  c.hostConfig.CpuShares,
309
+		CpusetCpus: c.hostConfig.CpusetCpus,
310 310
 		Rlimits:    rlimits,
311 311
 	}
312 312
 
... ...
@@ -18,33 +18,28 @@ func (daemon *Daemon) ContainerCreate(job *engine.Job) engine.Status {
18 18
 	} else if len(job.Args) > 1 {
19 19
 		return job.Errorf("Usage: %s", job.Name)
20 20
 	}
21
+
21 22
 	config := runconfig.ContainerConfigFromJob(job)
22
-	if config.Memory != 0 && config.Memory < 4194304 {
23
+	hostConfig := runconfig.ContainerHostConfigFromJob(job)
24
+
25
+	if hostConfig.Memory != 0 && hostConfig.Memory < 4194304 {
23 26
 		return job.Errorf("Minimum memory limit allowed is 4MB")
24 27
 	}
25
-	if config.Memory > 0 && !daemon.SystemConfig().MemoryLimit {
28
+	if hostConfig.Memory > 0 && !daemon.SystemConfig().MemoryLimit {
26 29
 		job.Errorf("Your kernel does not support memory limit capabilities. Limitation discarded.\n")
27
-		config.Memory = 0
30
+		hostConfig.Memory = 0
28 31
 	}
29
-	if config.Memory > 0 && !daemon.SystemConfig().SwapLimit {
32
+	if hostConfig.Memory > 0 && !daemon.SystemConfig().SwapLimit {
30 33
 		job.Errorf("Your kernel does not support swap limit capabilities. Limitation discarded.\n")
31
-		config.MemorySwap = -1
34
+		hostConfig.MemorySwap = -1
32 35
 	}
33
-	if config.Memory > 0 && config.MemorySwap > 0 && config.MemorySwap < config.Memory {
36
+	if hostConfig.Memory > 0 && hostConfig.MemorySwap > 0 && hostConfig.MemorySwap < hostConfig.Memory {
34 37
 		return job.Errorf("Minimum memoryswap limit should be larger than memory limit, see usage.\n")
35 38
 	}
36
-	if config.Memory == 0 && config.MemorySwap > 0 {
39
+	if hostConfig.Memory == 0 && hostConfig.MemorySwap > 0 {
37 40
 		return job.Errorf("You should always set the Memory limit when using Memoryswap limit, see usage.\n")
38 41
 	}
39 42
 
40
-	var hostConfig *runconfig.HostConfig
41
-	if job.EnvExists("HostConfig") {
42
-		hostConfig = runconfig.ContainerHostConfigFromJob(job)
43
-	} else {
44
-		// Older versions of the API don't provide a HostConfig.
45
-		hostConfig = nil
46
-	}
47
-
48 43
 	container, buildWarnings, err := daemon.Create(config, hostConfig, name)
49 44
 	if err != nil {
50 45
 		if daemon.Graph().IsNotExist(err) {
... ...
@@ -109,7 +109,7 @@ type Resources struct {
109 109
 	Memory     int64            `json:"memory"`
110 110
 	MemorySwap int64            `json:"memory_swap"`
111 111
 	CpuShares  int64            `json:"cpu_shares"`
112
-	Cpuset     string           `json:"cpuset"`
112
+	CpusetCpus string           `json:"cpuset_cpus"`
113 113
 	Rlimits    []*ulimit.Rlimit `json:"rlimits"`
114 114
 }
115 115
 
... ...
@@ -198,7 +198,7 @@ func SetupCgroups(container *configs.Config, c *Command) error {
198 198
 		container.Cgroups.Memory = c.Resources.Memory
199 199
 		container.Cgroups.MemoryReservation = c.Resources.Memory
200 200
 		container.Cgroups.MemorySwap = c.Resources.MemorySwap
201
-		container.Cgroups.CpusetCpus = c.Resources.Cpuset
201
+		container.Cgroups.CpusetCpus = c.Resources.CpusetCpus
202 202
 	}
203 203
 
204 204
 	return nil
... ...
@@ -107,8 +107,8 @@ lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}}
107 107
 {{if .Resources.CpuShares}}
108 108
 lxc.cgroup.cpu.shares = {{.Resources.CpuShares}}
109 109
 {{end}}
110
-{{if .Resources.Cpuset}}
111
-lxc.cgroup.cpuset.cpus = {{.Resources.Cpuset}}
110
+{{if .Resources.CpusetCpus}}
111
+lxc.cgroup.cpuset.cpus = {{.Resources.CpusetCpus}}
112 112
 {{end}}
113 113
 {{end}}
114 114
 
... ...
@@ -12,7 +12,7 @@ docker-create - Create a new container
12 12
 [**--cap-add**[=*[]*]]
13 13
 [**--cap-drop**[=*[]*]]
14 14
 [**--cidfile**[=*CIDFILE*]]
15
-[**--cpuset**[=*CPUSET*]]
15
+[**--cpuset-cpus**[=*CPUSET-CPUS*]]
16 16
 [**--device**[=*[]*]]
17 17
 [**--dns-search**[=*[]*]]
18 18
 [**--dns**[=*[]*]]
... ...
@@ -64,7 +64,7 @@ IMAGE [COMMAND] [ARG...]
64 64
 **--cidfile**=""
65 65
    Write the container ID to the file
66 66
 
67
-**--cpuset**=""
67
+**--cpuset-cpus**=""
68 68
    CPUs in which to allow execution (0-3, 0,1)
69 69
 
70 70
 **--device**=[]
... ...
@@ -12,7 +12,7 @@ docker-run - Run a command in a new container
12 12
 [**--cap-add**[=*[]*]]
13 13
 [**--cap-drop**[=*[]*]]
14 14
 [**--cidfile**[=*CIDFILE*]]
15
-[**--cpuset**[=*CPUSET*]]
15
+[**--cpuset-cpus**[=*CPUSET-CPUS*]]
16 16
 [**-d**|**--detach**[=*false*]]
17 17
 [**--device**[=*[]*]]
18 18
 [**--dns-search**[=*[]*]]
... ...
@@ -124,7 +124,7 @@ division of CPU shares:
124 124
 **--cidfile**=""
125 125
    Write the container ID to the file
126 126
 
127
-**--cpuset**=""
127
+**--cpuset-cpus**=""
128 128
    CPUs in which to allow execution (0-3, 0,1)
129 129
 
130 130
 **-d**, **--detach**=*true*|*false*
... ...
@@ -113,10 +113,6 @@ Create a container
113 113
              "Hostname": "",
114 114
              "Domainname": "",
115 115
              "User": "",
116
-             "Memory": 0,
117
-             "MemorySwap": 0,
118
-             "CpuShares": 512,
119
-             "Cpuset": "0,1",
120 116
              "AttachStdin": false,
121 117
              "AttachStdout": true,
122 118
              "AttachStderr": true,
... ...
@@ -143,6 +139,10 @@ Create a container
143 143
                "Binds": ["/tmp:/tmp"],
144 144
                "Links": ["redis3:redis"],
145 145
                "LxcConf": {"lxc.utsname":"docker"},
146
+               "Memory": 0,
147
+               "MemorySwap": 0,
148
+               "CpuShares": 512,
149
+               "CpusetCpus": "0,1",
146 150
                "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
147 151
                "PublishAllPorts": false,
148 152
                "Privileged": false,
... ...
@@ -182,7 +182,8 @@ Json Parameters:
182 182
       always use this with `memory`, and make the value larger than `memory`.
183 183
 -   **CpuShares** - An integer value containing the CPU Shares for container
184 184
       (ie. the relative weight vs othercontainers).
185
-    **CpuSet** - String value containg the cgroups Cpuset to use.
185
+-   **Cpuset** - The same as CpusetCpus, but deprecated, please don't use.
186
+-   **CpusetCpus** - String value containg the cgroups CpusetCpus to use.
186 187
 -   **AttachStdin** - Boolean value, attaches to stdin.
187 188
 -   **AttachStdout** - Boolean value, attaches to stdout.
188 189
 -   **AttachStderr** - Boolean value, attaches to stderr.
... ...
@@ -195,7 +196,7 @@ Json Parameters:
195 195
       of strings
196 196
 -   **Image** - String value containing the image name to use for the container
197 197
 -   **Volumes** – An object mapping mountpoint paths (strings) inside the
198
-        container to empty objects.
198
+      container to empty objects.
199 199
 -   **WorkingDir** - A string value containing the working dir for commands to
200 200
       run in.
201 201
 -   **NetworkDisabled** - Boolean value, when true disables neworking for the
... ...
@@ -292,8 +293,6 @@ Return low-level information on the container `id`
292 292
 				"-c",
293 293
 				"exit 9"
294 294
 			],
295
-			"CpuShares": 0,
296
-			"Cpuset": "",
297 295
 			"Domainname": "",
298 296
 			"Entrypoint": null,
299 297
 			"Env": [
... ...
@@ -303,8 +302,6 @@ Return low-level information on the container `id`
303 303
 			"Hostname": "ba033ac44011",
304 304
 			"Image": "ubuntu",
305 305
 			"MacAddress": "",
306
-			"Memory": 0,
307
-			"MemorySwap": 0,
308 306
 			"NetworkDisabled": false,
309 307
 			"OnBuild": null,
310 308
 			"OpenStdin": false,
... ...
@@ -324,6 +321,8 @@ Return low-level information on the container `id`
324 324
 			"CapAdd": null,
325 325
 			"CapDrop": null,
326 326
 			"ContainerIDFile": "",
327
+			"CpusetCpus": "",
328
+			"CpuShares": 0,
327 329
 			"Devices": [],
328 330
 			"Dns": null,
329 331
 			"DnsSearch": null,
... ...
@@ -331,6 +330,8 @@ Return low-level information on the container `id`
331 331
 			"IpcMode": "",
332 332
 			"Links": null,
333 333
 			"LxcConf": [],
334
+			"Memory": 0,
335
+			"MemorySwap": 0,
334 336
 			"NetworkMode": "bridge",
335 337
 			"PortBindings": {},
336 338
 			"Privileged": false,
... ...
@@ -1173,8 +1174,6 @@ Return low-level information on the image `name`
1173 1173
                      {
1174 1174
                              "Hostname": "",
1175 1175
                              "User": "",
1176
-                             "Memory": 0,
1177
-                             "MemorySwap": 0,
1178 1176
                              "AttachStdin": false,
1179 1177
                              "AttachStdout": false,
1180 1178
                              "AttachStderr": false,
... ...
@@ -1539,10 +1538,6 @@ Create a new image from a container's changes
1539 1539
              "Hostname": "",
1540 1540
              "Domainname": "",
1541 1541
              "User": "",
1542
-             "Memory": 0,
1543
-             "MemorySwap": 0,
1544
-             "CpuShares": 512,
1545
-             "Cpuset": "0,1",
1546 1542
              "AttachStdin": false,
1547 1543
              "AttachStdout": true,
1548 1544
              "AttachStderr": true,
... ...
@@ -1896,10 +1891,6 @@ Return low-level information about the exec command `id`.
1896 1896
               "Hostname" : "8f177a186b97",
1897 1897
               "Domainname" : "",
1898 1898
               "User" : "",
1899
-              "Memory" : 0,
1900
-              "MemorySwap" : 0,
1901
-              "CpuShares" : 0,
1902
-              "Cpuset" : "",
1903 1899
               "AttachStdin" : false,
1904 1900
               "AttachStdout" : false,
1905 1901
               "AttachStderr" : false,
... ...
@@ -781,7 +781,7 @@ Creates a new container.
781 781
       --cap-add=[]               Add Linux capabilities
782 782
       --cap-drop=[]              Drop Linux capabilities
783 783
       --cidfile=""               Write the container ID to the file
784
-      --cpuset=""                CPUs in which to allow execution (0-3, 0,1)
784
+      --cpuset-cpus=""           CPUs in which to allow execution (0-3, 0,1)
785 785
       --device=[]                Add a host device to the container
786 786
       --dns=[]                   Set custom DNS servers
787 787
       --dns-search=[]            Set custom DNS search domains
... ...
@@ -1638,7 +1638,7 @@ removed before the image is removed.
1638 1638
       --cap-add=[]               Add Linux capabilities
1639 1639
       --cap-drop=[]              Drop Linux capabilities
1640 1640
       --cidfile=""               Write the container ID to the file
1641
-      --cpuset=""                CPUs in which to allow execution (0-3, 0,1)
1641
+      --cpuset-cpus=""           CPUs in which to allow execution (0-3, 0,1)
1642 1642
       -d, --detach=false         Run container in background and print container ID
1643 1643
       --device=[]                Add a host device to the container
1644 1644
       --dns=[]                   Set custom DNS servers
... ...
@@ -1283,6 +1283,17 @@ func TestRunWithCpuset(t *testing.T) {
1283 1283
 	logDone("run - cpuset 0")
1284 1284
 }
1285 1285
 
1286
+func TestRunWithCpusetCpus(t *testing.T) {
1287
+	defer deleteAllContainers()
1288
+
1289
+	cmd := exec.Command(dockerBinary, "run", "--cpuset-cpus", "0", "busybox", "true")
1290
+	if code, err := runCommand(cmd); err != nil || code != 0 {
1291
+		t.Fatalf("container should run successfuly with cpuset-cpus of 0: %s", err)
1292
+	}
1293
+
1294
+	logDone("run - cpuset-cpus 0")
1295
+}
1296
+
1286 1297
 func TestRunDeviceNumbers(t *testing.T) {
1287 1298
 	defer deleteAllContainers()
1288 1299
 
... ...
@@ -12,10 +12,10 @@ type Config struct {
12 12
 	Hostname        string
13 13
 	Domainname      string
14 14
 	User            string
15
-	Memory          int64  // Memory limit (in bytes)
16
-	MemorySwap      int64  // Total memory usage (memory + swap); set `-1' to disable swap
17
-	CpuShares       int64  // CPU shares (relative weight vs. other containers)
18
-	Cpuset          string // Cpuset 0-2, 0,1
15
+	Memory          int64  // FIXME: we keep it for backward compatibility, it has been moved to hostConfig.
16
+	MemorySwap      int64  // FIXME: it has been moved to hostConfig.
17
+	CpuShares       int64  // FIXME: it has been moved to hostConfig.
18
+	Cpuset          string // FIXME: it has been moved to hostConfig and renamed to CpusetCpus.
19 19
 	AttachStdin     bool
20 20
 	AttachStdout    bool
21 21
 	AttachStderr    bool
... ...
@@ -103,6 +103,10 @@ type HostConfig struct {
103 103
 	Binds           []string
104 104
 	ContainerIDFile string
105 105
 	LxcConf         []utils.KeyValuePair
106
+	Memory          int64  // Memory limit (in bytes)
107
+	MemorySwap      int64  // Total memory usage (memory + swap); set `-1` to disable swap
108
+	CpuShares       int64  // CPU shares (relative weight vs. other containers)
109
+	CpusetCpus      string // CpusetCpus 0-2, 0,1
106 110
 	Privileged      bool
107 111
 	PortBindings    nat.PortMap
108 112
 	Links           []string
... ...
@@ -141,11 +145,31 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
141 141
 	if job.EnvExists("HostConfig") {
142 142
 		hostConfig := HostConfig{}
143 143
 		job.GetenvJson("HostConfig", &hostConfig)
144
+
145
+		// FIXME: These are for backward compatibility, if people use these
146
+		// options with `HostConfig`, we should still make them workable.
147
+		if job.EnvExists("Memory") && hostConfig.Memory == 0 {
148
+			hostConfig.Memory = job.GetenvInt64("Memory")
149
+		}
150
+		if job.EnvExists("MemorySwap") && hostConfig.MemorySwap == 0 {
151
+			hostConfig.MemorySwap = job.GetenvInt64("MemorySwap")
152
+		}
153
+		if job.EnvExists("CpuShares") && hostConfig.CpuShares == 0 {
154
+			hostConfig.CpuShares = job.GetenvInt64("CpuShares")
155
+		}
156
+		if job.EnvExists("Cpuset") && hostConfig.CpusetCpus == "" {
157
+			hostConfig.CpusetCpus = job.Getenv("Cpuset")
158
+		}
159
+
144 160
 		return &hostConfig
145 161
 	}
146 162
 
147 163
 	hostConfig := &HostConfig{
148 164
 		ContainerIDFile: job.Getenv("ContainerIDFile"),
165
+		Memory:          job.GetenvInt64("Memory"),
166
+		MemorySwap:      job.GetenvInt64("MemorySwap"),
167
+		CpuShares:       job.GetenvInt64("CpuShares"),
168
+		CpusetCpus:      job.Getenv("CpusetCpus"),
149 169
 		Privileged:      job.GetenvBool("Privileged"),
150 170
 		PublishAllPorts: job.GetenvBool("PublishAllPorts"),
151 171
 		NetworkMode:     NetworkMode(job.Getenv("NetworkMode")),
... ...
@@ -154,6 +178,13 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
154 154
 		ReadonlyRootfs:  job.GetenvBool("ReadonlyRootfs"),
155 155
 	}
156 156
 
157
+	// FIXME: This is for backward compatibility, if people use `Cpuset`
158
+	// in json, make it workable, we will only pass hostConfig.CpusetCpus
159
+	// to execDriver.
160
+	if job.EnvExists("Cpuset") && hostConfig.CpusetCpus == "" {
161
+		hostConfig.CpusetCpus = job.Getenv("Cpuset")
162
+	}
163
+
157 164
 	job.GetenvJson("LxcConf", &hostConfig.LxcConf)
158 165
 	job.GetenvJson("PortBindings", &hostConfig.PortBindings)
159 166
 	job.GetenvJson("Devices", &hostConfig.Devices)
... ...
@@ -62,7 +62,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
62 62
 		flUser            = cmd.String([]string{"u", "-user"}, "", "Username or UID (format: <name|uid>[:<group|gid>])")
63 63
 		flWorkingDir      = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container")
64 64
 		flCpuShares       = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
65
-		flCpuset          = cmd.String([]string{"-cpuset"}, "", "CPUs in which to allow execution (0-3, 0,1)")
65
+		flCpusetCpus      = cmd.String([]string{"#-cpuset", "-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
66 66
 		flNetMode         = cmd.String([]string{"-net"}, "bridge", "Set the Network mode for the container")
67 67
 		flMacAddress      = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
68 68
 		flIpcMode         = cmd.String([]string{"-ipc"}, "", "IPC namespace to use")
... ...
@@ -283,10 +283,10 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
283 283
 		Tty:             *flTty,
284 284
 		NetworkDisabled: !*flNetwork,
285 285
 		OpenStdin:       *flStdin,
286
-		Memory:          flMemory,
287
-		MemorySwap:      MemorySwap,
288
-		CpuShares:       *flCpuShares,
289
-		Cpuset:          *flCpuset,
286
+		Memory:          flMemory,      // FIXME: for backward compatibility
287
+		MemorySwap:      MemorySwap,    // FIXME: for backward compatibility
288
+		CpuShares:       *flCpuShares,  // FIXME: for backward compatibility
289
+		Cpuset:          *flCpusetCpus, // FIXME: for backward compatibility
290 290
 		AttachStdin:     attachStdin,
291 291
 		AttachStdout:    attachStdout,
292 292
 		AttachStderr:    attachStderr,
... ...
@@ -303,6 +303,10 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
303 303
 		Binds:           binds,
304 304
 		ContainerIDFile: *flContainerIDFile,
305 305
 		LxcConf:         lxcConf,
306
+		Memory:          flMemory,
307
+		MemorySwap:      MemorySwap,
308
+		CpuShares:       *flCpuShares,
309
+		CpusetCpus:      *flCpusetCpus,
306 310
 		Privileged:      *flPrivileged,
307 311
 		PortBindings:    portBindings,
308 312
 		Links:           flLinks.GetAll(),