Signed-off-by: Lei Jitang <leijitang@huawei.com>
| ... | ... |
@@ -19,6 +19,7 @@ import ( |
| 19 | 19 |
|
| 20 | 20 |
"github.com/docker/docker/api" |
| 21 | 21 |
"github.com/docker/docker/graph/tags" |
| 22 |
+ "github.com/docker/docker/opts" |
|
| 22 | 23 |
"github.com/docker/docker/pkg/archive" |
| 23 | 24 |
"github.com/docker/docker/pkg/fileutils" |
| 24 | 25 |
"github.com/docker/docker/pkg/httputils" |
| ... | ... |
@@ -28,6 +29,7 @@ import ( |
| 28 | 28 |
"github.com/docker/docker/pkg/progressreader" |
| 29 | 29 |
"github.com/docker/docker/pkg/streamformatter" |
| 30 | 30 |
"github.com/docker/docker/pkg/symlink" |
| 31 |
+ "github.com/docker/docker/pkg/ulimit" |
|
| 31 | 32 |
"github.com/docker/docker/pkg/units" |
| 32 | 33 |
"github.com/docker/docker/pkg/urlutil" |
| 33 | 34 |
"github.com/docker/docker/registry" |
| ... | ... |
@@ -60,6 +62,11 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
| 60 | 60 |
flCPUSetCpus := cmd.String([]string{"-cpuset-cpus"}, "", "CPUs in which to allow execution (0-3, 0,1)")
|
| 61 | 61 |
flCPUSetMems := cmd.String([]string{"-cpuset-mems"}, "", "MEMs in which to allow execution (0-3, 0,1)")
|
| 62 | 62 |
flCgroupParent := cmd.String([]string{"-cgroup-parent"}, "", "Optional parent cgroup for the container")
|
| 63 |
+ |
|
| 64 |
+ ulimits := make(map[string]*ulimit.Ulimit) |
|
| 65 |
+ flUlimits := opts.NewUlimitOpt(ulimits) |
|
| 66 |
+ cmd.Var(flUlimits, []string{"-ulimit"}, "Ulimit options")
|
|
| 67 |
+ |
|
| 63 | 68 |
cmd.Require(flag.Exact, 1) |
| 64 | 69 |
|
| 65 | 70 |
cmd.ParseFlags(args, true) |
| ... | ... |
@@ -277,6 +284,13 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
| 277 | 277 |
|
| 278 | 278 |
v.Set("dockerfile", *dockerfileName)
|
| 279 | 279 |
|
| 280 |
+ ulimitsVar := flUlimits.GetList() |
|
| 281 |
+ ulimitsJson, err := json.Marshal(ulimitsVar) |
|
| 282 |
+ if err != nil {
|
|
| 283 |
+ return err |
|
| 284 |
+ } |
|
| 285 |
+ v.Set("ulimits", string(ulimitsJson))
|
|
| 286 |
+ |
|
| 280 | 287 |
headers := http.Header(make(map[string][]string)) |
| 281 | 288 |
buf, err := json.Marshal(cli.configFile.AuthConfigs) |
| 282 | 289 |
if err != nil {
|
| ... | ... |
@@ -34,6 +34,7 @@ import ( |
| 34 | 34 |
"github.com/docker/docker/pkg/sockets" |
| 35 | 35 |
"github.com/docker/docker/pkg/stdcopy" |
| 36 | 36 |
"github.com/docker/docker/pkg/streamformatter" |
| 37 |
+ "github.com/docker/docker/pkg/ulimit" |
|
| 37 | 38 |
"github.com/docker/docker/pkg/version" |
| 38 | 39 |
"github.com/docker/docker/runconfig" |
| 39 | 40 |
"github.com/docker/docker/utils" |
| ... | ... |
@@ -1294,6 +1295,15 @@ func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *ht |
| 1294 | 1294 |
buildConfig.CPUSetMems = r.FormValue("cpusetmems")
|
| 1295 | 1295 |
buildConfig.CgroupParent = r.FormValue("cgroupparent")
|
| 1296 | 1296 |
|
| 1297 |
+ var buildUlimits = []*ulimit.Ulimit{}
|
|
| 1298 |
+ ulimitsJson := r.FormValue("ulimits")
|
|
| 1299 |
+ if ulimitsJson != "" {
|
|
| 1300 |
+ if err := json.NewDecoder(strings.NewReader(ulimitsJson)).Decode(&buildUlimits); err != nil {
|
|
| 1301 |
+ return err |
|
| 1302 |
+ } |
|
| 1303 |
+ buildConfig.Ulimits = buildUlimits |
|
| 1304 |
+ } |
|
| 1305 |
+ |
|
| 1297 | 1306 |
// Job cancellation. Note: not all job types support this. |
| 1298 | 1307 |
if closeNotifier, ok := w.(http.CloseNotifier); ok {
|
| 1299 | 1308 |
finished := make(chan struct{})
|
| ... | ... |
@@ -37,6 +37,7 @@ import ( |
| 37 | 37 |
"github.com/docker/docker/pkg/stringid" |
| 38 | 38 |
"github.com/docker/docker/pkg/symlink" |
| 39 | 39 |
"github.com/docker/docker/pkg/tarsum" |
| 40 |
+ "github.com/docker/docker/pkg/ulimit" |
|
| 40 | 41 |
"github.com/docker/docker/runconfig" |
| 41 | 42 |
"github.com/docker/docker/utils" |
| 42 | 43 |
) |
| ... | ... |
@@ -129,6 +130,7 @@ type builder struct {
|
| 129 | 129 |
cgroupParent string |
| 130 | 130 |
memory int64 |
| 131 | 131 |
memorySwap int64 |
| 132 |
+ ulimits []*ulimit.Ulimit |
|
| 132 | 133 |
|
| 133 | 134 |
cancelled <-chan struct{} // When closed, job was cancelled.
|
| 134 | 135 |
|
| ... | ... |
@@ -21,6 +21,7 @@ import ( |
| 21 | 21 |
"github.com/docker/docker/pkg/progressreader" |
| 22 | 22 |
"github.com/docker/docker/pkg/streamformatter" |
| 23 | 23 |
"github.com/docker/docker/pkg/stringid" |
| 24 |
+ "github.com/docker/docker/pkg/ulimit" |
|
| 24 | 25 |
"github.com/docker/docker/pkg/urlutil" |
| 25 | 26 |
"github.com/docker/docker/registry" |
| 26 | 27 |
"github.com/docker/docker/runconfig" |
| ... | ... |
@@ -62,6 +63,7 @@ type Config struct {
|
| 62 | 62 |
CPUSetCpus string |
| 63 | 63 |
CPUSetMems string |
| 64 | 64 |
CgroupParent string |
| 65 |
+ Ulimits []*ulimit.Ulimit |
|
| 65 | 66 |
AuthConfigs map[string]cliconfig.AuthConfig |
| 66 | 67 |
|
| 67 | 68 |
Stdout io.Writer |
| ... | ... |
@@ -205,6 +207,7 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
|
| 205 | 205 |
cgroupParent: buildConfig.CgroupParent, |
| 206 | 206 |
memory: buildConfig.Memory, |
| 207 | 207 |
memorySwap: buildConfig.MemorySwap, |
| 208 |
+ ulimits: buildConfig.Ulimits, |
|
| 208 | 209 |
cancelled: buildConfig.WaitCancelled(), |
| 209 | 210 |
id: stringid.GenerateRandomID(), |
| 210 | 211 |
} |
| ... | ... |
@@ -395,7 +395,7 @@ _docker_build() {
|
| 395 | 395 |
|
| 396 | 396 |
case "$cur" in |
| 397 | 397 |
-*) |
| 398 |
- COMPREPLY=( $( compgen -W "--cgroup-parent --cpuset-cpus --cpuset-mems --cpu-shares -c --cpu-period --cpu-quota --file -f --force-rm --help --memory -m --memory-swap --no-cache --pull --quiet -q --rm --tag -t" -- "$cur" ) ) |
|
| 398 |
+ COMPREPLY=( $( compgen -W "--cgroup-parent --cpuset-cpus --cpuset-mems --cpu-shares -c --cpu-period --cpu-quota --file -f --force-rm --help --memory -m --memory-swap --no-cache --pull --quiet -q --rm --tag -t --ulimit" -- "$cur" ) ) |
|
| 399 | 399 |
;; |
| 400 | 400 |
*) |
| 401 | 401 |
local counter="$(__docker_pos_first_nonflag '--cgroup-parent|--cpuset-cpus|--cpuset-mems|--cpu-shares|-c|--cpu-period|--cpu-quota|--file|-f|--memory|-m|--memory-swap|--tag|-t')" |
| ... | ... |
@@ -28,6 +28,7 @@ weight=1 |
| 28 | 28 |
--cpuset-mems="" MEMs in which to allow execution, e.g. `0-3`, `0,1` |
| 29 | 29 |
--cpuset-cpus="" CPUs in which to allow execution, e.g. `0-3`, `0,1` |
| 30 | 30 |
--cgroup-parent="" Optional parent cgroup for the container |
| 31 |
+ --ulimit=[] Ulimit options |
|
| 31 | 32 |
|
| 32 | 33 |
Builds Docker images from a Dockerfile and a "context". A build's context is |
| 33 | 34 |
the files located in the specified `PATH` or `URL`. The build process can refer |
| ... | ... |
@@ -245,5 +246,8 @@ the command line. |
| 245 | 245 |
|
| 246 | 246 |
When `docker build` is run with the `--cgroup-parent` option the containers |
| 247 | 247 |
used in the build will be run with the [corresponding `docker run` |
| 248 |
-flag](/reference/run/#specifying-custom-cgroups). |
|
| 248 |
+flag](/reference/run/#specifying-custom-cgroups). |
|
| 249 | 249 |
|
| 250 |
+Using the `--ulimit` option with `docker build` will cause each build step's |
|
| 251 |
+container to be started using those [`--ulimit` |
|
| 252 |
+flag values](/reference/run/#setting-ulimits-in-a-container). |
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"encoding/json" |
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 |
+ "github.com/docker/docker/pkg/ulimit" |
|
| 9 | 10 |
"github.com/go-check/check" |
| 10 | 11 |
) |
| 11 | 12 |
|
| ... | ... |
@@ -21,7 +22,7 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
|
| 21 | 21 |
c.Fatal(err) |
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 |
- dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "-t", name, ".") |
|
| 24 |
+ dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, ".") |
|
| 25 | 25 |
|
| 26 | 26 |
out, _ := dockerCmd(c, "ps", "-lq") |
| 27 | 27 |
|
| ... | ... |
@@ -34,6 +35,7 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
|
| 34 | 34 |
CpusetMems string |
| 35 | 35 |
CPUShares int64 |
| 36 | 36 |
CPUQuota int64 |
| 37 |
+ Ulimits []*ulimit.Ulimit |
|
| 37 | 38 |
} |
| 38 | 39 |
|
| 39 | 40 |
cfg, err := inspectFieldJSON(cID, "HostConfig") |
| ... | ... |
@@ -45,9 +47,9 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
|
| 45 | 45 |
if err := json.Unmarshal([]byte(cfg), &c1); err != nil {
|
| 46 | 46 |
c.Fatal(err, cfg) |
| 47 | 47 |
} |
| 48 |
- if c1.Memory != 67108864 || c1.MemorySwap != -1 || c1.CpusetCpus != "0" || c1.CpusetMems != "0" || c1.CPUShares != 100 || c1.CPUQuota != 8000 {
|
|
| 49 |
- c.Fatalf("resource constraints not set properly:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CPUShares: %d, CPUQuota: %d",
|
|
| 50 |
- c1.Memory, c1.MemorySwap, c1.CpusetCpus, c1.CpusetMems, c1.CPUShares, c1.CPUQuota) |
|
| 48 |
+ if c1.Memory != 67108864 || c1.MemorySwap != -1 || c1.CpusetCpus != "0" || c1.CpusetMems != "0" || c1.CPUShares != 100 || c1.CPUQuota != 8000 || c1.Ulimits[0].Name != "nofile" || c1.Ulimits[0].Hard != 42 {
|
|
| 49 |
+ c.Fatalf("resource constraints not set properly:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CPUShares: %d, CPUQuota: %d, Ulimits: %s",
|
|
| 50 |
+ c1.Memory, c1.MemorySwap, c1.CpusetCpus, c1.CpusetMems, c1.CPUShares, c1.CPUQuota, c1.Ulimits[0]) |
|
| 51 | 51 |
} |
| 52 | 52 |
|
| 53 | 53 |
// Make sure constraints aren't saved to image |
| ... | ... |
@@ -61,9 +63,10 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
|
| 61 | 61 |
if err := json.Unmarshal([]byte(cfg), &c2); err != nil {
|
| 62 | 62 |
c.Fatal(err, cfg) |
| 63 | 63 |
} |
| 64 |
- if c2.Memory == 67108864 || c2.MemorySwap == -1 || c2.CpusetCpus == "0" || c2.CpusetMems == "0" || c2.CPUShares == 100 || c2.CPUQuota == 8000 {
|
|
| 65 |
- c.Fatalf("resource constraints leaked from build:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CPUShares: %d, CPUQuota: %d",
|
|
| 66 |
- c2.Memory, c2.MemorySwap, c2.CpusetCpus, c2.CpusetMems, c2.CPUShares, c2.CPUQuota) |
|
| 64 |
+ if c2.Memory == 67108864 || c2.MemorySwap == -1 || c2.CpusetCpus == "0" || c2.CpusetMems == "0" || c2.CPUShares == 100 || c2.CPUQuota == 8000 || c2.Ulimits != nil {
|
|
| 65 |
+ c.Fatalf("resource constraints leaked from build:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CPUShares: %d, CPUQuota: %d, Ulimits: %s",
|
|
| 66 |
+ c2.Memory, c2.MemorySwap, c2.CpusetCpus, c2.CpusetMems, c2.CPUShares, c2.CPUQuota, c2.Ulimits) |
|
| 67 |
+ |
|
| 67 | 68 |
} |
| 68 | 69 |
|
| 69 | 70 |
} |
| ... | ... |
@@ -22,6 +22,7 @@ docker-build - Build a new image from the source code at PATH |
| 22 | 22 |
[**--cpuset-cpus**[=*CPUSET-CPUS*]] |
| 23 | 23 |
[**--cpuset-mems**[=*CPUSET-MEMS*]] |
| 24 | 24 |
[**--cgroup-parent**[=*CGROUP-PARENT*]] |
| 25 |
+[**--ulimit**[=*[]*]] |
|
| 25 | 26 |
|
| 26 | 27 |
PATH | URL | - |
| 27 | 28 |
|
| ... | ... |
@@ -142,6 +143,12 @@ two memory nodes. |
| 142 | 142 |
If the path is not absolute, the path is considered relative to the `cgroups` path of the init process. |
| 143 | 143 |
Cgroups are created if they do not already exist. |
| 144 | 144 |
|
| 145 |
+**--ulimit**=[] |
|
| 146 |
+ Ulimit options |
|
| 147 |
+ |
|
| 148 |
+ For more information about `ulimit` see [Setting ulimits in a |
|
| 149 |
+container](https://docs.docker.com/reference/commandline/run/#setting-ulimits-in-a-container) |
|
| 150 |
+ |
|
| 145 | 151 |
# EXAMPLES |
| 146 | 152 |
|
| 147 | 153 |
## Building an image using a Dockerfile located inside the current directory |