mirror of
https://github.com/kreuzwerker/terraform-provider-docker.git
synced 2025-12-20 22:59:42 -05:00
* fix running tests in directories with spaces * REGISTRY_STORAGE_DELETE * Updated Windows testing scripts Co-authored-by: Zhitenev-Lexy <Zhitenev.Lexy@bcg.com> Co-authored-by: Manuel Vogel <mavogel@posteo.de>
422 lines
11 KiB
Go
422 lines
11 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
|
|
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
|
|
)
|
|
|
|
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"
|
|
ctx := context.Background()
|
|
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) },
|
|
ProviderFactories: providerFactories,
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return testAccDockerImageDestroy(ctx, state)
|
|
},
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccDockerImageConfig,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foo", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
{
|
|
Config: testAccForceRemoveDockerImage,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.test", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_private(t *testing.T) {
|
|
ctx := context.Background()
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return testAccDockerImageDestroy(ctx, state)
|
|
},
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAddDockerPrivateImageConfig,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foobar", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_destroy(t *testing.T) {
|
|
ctx := context.Background()
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
CheckDestroy: func(s *terraform.State) error {
|
|
for _, rs := range s.RootModule().Resources {
|
|
if rs.Type != "docker_image" {
|
|
continue
|
|
}
|
|
|
|
client := testAccProvider.Meta().(*ProviderConfig).DockerClient
|
|
_, _, err := client.ImageInspectWithRaw(ctx, rs.Primary.Attributes["name"])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
},
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccDockerImageKeepLocallyConfig,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foobarzoo", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_data(t *testing.T) {
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
PreventPostDestroyRefresh: true,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccDockerImageFromDataConfig,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foobarbaz", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_data_pull_trigger(t *testing.T) {
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
PreventPostDestroyRefresh: true,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccDockerImageFromDataConfigWithPullTrigger,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foobarbazoo", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_data_private(t *testing.T) {
|
|
registry := "127.0.0.1:15000"
|
|
image := "127.0.0.1:15000/tftest-service:v1"
|
|
ctx := context.Background()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
PreventPostDestroyRefresh: true,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: fmt.Sprintf(testAccDockerImageFromDataPrivateConfig, registry, image),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foo_private", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return checkAndRemoveImages(ctx, state)
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_data_private_config_file(t *testing.T) {
|
|
registry := "127.0.0.1:15000"
|
|
image := "127.0.0.1:15000/tftest-service:v1"
|
|
wd, _ := os.Getwd()
|
|
dockerConfig := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "dockerconfig.json"), "\\", "\\\\")
|
|
ctx := context.Background()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
PreventPostDestroyRefresh: true,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: fmt.Sprintf(testAccDockerImageFromDataPrivateConfigFile, registry, dockerConfig, image),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foo_private", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return checkAndRemoveImages(ctx, state)
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_data_private_config_file_content(t *testing.T) {
|
|
registry := "127.0.0.1:15000"
|
|
image := "127.0.0.1:15000/tftest-service:v1"
|
|
wd, _ := os.Getwd()
|
|
dockerConfig := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "dockerconfig.json"), "\\", "\\\\")
|
|
ctx := context.Background()
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
PreventPostDestroyRefresh: true,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: fmt.Sprintf(testAccDockerImageFromDataPrivateConfigFileContent, registry, dockerConfig, image),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foo_private", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return checkAndRemoveImages(ctx, state)
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_sha265(t *testing.T) {
|
|
ctx := context.Background()
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return testAccDockerImageDestroy(ctx, state)
|
|
},
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAddDockerImageWithSHA256RepoDigest,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.foobar", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func testAccDockerImageDestroy(ctx context.Context, s *terraform.State) error {
|
|
for _, rs := range s.RootModule().Resources {
|
|
if rs.Type != "docker_image" {
|
|
continue
|
|
}
|
|
|
|
client := testAccProvider.Meta().(*ProviderConfig).DockerClient
|
|
_, _, err := client.ImageInspectWithRaw(ctx, rs.Primary.Attributes["name"])
|
|
if err == nil {
|
|
return fmt.Errorf("Image still exists")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestAccDockerImage_tag_sha265(t *testing.T) {
|
|
ctx := context.Background()
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return testAccDockerImageDestroy(ctx, state)
|
|
},
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testDockerImageWithTagAndSHA256RepoDigest,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.nginx", "latest", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccDockerImage_build(t *testing.T) {
|
|
ctx := context.Background()
|
|
wd, _ := os.Getwd()
|
|
dfPath := filepath.Join(wd, "Dockerfile")
|
|
if err := ioutil.WriteFile(dfPath, []byte(testDockerFileExample), 0o644); err != nil {
|
|
t.Fatalf("failed to create a Dockerfile %s for test: %+v", dfPath, err)
|
|
}
|
|
defer os.Remove(dfPath)
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
ProviderFactories: providerFactories,
|
|
CheckDestroy: func(state *terraform.State) error {
|
|
return testAccDockerImageDestroy(ctx, state)
|
|
},
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testCreateDockerImage,
|
|
Check: resource.ComposeTestCheckFunc(
|
|
resource.TestMatchResourceAttr("docker_image.test", "name", contentDigestRegexp),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
const testAccDockerImageConfig = `
|
|
resource "docker_image" "foo" {
|
|
name = "alpine:3.1"
|
|
}
|
|
`
|
|
|
|
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"
|
|
}
|
|
`
|
|
|
|
const testAccDockerImageKeepLocallyConfig = `
|
|
resource "docker_image" "foobarzoo" {
|
|
name = "crux:3.1"
|
|
keep_locally = true
|
|
}
|
|
`
|
|
|
|
const testAccDockerImageFromDataConfig = `
|
|
data "docker_registry_image" "foobarbaz" {
|
|
name = "alpine:3.1"
|
|
}
|
|
resource "docker_image" "foobarbaz" {
|
|
name = data.docker_registry_image.foobarbaz.name
|
|
pull_triggers = [data.docker_registry_image.foobarbaz.sha256_digest]
|
|
}
|
|
`
|
|
|
|
const testAccDockerImageFromDataConfigWithPullTrigger = `
|
|
data "docker_registry_image" "foobarbazoo" {
|
|
name = "alpine:3.1"
|
|
}
|
|
resource "docker_image" "foobarbazoo" {
|
|
name = data.docker_registry_image.foobarbazoo.name
|
|
pull_trigger = data.docker_registry_image.foobarbazoo.sha256_digest
|
|
}
|
|
`
|
|
|
|
const testAccDockerImageFromDataPrivateConfig = `
|
|
provider "docker" {
|
|
alias = "private"
|
|
registry_auth {
|
|
address = "%s"
|
|
}
|
|
}
|
|
data "docker_registry_image" "foo_private" {
|
|
provider = "docker.private"
|
|
name = "%s"
|
|
}
|
|
resource "docker_image" "foo_private" {
|
|
provider = "docker.private"
|
|
name = data.docker_registry_image.foo_private.name
|
|
keep_locally = true
|
|
pull_triggers = [data.docker_registry_image.foo_private.sha256_digest]
|
|
}
|
|
`
|
|
|
|
const testAccDockerImageFromDataPrivateConfigFile = `
|
|
provider "docker" {
|
|
alias = "private"
|
|
registry_auth {
|
|
address = "%s"
|
|
config_file = "%s"
|
|
}
|
|
}
|
|
resource "docker_image" "foo_private" {
|
|
provider = "docker.private"
|
|
name = "%s"
|
|
}
|
|
`
|
|
|
|
const testAccDockerImageFromDataPrivateConfigFileContent = `
|
|
provider "docker" {
|
|
alias = "private"
|
|
registry_auth {
|
|
address = "%s"
|
|
config_file_content = file("%s")
|
|
}
|
|
}
|
|
resource "docker_image" "foo_private" {
|
|
provider = "docker.private"
|
|
name = "%s"
|
|
}
|
|
`
|
|
|
|
const testAddDockerImageWithSHA256RepoDigest = `
|
|
resource "docker_image" "foobar" {
|
|
name = "stocard/gotthard@sha256:ed752380c07940c651b46c97ca2101034b3be112f4d86198900aa6141f37fe7b"
|
|
}
|
|
`
|
|
|
|
const testCreateDockerImage = `
|
|
resource "docker_image" "test" {
|
|
name = "ubuntu:11"
|
|
build {
|
|
path = "."
|
|
dockerfile = "Dockerfile"
|
|
force_remove = true
|
|
build_arg = {
|
|
test_arg = "kenobi"
|
|
}
|
|
label = {
|
|
test_label1 = "han"
|
|
test_label2 = "solo"
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
const testDockerFileExample = `
|
|
FROM python:3-stretch
|
|
|
|
WORKDIR /app
|
|
|
|
ARG test_arg
|
|
|
|
RUN echo ${test_arg} > test_arg.txt
|
|
|
|
RUN apt-get update -qq
|
|
`
|
|
|
|
const testDockerImageWithTagAndSHA256RepoDigest = `
|
|
resource "docker_image" "nginx" {
|
|
name = "nginx:1.18.0-alpine@sha256:0c56c40f232f41c1b8341c3cc055c8b528cb6decefd7f7c8506e2d30bb9678b6"
|
|
}
|
|
`
|