Skip to content

Commit d6592dd

Browse files
authored
Merge pull request #2967 from akerouanton/ulimits
Add Ulimits to ContainerSpec
2 parents 293aa2e + ee3aa3c commit d6592dd

File tree

7 files changed

+565
-141
lines changed

7 files changed

+565
-141
lines changed

agent/exec/dockerapi/container.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/docker/docker/api/types/network"
1717
"github.com/docker/docker/api/types/volume"
1818
"github.com/docker/go-connections/nat"
19+
"github.com/docker/go-units"
1920
"github.com/docker/swarmkit/agent/exec"
2021
"github.com/docker/swarmkit/api"
2122
"github.com/docker/swarmkit/api/genericresource"
@@ -447,6 +448,15 @@ func (c *containerConfig) resources() enginecontainer.Resources {
447448
resources.PidsLimit = &pidsLimit
448449
}
449450

451+
resources.Ulimits = make([]*units.Ulimit, len(c.spec().Ulimits))
452+
for i, ulimit := range c.spec().Ulimits {
453+
resources.Ulimits[i] = &units.Ulimit{
454+
Name: ulimit.Name,
455+
Soft: ulimit.Soft,
456+
Hard: ulimit.Hard,
457+
}
458+
}
459+
450460
// If no limits are specified let the engine use its defaults.
451461
//
452462
// TODO(aluzzardi): We might want to set some limits anyway otherwise

agent/exec/dockerapi/container_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
enginecontainer "github.com/docker/docker/api/types/container"
99
enginemount "github.com/docker/docker/api/types/mount"
1010
"github.com/docker/docker/api/types/strslice"
11+
"github.com/docker/go-units"
1112
"github.com/docker/swarmkit/api"
1213
gogotypes "github.com/gogo/protobuf/types"
1314
)
@@ -297,3 +298,35 @@ func TestCapabilityDrop(t *testing.T) {
297298
t.Fatalf("expected %s, got %s", expected, actual)
298299
}
299300
}
301+
302+
func TestUlimits(t *testing.T) {
303+
c := containerConfig{
304+
task: &api.Task{
305+
Spec: api.TaskSpec{
306+
Runtime: &api.TaskSpec_Container{
307+
Container: &api.ContainerSpec{
308+
Ulimits: []*api.ContainerSpec_Ulimit{
309+
{
310+
Name: "nofile",
311+
Soft: 1024,
312+
Hard: 2048,
313+
},
314+
},
315+
},
316+
},
317+
},
318+
},
319+
}
320+
321+
expected := []*units.Ulimit{
322+
{
323+
Name: "nofile",
324+
Soft: 1024,
325+
Hard: 2048,
326+
},
327+
}
328+
actual := c.resources().Ulimits
329+
if !reflect.DeepEqual(actual, expected) {
330+
t.Fatalf("expected %v, got %v", expected, actual)
331+
}
332+
}

api/api.pb.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5081,6 +5081,14 @@ file {
50815081
type: TYPE_STRING
50825082
json_name: "capabilityDrop"
50835083
}
5084+
field {
5085+
name: "ulimits"
5086+
number: 29
5087+
label: LABEL_REPEATED
5088+
type: TYPE_MESSAGE
5089+
type_name: ".docker.swarmkit.v1.ContainerSpec.Ulimit"
5090+
json_name: "ulimits"
5091+
}
50845092
nested_type {
50855093
name: "LabelsEntry"
50865094
field {
@@ -5155,6 +5163,30 @@ file {
51555163
map_entry: true
51565164
}
51575165
}
5166+
nested_type {
5167+
name: "Ulimit"
5168+
field {
5169+
name: "name"
5170+
number: 1
5171+
label: LABEL_OPTIONAL
5172+
type: TYPE_STRING
5173+
json_name: "name"
5174+
}
5175+
field {
5176+
name: "soft"
5177+
number: 2
5178+
label: LABEL_OPTIONAL
5179+
type: TYPE_INT64
5180+
json_name: "soft"
5181+
}
5182+
field {
5183+
name: "hard"
5184+
number: 3
5185+
label: LABEL_OPTIONAL
5186+
type: TYPE_INT64
5187+
json_name: "hard"
5188+
}
5189+
}
51585190
enum_type {
51595191
name: "Isolation"
51605192
value {

api/specs.pb.go

Lines changed: 452 additions & 141 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/specs.proto

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,16 @@ message ContainerSpec {
360360
repeated string capability_add = 27;
361361
// CapabilityDrop sets the list of capabilities to drop from the default capability list
362362
repeated string capability_drop = 28;
363+
364+
message Ulimit {
365+
string name = 1;
366+
int64 soft = 2;
367+
int64 hard = 3;
368+
}
369+
370+
// Ulimits defines the list of ulimits to set in the container. This option
371+
// is equivalent to passing --ulimit to docker run.
372+
repeated Ulimit ulimits = 29;
363373
}
364374

365375
// EndpointSpec defines the properties that can be configured to

cmd/swarmctl/service/flagparser/flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func AddServiceFlags(flags *pflag.FlagSet) {
3434
flags.String("cpu-reservation", "", "number of CPU cores reserved (e.g. 0.5)")
3535
flags.String("cpu-limit", "", "CPU cores limit (e.g. 0.5)")
3636
flags.String("generic-resources", "", "user defined resources request (e.g. gpu=3,fpga=1)")
37+
flags.StringSlice("ulimit", []string{}, "ulimit options")
3738

3839
flags.Uint64("update-parallelism", 0, "task update parallelism (0 = all at once)")
3940
flags.String("update-delay", "0s", "delay between task updates (0s = none)")

cmd/swarmctl/service/flagparser/resource.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,32 @@ func parseResource(flags *pflag.FlagSet, spec *api.ServiceSpec) error {
114114
}
115115
}
116116

117+
if flags.Changed("ulimit") {
118+
container := spec.Task.GetContainer()
119+
if container == nil {
120+
return nil
121+
}
122+
123+
ulimits, err := flags.GetStringSlice("ulimit")
124+
if err != nil {
125+
return err
126+
}
127+
128+
container.Ulimits = make([]*api.ContainerSpec_Ulimit, len(ulimits))
129+
130+
for i, ulimit := range ulimits {
131+
parsed, err := units.ParseUlimit(ulimit)
132+
if err != nil {
133+
return err
134+
}
135+
136+
container.Ulimits[i] = &api.ContainerSpec_Ulimit{
137+
Name: parsed.Name,
138+
Soft: parsed.Soft,
139+
Hard: parsed.Hard,
140+
}
141+
}
142+
}
143+
117144
return nil
118145
}

0 commit comments

Comments
 (0)