mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add ulimits support to services
Add Ulimits field to the ContainerSpec API type and wire it to Swarmkit. This is related to #40639. Signed-off-by: Albin Kerouanton <albin@akerouanton.name>
This commit is contained in:
parent
1fdb1033c4
commit
c76f380bea
7 changed files with 81 additions and 1 deletions
|
@ -97,10 +97,11 @@ func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
|
|||
}
|
||||
if versions.LessThan(cliVersion, "1.41") {
|
||||
if service.TaskTemplate.ContainerSpec != nil {
|
||||
// Capabilities for docker swarm services weren't
|
||||
// Capabilities and Ulimits for docker swarm services weren't
|
||||
// supported before API version 1.41
|
||||
service.TaskTemplate.ContainerSpec.CapabilityAdd = nil
|
||||
service.TaskTemplate.ContainerSpec.CapabilityDrop = nil
|
||||
service.TaskTemplate.ContainerSpec.Ulimits = nil
|
||||
}
|
||||
if service.TaskTemplate.Resources != nil && service.TaskTemplate.Resources.Limits != nil {
|
||||
// Limits.Pids not supported before API version 1.41
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/go-units"
|
||||
)
|
||||
|
||||
func TestAdjustForAPIVersion(t *testing.T) {
|
||||
|
@ -39,6 +40,13 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
|||
ConfigName: "configRuntime",
|
||||
},
|
||||
},
|
||||
Ulimits: []*units.Ulimit{
|
||||
{
|
||||
Name: "nofile",
|
||||
Soft: 100,
|
||||
Hard: 200,
|
||||
},
|
||||
},
|
||||
},
|
||||
Placement: &swarm.Placement{
|
||||
MaxReplicas: 222,
|
||||
|
@ -78,6 +86,10 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
|||
t.Error("MaxReplicas was stripped from spec")
|
||||
}
|
||||
|
||||
if len(spec.TaskTemplate.ContainerSpec.Ulimits) == 0 {
|
||||
t.Error("Ulimits were stripped from spec")
|
||||
}
|
||||
|
||||
// next, does calling this with an earlier version correctly strip fields?
|
||||
adjustForAPIVersion("1.29", spec)
|
||||
if spec.TaskTemplate.ContainerSpec.Sysctls != nil {
|
||||
|
@ -100,4 +112,8 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
|||
t.Error("MaxReplicas was not stripped from spec")
|
||||
}
|
||||
|
||||
if len(spec.TaskTemplate.ContainerSpec.Ulimits) != 0 {
|
||||
t.Error("Ulimits were not stripped from spec")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3306,6 +3306,22 @@ definitions:
|
|||
type: "string"
|
||||
example:
|
||||
- "CAP_NET_RAW"
|
||||
Ulimits:
|
||||
description: |
|
||||
A list of resource limits to set in the container. For example: `{"Name": "nofile", "Soft": 1024, "Hard": 2048}`"
|
||||
type: "array"
|
||||
items:
|
||||
type: "object"
|
||||
properties:
|
||||
Name:
|
||||
description: "Name of ulimit"
|
||||
type: "string"
|
||||
Soft:
|
||||
description: "Soft limit"
|
||||
type: "integer"
|
||||
Hard:
|
||||
description: "Hard limit"
|
||||
type: "integer"
|
||||
NetworkAttachmentSpec:
|
||||
description: |
|
||||
Read-only spec type for non-swarm containers attached to swarm overlay
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/go-units"
|
||||
)
|
||||
|
||||
// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)
|
||||
|
@ -75,4 +76,5 @@ type ContainerSpec struct {
|
|||
Sysctls map[string]string `json:",omitempty"`
|
||||
CapabilityAdd []string `json:",omitempty"`
|
||||
CapabilityDrop []string `json:",omitempty"`
|
||||
Ulimits []*units.Ulimit `json:",omitempty"`
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/docker/docker/api/types/container"
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
types "github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/go-units"
|
||||
swarmapi "github.com/docker/swarmkit/api"
|
||||
gogotypes "github.com/gogo/protobuf/types"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -39,6 +40,7 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
|
|||
Sysctls: c.Sysctls,
|
||||
CapabilityAdd: c.CapabilityAdd,
|
||||
CapabilityDrop: c.CapabilityDrop,
|
||||
Ulimits: ulimitsFromGRPC(c.Ulimits),
|
||||
}
|
||||
|
||||
if c.DNSConfig != nil {
|
||||
|
@ -267,6 +269,7 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
|
|||
Sysctls: c.Sysctls,
|
||||
CapabilityAdd: c.CapabilityAdd,
|
||||
CapabilityDrop: c.CapabilityDrop,
|
||||
Ulimits: ulimitsToGRPC(c.Ulimits),
|
||||
}
|
||||
|
||||
if c.DNSConfig != nil {
|
||||
|
@ -471,3 +474,31 @@ func isolationToGRPC(i container.Isolation) swarmapi.ContainerSpec_Isolation {
|
|||
}
|
||||
return swarmapi.ContainerIsolationDefault
|
||||
}
|
||||
|
||||
func ulimitsFromGRPC(u []*swarmapi.ContainerSpec_Ulimit) []*units.Ulimit {
|
||||
ulimits := make([]*units.Ulimit, len(u))
|
||||
|
||||
for i, ulimit := range u {
|
||||
ulimits[i] = &units.Ulimit{
|
||||
Name: ulimit.Name,
|
||||
Soft: ulimit.Soft,
|
||||
Hard: ulimit.Hard,
|
||||
}
|
||||
}
|
||||
|
||||
return ulimits
|
||||
}
|
||||
|
||||
func ulimitsToGRPC(u []*units.Ulimit) []*swarmapi.ContainerSpec_Ulimit {
|
||||
ulimits := make([]*swarmapi.ContainerSpec_Ulimit, len(u))
|
||||
|
||||
for i, ulimit := range u {
|
||||
ulimits[i] = &swarmapi.ContainerSpec_Ulimit{
|
||||
Name: ulimit.Name,
|
||||
Soft: ulimit.Soft,
|
||||
Hard: ulimit.Hard,
|
||||
}
|
||||
}
|
||||
|
||||
return ulimits
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
||||
clustertypes "github.com/docker/docker/daemon/cluster/provider"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/docker/go-units"
|
||||
netconst "github.com/docker/libnetwork/datastore"
|
||||
"github.com/docker/swarmkit/agent/exec"
|
||||
"github.com/docker/swarmkit/api"
|
||||
|
@ -438,6 +439,15 @@ func (c *containerConfig) resources() enginecontainer.Resources {
|
|||
resources.PidsLimit = &pidsLimit
|
||||
}
|
||||
|
||||
resources.Ulimits = make([]*units.Ulimit, len(c.spec().Ulimits))
|
||||
for i, ulimit := range c.spec().Ulimits {
|
||||
resources.Ulimits[i] = &units.Ulimit{
|
||||
Name: ulimit.Name,
|
||||
Soft: ulimit.Soft,
|
||||
Hard: ulimit.Hard,
|
||||
}
|
||||
}
|
||||
|
||||
// If no limits are specified let the engine use its defaults.
|
||||
//
|
||||
// TODO(aluzzardi): We might want to set some limits anyway otherwise
|
||||
|
|
|
@ -76,6 +76,10 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
single set of stats instead of waiting for two collection cycles to have 2 CPU stats over a 1 second period.
|
||||
* The `KernelMemory` field in `HostConfig.Resources` is now deprecated.
|
||||
* The `KernelMemory` field in `Info` is now deprecated.
|
||||
* `GET /services` now returns `Ulimits` as part of `ContainerSpec`.
|
||||
* `GET /services/{id}` now returns `Ulimits` as part of `ContainerSpec`.
|
||||
* `POST /services/create` now accepts `Ulimits` as part of `ContainerSpec`.
|
||||
* `POST /services/{id}/update` now accepts `Ulimits` as part of `ContainerSpec`.
|
||||
|
||||
## v1.40 API changes
|
||||
|
||||
|
|
Loading…
Reference in a new issue