From 77420b1bd624e30d32ae5b0956ed246fff17452f Mon Sep 17 00:00:00 2001 From: Conor Mongey Date: Fri, 20 Apr 2018 10:35:49 +0100 Subject: [PATCH] Add Ulimits to containers (#35) * Add Ulimits * added tests --- docker/resource_docker_container.go | 25 ++++++++++++++ docker/resource_docker_container_funcs.go | 22 +++++++++++++ docker/resource_docker_container_test.go | 40 +++++++++++++++++++++++ website/docs/r/container.html.markdown | 13 ++++++++ 4 files changed, 100 insertions(+) diff --git a/docker/resource_docker_container.go b/docker/resource_docker_container.go index 0603d76c..f8932b8a 100644 --- a/docker/resource_docker_container.go +++ b/docker/resource_docker_container.go @@ -250,6 +250,31 @@ func resourceDockerContainer() *schema.Resource { }, }, + "ulimit": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "soft": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "hard": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + }, + }, + }, + "env": &schema.Schema{ Type: schema.TypeSet, Optional: true, diff --git a/docker/resource_docker_container_funcs.go b/docker/resource_docker_container_funcs.go index 4480b0f0..f9abd674 100644 --- a/docker/resource_docker_container_funcs.go +++ b/docker/resource_docker_container_funcs.go @@ -83,6 +83,10 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err extraHosts = extraHostsSetToDockerExtraHosts(v.(*schema.Set)) } + extraUlimits := []dc.ULimit{} + if v, ok := d.GetOk("ulimit"); ok { + extraUlimits = ulimitsToDockerUlimits(v.(*schema.Set)) + } volumes := map[string]struct{}{} binds := []string{} volumesFrom := []string{} @@ -125,6 +129,9 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err if len(volumesFrom) != 0 { hostConfig.VolumesFrom = volumesFrom } + if len(extraUlimits) != 0 { + hostConfig.Ulimits = extraUlimits + } if v, ok := d.GetOk("capabilities"); ok { for _, capInt := range v.(*schema.Set).List() { @@ -426,6 +433,21 @@ func portSetToDockerPorts(ports *schema.Set) (map[dc.Port]struct{}, map[dc.Port] return retExposedPorts, retPortBindings } +func ulimitsToDockerUlimits(extraUlimits *schema.Set) []dc.ULimit { + retExtraUlimits := []dc.ULimit{} + + for _, ulimitInt := range extraUlimits.List() { + ulimits := ulimitInt.(map[string]interface{}) + u := dc.ULimit{ + Name: ulimits["name"].(string), + Soft: int64(ulimits["soft"].(int)), + Hard: int64(ulimits["hard"].(int)), + } + retExtraUlimits = append(retExtraUlimits, u) + } + + return retExtraUlimits +} func extraHostsSetToDockerExtraHosts(extraHosts *schema.Set) []string { retExtraHosts := []string{} diff --git a/docker/resource_docker_container_test.go b/docker/resource_docker_container_test.go index 48e31c44..9de5e556 100644 --- a/docker/resource_docker_container_test.go +++ b/docker/resource_docker_container_test.go @@ -210,6 +210,34 @@ func TestAccDockerContainer_customized(t *testing.T) { return fmt.Errorf("Container is not connected to the right user defined network: test") } + if len(c.HostConfig.Ulimits) != 2 { + return fmt.Errorf("Container doesn't have 2 ulimits") + } + + if c.HostConfig.Ulimits[0].Name != "nproc" { + return fmt.Errorf("Container doesn't have a nproc ulimit") + } + + if c.HostConfig.Ulimits[0].Hard != 1024 { + return fmt.Errorf("Container doesn't have a correct nproc hard limit") + } + + if c.HostConfig.Ulimits[0].Soft != 512 { + return fmt.Errorf("Container doesn't have a correct mem nproc limit") + } + + if c.HostConfig.Ulimits[1].Name != "nofile" { + return fmt.Errorf("Container doesn't have a nofile ulimit") + } + + if c.HostConfig.Ulimits[1].Hard != 262144 { + return fmt.Errorf("Container doesn't have a correct nofile hard limit") + } + + if c.HostConfig.Ulimits[1].Soft != 200000 { + return fmt.Errorf("Container doesn't have a correct nofile soft limit") + } + return nil } @@ -467,6 +495,18 @@ resource "docker_container" "foo" { host = "testhost2" ip = "10.0.2.0" } + + ulimit { + name = "nproc" + hard = 1024 + soft = 512 + } + + ulimit { + name = "nofile" + hard = 262144 + soft = 200000 + } } resource "docker_network" "test_network" { diff --git a/website/docs/r/container.html.markdown b/website/docs/r/container.html.markdown index b3290f7c..9bc64ae8 100644 --- a/website/docs/r/container.html.markdown +++ b/website/docs/r/container.html.markdown @@ -84,6 +84,8 @@ The following arguments are supported: container is. * `destroy_grace_seconds` - (Optional, int) If defined will attempt to stop the container before destroying. Container will be destroyed after `n` seconds or on successful stop. * `upload` - (Optional, block) See [File Upload](#upload) below for details. +* `ulimit` - (Optional, block) See [Ulimits](#ulimits) below for + details. ### Capabilities @@ -180,6 +182,17 @@ the following: container to access the device. Defaults to `rwm`. + +### Ulimits + +`ulimit` is a block within the configuration that can be repeated to specify +the extra ulimits for the container. Each `ulimit` block supports +the following: + +* `name` - (Required, string) +* `soft` - (Required, int) +* `hard` - (Required, int) + ## Attributes Reference The following attributes are exported: