From 0ded14f160af4e99b4f47b0473e4b85dc4358690 Mon Sep 17 00:00:00 2001 From: ryane Date: Mon, 26 Oct 2015 17:24:48 -0400 Subject: [PATCH 1/8] entrypoint support for docker_container resource --- .../docker/resource_docker_container.go | 7 +++ .../docker/resource_docker_container_funcs.go | 4 ++ .../docker/resource_docker_container_test.go | 49 ++++++++++++++++++- .../docker/r/container.html.markdown | 5 ++ 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go index 59e65b9c1672..4fe63650edf2 100644 --- a/builtin/providers/docker/resource_docker_container.go +++ b/builtin/providers/docker/resource_docker_container.go @@ -71,6 +71,13 @@ func resourceDockerContainer() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, + "entrypoint": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dns": &schema.Schema{ Type: schema.TypeSet, Optional: true, diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index aa74a4e1d81c..24df6949061f 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -54,6 +54,10 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err createOpts.Config.Cmd = stringListToStringSlice(v.([]interface{})) } + if v, ok := d.GetOk("entrypoint"); ok { + createOpts.Config.Entrypoint = stringListToStringSlice(v.([]interface{})) + } + exposedPorts := map[dc.Port]struct{}{} portBindings := map[dc.Port][]dc.PortBinding{} diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go index 29ecc4bb3f9e..e888c67da7d3 100644 --- a/builtin/providers/docker/resource_docker_container_test.go +++ b/builtin/providers/docker/resource_docker_container_test.go @@ -10,6 +10,7 @@ import ( ) func TestAccDockerContainer_basic(t *testing.T) { + var c dc.Container resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -17,14 +18,42 @@ func TestAccDockerContainer_basic(t *testing.T) { resource.TestStep{ Config: testAccDockerContainerConfig, Check: resource.ComposeTestCheckFunc( - testAccContainerRunning("docker_container.foo"), + testAccContainerRunning("docker_container.foo", &c), ), }, }, }) } -func testAccContainerRunning(n string) resource.TestCheckFunc { +func TestAccDockerContainer_entrypoint(t *testing.T) { + var c dc.Container + + testCheck := func(*terraform.State) error { + if len(c.Config.Entrypoint) < 3 || + (c.Config.Entrypoint[0] != "/bin/bash" && + c.Config.Entrypoint[1] != "-c" && + c.Config.Entrypoint[2] != "ping localhost") { + return fmt.Errorf("Container wrong entrypoint: %s", c.Config.Entrypoint) + } + return nil + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDockerContainerEntrypointConfig, + Check: resource.ComposeTestCheckFunc( + testAccContainerRunning("docker_container.foo", &c), + testCheck, + ), + }, + }, + }) +} + +func testAccContainerRunning(n string, container *dc.Container) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -43,6 +72,11 @@ func testAccContainerRunning(n string) resource.TestCheckFunc { for _, c := range containers { if c.ID == rs.Primary.ID { + inspected, err := client.InspectContainer(c.ID) + if err != nil { + return fmt.Errorf("Container could not be inspected: %s", err) + } + *container = *inspected return nil } } @@ -61,3 +95,14 @@ resource "docker_container" "foo" { image = "${docker_image.foo.latest}" } ` +const testAccDockerContainerEntrypointConfig = ` +resource "docker_image" "foo" { + name = "nginx:latest" +} + +resource "docker_container" "foo" { + name = "tf-test" + image = "${docker_image.foo.latest}" + entrypoint = ["/bin/bash", "-c", "ping localhost"] +} +` diff --git a/website/source/docs/providers/docker/r/container.html.markdown b/website/source/docs/providers/docker/r/container.html.markdown index 91a4714b7ace..f1f9707bf17e 100644 --- a/website/source/docs/providers/docker/r/container.html.markdown +++ b/website/source/docs/providers/docker/r/container.html.markdown @@ -37,6 +37,11 @@ The following arguments are supported: * `command` - (Optional, list of strings) The command to use to start the container. For example, to run `/usr/bin/myprogram -f baz.conf` set the command to be `["/usr/bin/myprogram", "-f", "baz.conf"]`. +* `entrypoint` - (Optional, list of strings) The command to use as the + Entrypoint for the container. The Entrypoint allows you to configure a + container to run as an executable. For example, to run `/usr/bin/myprogram` + when starting a container, set the entrypoint to be + `["/usr/bin/myprogram"]`. * `dns` - (Optional, set of strings) Set of DNS servers. * `env` - (Optional, set of strings) Environmental variables to set. * `links` - (Optional, set of strings) Set of links for link based From 17d185808e5e83cde6d4a535b20e4a4fc6770b00 Mon Sep 17 00:00:00 2001 From: ryane Date: Tue, 27 Oct 2015 12:08:57 -0400 Subject: [PATCH 2/8] restart policy support for docker_container --- .../docker/resource_docker_container.go | 22 +++++++++++++++++++ .../docker/resource_docker_container_funcs.go | 4 ++++ .../docker/resource_docker_container_test.go | 17 +++++++++++--- .../docker/r/container.html.markdown | 4 ++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go index 4fe63650edf2..7d2fa34cdc26 100644 --- a/builtin/providers/docker/resource_docker_container.go +++ b/builtin/providers/docker/resource_docker_container.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" + "regexp" ) func resourceDockerContainer() *schema.Resource { @@ -92,6 +93,27 @@ func resourceDockerContainer() *schema.Resource { ForceNew: true, }, + "restart": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: "no", + ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { + value := v.(string) + if !regexp.MustCompile(`^(no|on-failure|always)$`).MatchString(value) { + es = append(es, fmt.Errorf( + "%q must be one of \"no\", \"on-failure\", or \"always\"", k)) + } + return + }, + }, + + "max_retry_count": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "volumes": &schema.Schema{ Type: schema.TypeSet, Optional: true, diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index 24df6949061f..800f0f8abf92 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -95,6 +95,10 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err hostConfig := &dc.HostConfig{ Privileged: d.Get("privileged").(bool), PublishAllPorts: d.Get("publish_all_ports").(bool), + RestartPolicy: dc.RestartPolicy{ + Name: d.Get("restart").(string), + MaximumRetryCount: d.Get("max_retry_count").(int), + }, } if len(portBindings) != 0 { diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go index e888c67da7d3..0d0fe734fcda 100644 --- a/builtin/providers/docker/resource_docker_container_test.go +++ b/builtin/providers/docker/resource_docker_container_test.go @@ -25,7 +25,7 @@ func TestAccDockerContainer_basic(t *testing.T) { }) } -func TestAccDockerContainer_entrypoint(t *testing.T) { +func TestAccDockerContainer_customized(t *testing.T) { var c dc.Container testCheck := func(*terraform.State) error { @@ -35,6 +35,15 @@ func TestAccDockerContainer_entrypoint(t *testing.T) { c.Config.Entrypoint[2] != "ping localhost") { return fmt.Errorf("Container wrong entrypoint: %s", c.Config.Entrypoint) } + + if c.HostConfig.RestartPolicy.Name == "on-failure" { + if c.HostConfig.RestartPolicy.MaximumRetryCount != 5 { + return fmt.Errorf("Container has wrong restart policy max retry count: %d", c.HostConfig.RestartPolicy.MaximumRetryCount) + } + } else { + return fmt.Errorf("Container has wrong restart policy: %s", c.HostConfig.RestartPolicy.Name) + } + return nil } @@ -43,7 +52,7 @@ func TestAccDockerContainer_entrypoint(t *testing.T) { Providers: testAccProviders, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccDockerContainerEntrypointConfig, + Config: testAccDockerContainerCustomizedConfig, Check: resource.ComposeTestCheckFunc( testAccContainerRunning("docker_container.foo", &c), testCheck, @@ -95,7 +104,7 @@ resource "docker_container" "foo" { image = "${docker_image.foo.latest}" } ` -const testAccDockerContainerEntrypointConfig = ` +const testAccDockerContainerCustomizedConfig = ` resource "docker_image" "foo" { name = "nginx:latest" } @@ -104,5 +113,7 @@ resource "docker_container" "foo" { name = "tf-test" image = "${docker_image.foo.latest}" entrypoint = ["/bin/bash", "-c", "ping localhost"] + restart = "on-failure" + max_retry_count = 5 } ` diff --git a/website/source/docs/providers/docker/r/container.html.markdown b/website/source/docs/providers/docker/r/container.html.markdown index f1f9707bf17e..91c5a8659d7d 100644 --- a/website/source/docs/providers/docker/r/container.html.markdown +++ b/website/source/docs/providers/docker/r/container.html.markdown @@ -48,6 +48,10 @@ The following arguments are supported: connectivity between containers that are running on the same host. * `hostname` - (Optional, string) Hostname of the container. * `domainname` - (Optional, string) Domain name of the container. +* `restart` - (Optional, string) The restart policy for the container. Must be + one of "no", "on-failure", "always". +* `max_retry_count` - (Optional, int) The maximum amount of times to an attempt + a restart when `restart` is set to "on-failure" * `must_run` - (Optional, bool) If true, then the Docker container will be kept running. If false, then as long as the container exists, Terraform assumes it is successful. From 6842c32d03b5a48fa066efe1c00c3a01a903354b Mon Sep 17 00:00:00 2001 From: ryane Date: Tue, 27 Oct 2015 19:53:49 -0400 Subject: [PATCH 3/8] add basic runtime constraints to docker_container --- .../docker/resource_docker_container.go | 18 ++++++++++++++ .../docker/resource_docker_container_funcs.go | 24 +++++++++++++++++++ .../docker/resource_docker_container_test.go | 14 +++++++++++ .../docker/r/container.html.markdown | 4 ++++ 4 files changed, 60 insertions(+) diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go index 7d2fa34cdc26..48eac9a4d9c3 100644 --- a/builtin/providers/docker/resource_docker_container.go +++ b/builtin/providers/docker/resource_docker_container.go @@ -171,6 +171,24 @@ func resourceDockerContainer() *schema.Resource { Optional: true, ForceNew: true, }, + + "memory": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "memory_swap": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "cpu_shares": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, }, } } diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index 800f0f8abf92..0f1a9d9e0dc9 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -120,6 +120,30 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err hostConfig.Links = stringSetToStringSlice(v.(*schema.Set)) } + if v, ok := d.GetOk("memory"); ok { + memory := int64(v.(int)) + if memory > 0 { + hostConfig.Memory = memory * 1024 * 1024 + } + } + + if v, ok := d.GetOk("memory_swap"); ok { + swap := int64(v.(int)) + if swap != 0 { + if swap > 0 { // only convert positive #s to bytes + swap = swap * 1024 * 1024 + } + hostConfig.MemorySwap = swap + } + } + + if v, ok := d.GetOk("cpu_shares"); ok { + shares := int64(v.(int)) + if shares > 0 { + hostConfig.CPUShares = shares + } + } + creationTime = time.Now() if err := client.StartContainer(retContainer.ID, hostConfig); err != nil { return fmt.Errorf("Unable to start container: %s", err) diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go index 0d0fe734fcda..1402f129f348 100644 --- a/builtin/providers/docker/resource_docker_container_test.go +++ b/builtin/providers/docker/resource_docker_container_test.go @@ -44,6 +44,17 @@ func TestAccDockerContainer_customized(t *testing.T) { return fmt.Errorf("Container has wrong restart policy: %s", c.HostConfig.RestartPolicy.Name) } + if c.HostConfig.Memory != (128 * 1024 * 1024) { + return fmt.Errorf("Container has wrong memory setting: %d", c.HostConfig.Memory) + } + + if c.HostConfig.MemorySwap != (128 * 1024 * 1024) { + return fmt.Errorf("Container has wrong memory swap setting: %d", c.HostConfig.Memory) + } + + if c.HostConfig.CPUShares != 512 { + return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares) + } return nil } @@ -115,5 +126,8 @@ resource "docker_container" "foo" { entrypoint = ["/bin/bash", "-c", "ping localhost"] restart = "on-failure" max_retry_count = 5 + memory = 128 + memory_swap = 128 + cpu_shares = 512 } ` diff --git a/website/source/docs/providers/docker/r/container.html.markdown b/website/source/docs/providers/docker/r/container.html.markdown index 91c5a8659d7d..c1a728f1a683 100644 --- a/website/source/docs/providers/docker/r/container.html.markdown +++ b/website/source/docs/providers/docker/r/container.html.markdown @@ -59,6 +59,10 @@ The following arguments are supported: * `privileged` - (Optional, bool) Run container in privileged mode. * `publish_all_ports` - (Optional, bool) Publish all ports of the container. * `volumes` - (Optional) See [Volumes](#volumes) below for details. +* `memory` - (Optional, int) The memory limit for the container in MBs. +* `memory_swap` - (Optional, int) The total memory limit (memory + swap) for the + container in MBs. +* `cpu_shares` - (Optional, int) CPU shares (relative weight) for the container. ## Ports From 4531866d8da30aba88dfc7498648c1c15d15c756 Mon Sep 17 00:00:00 2001 From: ryane Date: Tue, 3 Nov 2015 15:20:58 -0500 Subject: [PATCH 4/8] add label support to docker container resource --- .../providers/docker/resource_docker_container.go | 6 ++++++ .../docker/resource_docker_container_funcs.go | 12 ++++++++++++ .../docker/resource_docker_container_test.go | 9 +++++++++ .../docs/providers/docker/r/container.html.markdown | 1 + 4 files changed, 28 insertions(+) diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go index 48eac9a4d9c3..0a29ab73d8fc 100644 --- a/builtin/providers/docker/resource_docker_container.go +++ b/builtin/providers/docker/resource_docker_container.go @@ -172,6 +172,12 @@ func resourceDockerContainer() *schema.Resource { ForceNew: true, }, + "labels": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + }, + "memory": &schema.Schema{ Type: schema.TypeInt, Optional: true, diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index 0f1a9d9e0dc9..4a617480e863 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -82,6 +82,10 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err createOpts.Config.Volumes = volumes } + if v, ok := d.GetOk("labels"); ok { + createOpts.Config.Labels = mapLabels(v.(map[string]interface{})) + } + var retContainer *dc.Container if retContainer, err = client.CreateContainer(createOpts); err != nil { return fmt.Errorf("Unable to create container: %s", err) @@ -255,6 +259,14 @@ func stringSetToStringSlice(stringSet *schema.Set) []string { return ret } +func mapLabels(labels map[string]interface{}) map[string]string { + mapped := make(map[string]string, len(labels)) + for k, v := range labels { + mapped[k] = v.(string) + } + return mapped +} + func fetchDockerContainer(name string, client *dc.Client) (*dc.APIContainers, error) { apiContainers, err := client.ListContainers(dc.ListContainersOptions{All: true}) diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go index 1402f129f348..e194d1a10ca3 100644 --- a/builtin/providers/docker/resource_docker_container_test.go +++ b/builtin/providers/docker/resource_docker_container_test.go @@ -55,6 +55,11 @@ func TestAccDockerContainer_customized(t *testing.T) { if c.HostConfig.CPUShares != 512 { return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares) } + + if c.Config.Labels["env"] != "prod" || c.Config.Labels["role"] != "test" { + return fmt.Errorf("Container does not have the correct labels") + } + return nil } @@ -129,5 +134,9 @@ resource "docker_container" "foo" { memory = 128 memory_swap = 128 cpu_shares = 512 + labels { + env = "prod" + role = "test" + } } ` diff --git a/website/source/docs/providers/docker/r/container.html.markdown b/website/source/docs/providers/docker/r/container.html.markdown index c1a728f1a683..b83387aef062 100644 --- a/website/source/docs/providers/docker/r/container.html.markdown +++ b/website/source/docs/providers/docker/r/container.html.markdown @@ -44,6 +44,7 @@ The following arguments are supported: `["/usr/bin/myprogram"]`. * `dns` - (Optional, set of strings) Set of DNS servers. * `env` - (Optional, set of strings) Environmental variables to set. +* `labels` - (Optional) Key/value pairs to set as labels on the container. * `links` - (Optional, set of strings) Set of links for link based connectivity between containers that are running on the same host. * `hostname` - (Optional, string) Hostname of the container. From 72c86a62c0a22fa6faf3e1effbbcb3a1e4bd0ad3 Mon Sep 17 00:00:00 2001 From: ryane Date: Wed, 4 Nov 2015 12:42:55 -0500 Subject: [PATCH 5/8] support for log driver + config in docker container --- .../docker/resource_docker_container.go | 21 +++++++++++++++++++ .../docker/resource_docker_container_funcs.go | 15 +++++++++---- .../docker/resource_docker_container_test.go | 17 +++++++++++++++ .../docker/r/container.html.markdown | 4 ++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go index 0a29ab73d8fc..92331fc795c6 100644 --- a/builtin/providers/docker/resource_docker_container.go +++ b/builtin/providers/docker/resource_docker_container.go @@ -195,6 +195,27 @@ func resourceDockerContainer() *schema.Resource { Optional: true, ForceNew: true, }, + + "log_driver": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: "json-file", + ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { + value := v.(string) + if !regexp.MustCompile(`^(json-file|syslog|journald|gelf|fluentd)$`).MatchString(value) { + es = append(es, fmt.Errorf( + "%q must be one of \"json-file\", \"syslog\", \"journald\", \"gelf\", or \"fluentd\"", k)) + } + return + }, + }, + + "log_opts": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + }, }, } } diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index 4a617480e863..443f9ef3fba8 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -83,7 +83,7 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err } if v, ok := d.GetOk("labels"); ok { - createOpts.Config.Labels = mapLabels(v.(map[string]interface{})) + createOpts.Config.Labels = mapTypeMapValsToString(v.(map[string]interface{})) } var retContainer *dc.Container @@ -103,6 +103,9 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err Name: d.Get("restart").(string), MaximumRetryCount: d.Get("max_retry_count").(int), }, + LogConfig: dc.LogConfig{ + Type: d.Get("log_driver").(string), + }, } if len(portBindings) != 0 { @@ -148,6 +151,10 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err } } + if v, ok := d.GetOk("log_opts"); ok { + hostConfig.LogConfig.Config = mapTypeMapValsToString(v.(map[string]interface{})) + } + creationTime = time.Now() if err := client.StartContainer(retContainer.ID, hostConfig); err != nil { return fmt.Errorf("Unable to start container: %s", err) @@ -259,9 +266,9 @@ func stringSetToStringSlice(stringSet *schema.Set) []string { return ret } -func mapLabels(labels map[string]interface{}) map[string]string { - mapped := make(map[string]string, len(labels)) - for k, v := range labels { +func mapTypeMapValsToString(typeMap map[string]interface{}) map[string]string { + mapped := make(map[string]string, len(typeMap)) + for k, v := range typeMap { mapped[k] = v.(string) } return mapped diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go index e194d1a10ca3..4b3dfce9a2c8 100644 --- a/builtin/providers/docker/resource_docker_container_test.go +++ b/builtin/providers/docker/resource_docker_container_test.go @@ -60,6 +60,18 @@ func TestAccDockerContainer_customized(t *testing.T) { return fmt.Errorf("Container does not have the correct labels") } + if c.HostConfig.LogConfig.Type != "json-file" { + return fmt.Errorf("Container does not have the correct log config: %s", c.HostConfig.LogConfig.Type) + } + + if c.HostConfig.LogConfig.Config["max-size"] != "10m" { + return fmt.Errorf("Container does not have the correct max-size log option: %v", c.HostConfig.LogConfig.Config["max-size"]) + } + + if c.HostConfig.LogConfig.Config["max-file"] != "20" { + return fmt.Errorf("Container does not have the correct max-file log option: %v", c.HostConfig.LogConfig.Config["max-file"]) + } + return nil } @@ -138,5 +150,10 @@ resource "docker_container" "foo" { env = "prod" role = "test" } + log_driver = "json-file" + log_opts = { + max-size = "10m" + max-file = 20 + } } ` diff --git a/website/source/docs/providers/docker/r/container.html.markdown b/website/source/docs/providers/docker/r/container.html.markdown index b83387aef062..920288eb25b0 100644 --- a/website/source/docs/providers/docker/r/container.html.markdown +++ b/website/source/docs/providers/docker/r/container.html.markdown @@ -64,6 +64,10 @@ The following arguments are supported: * `memory_swap` - (Optional, int) The total memory limit (memory + swap) for the container in MBs. * `cpu_shares` - (Optional, int) CPU shares (relative weight) for the container. +* `log_driver` - (Optional, string) The logging driver to use for the container. + Defaults to "json-file". +* `log_opts` - (Optional) Key/value pairs to use as options for the logging + driver. ## Ports From 1f739d31da0987622a02e476845e672422fa40a9 Mon Sep 17 00:00:00 2001 From: ryane Date: Wed, 4 Nov 2015 15:46:24 -0500 Subject: [PATCH 6/8] fix resource constraint specs --- .../docker/resource_docker_container_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go index 4b3dfce9a2c8..df8ba0cb8adc 100644 --- a/builtin/providers/docker/resource_docker_container_test.go +++ b/builtin/providers/docker/resource_docker_container_test.go @@ -44,15 +44,15 @@ func TestAccDockerContainer_customized(t *testing.T) { return fmt.Errorf("Container has wrong restart policy: %s", c.HostConfig.RestartPolicy.Name) } - if c.HostConfig.Memory != (128 * 1024 * 1024) { + if c.HostConfig.Memory != (512 * 1024 * 1024) { return fmt.Errorf("Container has wrong memory setting: %d", c.HostConfig.Memory) } - if c.HostConfig.MemorySwap != (128 * 1024 * 1024) { - return fmt.Errorf("Container has wrong memory swap setting: %d", c.HostConfig.Memory) + if c.HostConfig.MemorySwap != (2048 * 1024 * 1024) { + return fmt.Errorf("Container has wrong memory swap setting: %d", c.HostConfig.MemorySwap) } - if c.HostConfig.CPUShares != 512 { + if c.HostConfig.CPUShares != 32 { return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares) } @@ -143,9 +143,9 @@ resource "docker_container" "foo" { entrypoint = ["/bin/bash", "-c", "ping localhost"] restart = "on-failure" max_retry_count = 5 - memory = 128 - memory_swap = 128 - cpu_shares = 512 + memory = 512 + memory_swap = 2048 + cpu_shares = 32 labels { env = "prod" role = "test" From b5ae355a990720fa78a625d4b623420c5e11de55 Mon Sep 17 00:00:00 2001 From: ryane Date: Wed, 4 Nov 2015 15:46:41 -0500 Subject: [PATCH 7/8] include hostconfig when creating docker_container --- .../docker/resource_docker_container_funcs.go | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index 443f9ef3fba8..2b0259bc96c1 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -86,16 +86,6 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err createOpts.Config.Labels = mapTypeMapValsToString(v.(map[string]interface{})) } - var retContainer *dc.Container - if retContainer, err = client.CreateContainer(createOpts); err != nil { - return fmt.Errorf("Unable to create container: %s", err) - } - if retContainer == nil { - return fmt.Errorf("Returned container is nil") - } - - d.SetId(retContainer.ID) - hostConfig := &dc.HostConfig{ Privileged: d.Get("privileged").(bool), PublishAllPorts: d.Get("publish_all_ports").(bool), @@ -155,6 +145,18 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err hostConfig.LogConfig.Config = mapTypeMapValsToString(v.(map[string]interface{})) } + createOpts.HostConfig = hostConfig + + var retContainer *dc.Container + if retContainer, err = client.CreateContainer(createOpts); err != nil { + return fmt.Errorf("Unable to create container: %s", err) + } + if retContainer == nil { + return fmt.Errorf("Returned container is nil") + } + + d.SetId(retContainer.ID) + creationTime = time.Now() if err := client.StartContainer(retContainer.ID, hostConfig); err != nil { return fmt.Errorf("Unable to start container: %s", err) From 4fc60c9f89cc4ebad933bbffb0f243eb9213c183 Mon Sep 17 00:00:00 2001 From: ryane Date: Mon, 9 Nov 2015 19:36:23 -0500 Subject: [PATCH 8/8] docker: improve validation of runtime constraints --- .../docker/resource_docker_container.go | 21 +++++++++++++++++++ .../docker/resource_docker_container_funcs.go | 18 +++++----------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go index 92331fc795c6..242462e1a759 100644 --- a/builtin/providers/docker/resource_docker_container.go +++ b/builtin/providers/docker/resource_docker_container.go @@ -182,18 +182,39 @@ func resourceDockerContainer() *schema.Resource { Type: schema.TypeInt, Optional: true, ForceNew: true, + ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { + value := v.(int) + if value < 0 { + es = append(es, fmt.Errorf("%q must be greater than or equal to 0", k)) + } + return + }, }, "memory_swap": &schema.Schema{ Type: schema.TypeInt, Optional: true, ForceNew: true, + ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { + value := v.(int) + if value < -1 { + es = append(es, fmt.Errorf("%q must be greater than or equal to -1", k)) + } + return + }, }, "cpu_shares": &schema.Schema{ Type: schema.TypeInt, Optional: true, ForceNew: true, + ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { + value := v.(int) + if value < 0 { + es = append(es, fmt.Errorf("%q must be greater than or equal to 0", k)) + } + return + }, }, "log_driver": &schema.Schema{ diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go index 2b0259bc96c1..b0c262dfcd19 100644 --- a/builtin/providers/docker/resource_docker_container_funcs.go +++ b/builtin/providers/docker/resource_docker_container_funcs.go @@ -118,27 +118,19 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err } if v, ok := d.GetOk("memory"); ok { - memory := int64(v.(int)) - if memory > 0 { - hostConfig.Memory = memory * 1024 * 1024 - } + hostConfig.Memory = int64(v.(int)) * 1024 * 1024 } if v, ok := d.GetOk("memory_swap"); ok { swap := int64(v.(int)) - if swap != 0 { - if swap > 0 { // only convert positive #s to bytes - swap = swap * 1024 * 1024 - } - hostConfig.MemorySwap = swap + if swap > 0 { + swap = swap * 1024 * 1024 } + hostConfig.MemorySwap = swap } if v, ok := d.GetOk("cpu_shares"); ok { - shares := int64(v.(int)) - if shares > 0 { - hostConfig.CPUShares = shares - } + hostConfig.CPUShares = int64(v.(int)) } if v, ok := d.GetOk("log_opts"); ok {