From 4b80bc3d9d98615fba7d656d67889725476d3d91 Mon Sep 17 00:00:00 2001 From: Shunsuke Suzuki Date: Tue, 29 Dec 2020 16:03:40 +0900 Subject: [PATCH] feat: add force_remove option to r/image (#104) --- docker/resource_docker_image.go | 6 ++++++ docker/resource_docker_image_funcs.go | 4 +++- docker/resource_docker_image_test.go | 30 +++++++++++++++++++++++++-- website/docs/r/image.html.markdown | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/docker/resource_docker_image.go b/docker/resource_docker_image.go index 4703eee3..b10bfe32 100644 --- a/docker/resource_docker_image.go +++ b/docker/resource_docker_image.go @@ -51,6 +51,12 @@ func resourceDockerImage() *schema.Resource { }, }, + "force_remove": { + Type: schema.TypeBool, + Description: "Force remove the image when the resource is destroyed", + Optional: true, + }, + "build": { Type: schema.TypeSet, Optional: true, diff --git a/docker/resource_docker_image_funcs.go b/docker/resource_docker_image_funcs.go index b841aea8..cd0093eb 100644 --- a/docker/resource_docker_image_funcs.go +++ b/docker/resource_docker_image_funcs.go @@ -152,7 +152,9 @@ func removeImage(d *schema.ResourceData, client *client.Client) error { foundImage := searchLocalImages(data, imageName) if foundImage != nil { - imageDeleteResponseItems, err := client.ImageRemove(context.Background(), foundImage.ID, types.ImageRemoveOptions{}) + imageDeleteResponseItems, err := client.ImageRemove(context.Background(), imageName, types.ImageRemoveOptions{ + Force: d.Get("force_remove").(bool), + }) if err != nil { return err } diff --git a/docker/resource_docker_image_test.go b/docker/resource_docker_image_test.go index 831f8b22..b4d99f5c 100644 --- a/docker/resource_docker_image_test.go +++ b/docker/resource_docker_image_test.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "os/exec" "path" "regexp" "testing" @@ -15,7 +16,19 @@ import ( var contentDigestRegexp = regexp.MustCompile(`\A[A-Za-z0-9_\+\.-]+:[A-Fa-f0-9]+\z`) +const testForceRemoveDockerImageName = "alpine:3.11.5" + func TestAccDockerImage_basic(t *testing.T) { + // run a Docker container which refers the Docker image to test "force_remove" option + containerName := "test-docker-image-force-remove" + if err := exec.Command("docker", "run", "--rm", "-d", "--name", containerName, testForceRemoveDockerImageName, "tail", "-f", "/dev/null").Run(); err != nil { + t.Fatal(err) + } + defer func() { + if err := exec.Command("docker", "stop", containerName).Run(); err != nil { + t.Logf("failed to stop the Docker container %s: %v", containerName, err) + } + }() resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -27,6 +40,12 @@ func TestAccDockerImage_basic(t *testing.T) { resource.TestMatchResourceAttr("docker_image.foo", "latest", contentDigestRegexp), ), }, + { + Config: testAccForceRemoveDockerImage, + Check: resource.ComposeTestCheckFunc( + resource.TestMatchResourceAttr("docker_image.test", "latest", contentDigestRegexp), + ), + }, }, }) } @@ -58,7 +77,7 @@ func TestAccDockerImage_destroy(t *testing.T) { } client := testAccProvider.Meta().(*ProviderConfig).DockerClient - _, _, err := client.ImageInspectWithRaw(context.Background(), rs.Primary.Attributes["latest"]) + _, _, err := client.ImageInspectWithRaw(context.Background(), rs.Primary.Attributes["name"]) if err != nil { return err } @@ -195,7 +214,7 @@ func testAccDockerImageDestroy(s *terraform.State) error { } client := testAccProvider.Meta().(*ProviderConfig).DockerClient - _, _, err := client.ImageInspectWithRaw(context.Background(), rs.Primary.Attributes["latest"]) + _, _, err := client.ImageInspectWithRaw(context.Background(), rs.Primary.Attributes["name"]) if err == nil { return fmt.Errorf("Image still exists") } @@ -231,6 +250,13 @@ resource "docker_image" "foo" { } ` +const testAccForceRemoveDockerImage = ` +resource "docker_image" "test" { + name = "` + testForceRemoveDockerImageName + `" + force_remove = true +} +` + const testAddDockerPrivateImageConfig = ` resource "docker_image" "foobar" { name = "gcr.io:443/google_containers/pause:0.8.0" diff --git a/website/docs/r/image.html.markdown b/website/docs/r/image.html.markdown index bfac58ed..6dcfcc33 100644 --- a/website/docs/r/image.html.markdown +++ b/website/docs/r/image.html.markdown @@ -52,6 +52,7 @@ The following arguments are supported: registry when using the `docker_registry_image` [data source](/docs/providers/docker/d/registry_image.html) to trigger an image update. * `pull_trigger` - **Deprecated**, use `pull_triggers` instead. +* `force_remove` - (Optional, boolean) If true, then the image is removed Forcely when the resource is destroyed. * `build` - (Optional, block) See [Build](#build-1) below for details.