mirror of
https://github.com/kreuzwerker/terraform-provider-docker.git
synced 2025-12-24 00:29:46 -05:00
feat: wait container healthy state (#467)
This commit is contained in:
parent
4eb65f64db
commit
e1cf4151a1
4 changed files with 58 additions and 4 deletions
|
|
@ -94,6 +94,8 @@ resource "docker_image" "ubuntu" {
|
|||
- `user` (String) User used for run the first process. Format is `user` or `user:group` which user and group can be passed literraly or by name.
|
||||
- `userns_mode` (String) Sets the usernamespace mode for the container when usernamespace remapping option is enabled.
|
||||
- `volumes` (Block Set) Spec for mounting volumes in the container. (see [below for nested schema](#nestedblock--volumes))
|
||||
- `wait` (Boolean) If `true`, then the Docker container is waited for being healthy state after creation. If `false`, then the container health state is not checked. Defaults to `false`.
|
||||
- `wait_timeout` (Number) The timeout in seconds to wait the container to be healthy after creation. Defaults to `60`.
|
||||
- `working_dir` (String) The working directory for commands to run in.
|
||||
|
||||
### Read-Only
|
||||
|
|
|
|||
|
|
@ -64,6 +64,20 @@ func resourceDockerContainer() *schema.Resource {
|
|||
Optional: true,
|
||||
},
|
||||
|
||||
"wait": {
|
||||
Type: schema.TypeBool,
|
||||
Description: "If `true`, then the Docker container is waited for being healthy state after creation. If `false`, then the container health state is not checked. Defaults to `false`.",
|
||||
Default: false,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"wait_timeout": {
|
||||
Type: schema.TypeInt,
|
||||
Description: "The timeout in seconds to wait the container to be healthy after creation. Defaults to `60`.",
|
||||
Default: 60,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"attach": {
|
||||
Type: schema.TypeBool,
|
||||
Description: "If `true` attach to the container after its creation and waits the end of its execution. Defaults to `false`.",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ var (
|
|||
errContainerFailedToBeDeleted = errors.New("container failed to be deleted")
|
||||
errContainerExitedImmediately = errors.New("container exited immediately")
|
||||
errContainerFailedToBeInRunningState = errors.New("container failed to be in running state")
|
||||
errContainerFailedToBeInHealthyState = errors.New("container failed to be in healthy state")
|
||||
)
|
||||
|
||||
// NOTE mavogel: we keep this global var for tracking
|
||||
|
|
@ -506,6 +507,39 @@ func resourceDockerContainerCreate(ctx context.Context, d *schema.ResourceData,
|
|||
if err := client.ContainerStart(ctx, retContainer.ID, options); err != nil {
|
||||
return diag.Errorf("Unable to start container: %s", err)
|
||||
}
|
||||
|
||||
if d.Get("wait").(bool) {
|
||||
waitForHealthyState := func(result chan<- error) {
|
||||
for {
|
||||
infos, err := client.ContainerInspect(ctx, retContainer.ID)
|
||||
if err != nil {
|
||||
result <- fmt.Errorf("error inspecting container state: %s", err)
|
||||
}
|
||||
if infos.State.Health.Status == types.Healthy {
|
||||
log.Printf("[DEBUG] container state is healthy")
|
||||
break
|
||||
}
|
||||
log.Printf("[DEBUG] waiting for container healthy state")
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
result <- nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, time.Duration(d.Get("wait_timeout").(int))*time.Second)
|
||||
defer cancel()
|
||||
result := make(chan error, 1)
|
||||
go waitForHealthyState(result)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Printf("[ERROR] Container %s failed to be in healthy state in time", retContainer.ID)
|
||||
return diag.FromErr(errContainerFailedToBeInHealthyState)
|
||||
|
||||
case err := <-result:
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if d.Get("attach").(bool) {
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ func TestAccDockerContainer_basic(t *testing.T) {
|
|||
"restart",
|
||||
"rm",
|
||||
"start",
|
||||
"wait",
|
||||
"wait_timeout",
|
||||
"container_logs",
|
||||
"destroy_grace_seconds",
|
||||
"upload",
|
||||
|
|
@ -132,6 +134,8 @@ func TestAccDockerContainer_init(t *testing.T) {
|
|||
"restart",
|
||||
"rm",
|
||||
"start",
|
||||
"wait",
|
||||
"wait_timeout",
|
||||
"container_logs",
|
||||
"destroy_grace_seconds",
|
||||
"upload",
|
||||
|
|
@ -962,12 +966,12 @@ func TestAccDockerContainer_multipleUploadContentsConfig(t *testing.T) {
|
|||
name = "nginx:latest"
|
||||
keep_locally = true
|
||||
}
|
||||
|
||||
|
||||
resource "docker_container" "foo" {
|
||||
name = "tf-test"
|
||||
image = docker_image.foo.image_id
|
||||
must_run = "false"
|
||||
|
||||
|
||||
upload {
|
||||
content = "foobar"
|
||||
content_base64 = base64encode("barbaz")
|
||||
|
|
@ -993,12 +997,12 @@ func TestAccDockerContainer_noUploadContentsConfig(t *testing.T) {
|
|||
name = "nginx:latest"
|
||||
keep_locally = true
|
||||
}
|
||||
|
||||
|
||||
resource "docker_container" "foo" {
|
||||
name = "tf-test"
|
||||
image = docker_image.foo.image_id
|
||||
must_run = "false"
|
||||
|
||||
|
||||
upload {
|
||||
file = "/terraform/test1.txt"
|
||||
executable = true
|
||||
|
|
|
|||
Loading…
Reference in a new issue