Adds container healthcheck.

This commit is contained in:
Manuel Vogel 2018-10-26 07:37:45 +02:00
commit f689619b2d
No known key found for this signature in database
GPG key ID: 533006C7B61DB1CE
5 changed files with 138 additions and 0 deletions

View file

@ -3,6 +3,7 @@
IMPROVEMENTS
* Adds labels for `network`, `volume` and `secret` to support docker stacks. [[#92](https://github.com/terraform-providers/terraform-provider-docker/pull/92)]
* Adds `rm` and `attach` options to execute short-lived containers [GH-43] and [[#106](https://github.com/terraform-providers/terraform-provider-docker/pull/106)]
* Adds container healthcheck[[#93](https://github.com/terraform-providers/terraform-provider-docker/pull/93)]
BUG FIXES
* Fixes that new network were appended to the default bridge [GH-10]

View file

@ -494,6 +494,51 @@ func resourceDockerContainer() *schema.Resource {
},
},
},
"healthcheck": &schema.Schema{
Type: schema.TypeList,
Description: "A test to perform to check that the container is healthy",
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"test": &schema.Schema{
Type: schema.TypeList,
Description: "The test to perform as list",
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"interval": &schema.Schema{
Type: schema.TypeString,
Description: "Time between running the check (ms|s|m|h)",
Optional: true,
Default: "0s",
ValidateFunc: validateDurationGeq0(),
},
"timeout": &schema.Schema{
Type: schema.TypeString,
Description: "Maximum time to allow one check to run (ms|s|m|h)",
Optional: true,
Default: "0s",
ValidateFunc: validateDurationGeq0(),
},
"start_period": &schema.Schema{
Type: schema.TypeString,
Description: "Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)",
Optional: true,
Default: "0s",
ValidateFunc: validateDurationGeq0(),
},
"retries": &schema.Schema{
Type: schema.TypeInt,
Description: "Consecutive failures needed to report unhealthy",
Optional: true,
Default: 0,
ValidateFunc: validateIntegerGeqThan(0),
},
},
},
},
},
}
}

View file

@ -112,6 +112,30 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err
config.Labels = mapTypeMapValsToString(v.(map[string]interface{}))
}
if value, ok := d.GetOk("healthcheck"); ok {
config.Healthcheck = &container.HealthConfig{}
if len(value.([]interface{})) > 0 {
for _, rawHealthCheck := range value.([]interface{}) {
rawHealthCheck := rawHealthCheck.(map[string]interface{})
if testCommand, ok := rawHealthCheck["test"]; ok {
config.Healthcheck.Test = stringListToStringSlice(testCommand.([]interface{}))
}
if rawInterval, ok := rawHealthCheck["interval"]; ok {
config.Healthcheck.Interval, _ = time.ParseDuration(rawInterval.(string))
}
if rawTimeout, ok := rawHealthCheck["timeout"]; ok {
config.Healthcheck.Timeout, _ = time.ParseDuration(rawTimeout.(string))
}
if rawStartPeriod, ok := rawHealthCheck["start_period"]; ok {
config.Healthcheck.StartPeriod, _ = time.ParseDuration(rawStartPeriod.(string))
}
if rawRetries, ok := rawHealthCheck["retries"]; ok {
config.Healthcheck.Retries, _ = rawRetries.(int)
}
}
}
}
hostConfig := &container.HostConfig{
Privileged: d.Get("privileged").(bool),
PublishAllPorts: d.Get("publish_all_ports").(bool),

View file

@ -4,6 +4,7 @@ import (
"archive/tar"
"bytes"
"fmt"
"reflect"
"strconv"
"strings"
"testing"
@ -765,6 +766,41 @@ func TestAccDockerContainer_exitcode(t *testing.T) {
})
}
func TestAccDockerContainer_healthcheck(t *testing.T) {
var c types.ContainerJSON
testCheck := func(*terraform.State) error {
if !reflect.DeepEqual(c.Config.Healthcheck.Test, []string{"CMD", "/bin/true"}) {
return fmt.Errorf("Container doesn't have a correct healthcheck test")
}
if c.Config.Healthcheck.Interval != 30000000000 {
return fmt.Errorf("Container doesn't have a correct healthcheck interval")
}
if c.Config.Healthcheck.Timeout != 5000000000 {
return fmt.Errorf("Container doesn't have a correct healthcheck timeout")
}
if c.Config.Healthcheck.StartPeriod != 15000000000 {
return fmt.Errorf("Container doesn't have a correct healthcheck retries")
}
if c.Config.Healthcheck.Retries != 10 {
return fmt.Errorf("Container doesn't have a correct healthcheck retries")
}
return nil
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDockerContainerHealthcheckConfig,
Check: resource.ComposeTestCheckFunc(
testAccContainerRunning("docker_container.foo", &c),
testCheck,
),
},
},
})
}
func testAccContainerRunning(n string, container *types.ContainerJSON) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
@ -1235,3 +1271,22 @@ resource "docker_container" "bar" {
network_alias = ["tftest-container-foo"]
}
`
const testAccDockerContainerHealthcheckConfig = `
resource "docker_image" "foo" {
name = "nginx:latest"
keep_locally = true
}
resource "docker_container" "foo" {
name = "tf-test"
image = "${docker_image.foo.latest}"
healthcheck {
test = ["CMD", "/bin/true"]
interval = "30s"
timeout = "5s"
start_period = "15s"
retries = 10
}
}
`

View file

@ -97,6 +97,7 @@ data is stored in them. See [the docker documentation][linkdoc] for more details
details.
* `pid_mode` - (Optional, string) The PID (Process) Namespace mode for the container. Either `container:<name|id>` or `host`.
* `userns_mode` - (Optional, string) Sets the usernamespace mode for the container when usernamespace remapping option is enabled.
* `healthcheck` - (Optional, block) See [Healthcheck](#healthcheck) below for details.
<a id="capabilities"></a>
### Capabilities
@ -204,6 +205,18 @@ the following:
* `soft` - (Required, int)
* `hard` - (Required, int)
<a id="healthcheck"></a>
### Healthcheck
`healthcheck` is a block within the configuration that can be repeated only **once** to specify the extra healthcheck configuration for the container. The `healthcheck` block is a test to perform to check that the container is healthy and supports the following:
* `test` - (Required, list of strings) Command to run to check health. For example, to run `curl -f http://localhost/health` set the
command to be `["CMD", "curl", "-f", "http://localhost/health"]`.
* `interval` - (Optional, string) Time between running the check `(ms|s|m|h)`. Default: `0s`.
* `timeout` - (Optional, string) Maximum time to allow one check to run `(ms|s|m|h)`. Default: `0s`.
* `start_period` - (Optional, string) Start period for the container to initialize before counting retries towards unstable `(ms|s|m|h)`. Default: `0s`.
* `retries` - (Optional, int) Consecutive failures needed to report unhealthy. Default: `0`.
## Attributes Reference
The following attributes are exported: