mirror of
https://github.com/kreuzwerker/terraform-provider-docker.git
synced 2025-12-18 23:06:10 -05:00
Some checks failed
Acc Tests / acc-test (TestAccDockerConfig, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerConfig, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerNetwork, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerNetwork, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerPlugin, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerPlugin, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerSecret, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerSecret, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerTag, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerTag, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerVolume, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (TestAccDockerVolume, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerContainer, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerContainer, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerImage, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerImage, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerRegistryImage, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerRegistryImage, 1.8.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerService, 0.15.x) (push) Has been cancelled
Acc Tests / acc-test (true, TestAccDockerService, 1.8.x) (push) Has been cancelled
Compile Binaries / compile-fast (push) Has been cancelled
Compile Binaries / compile (push) Has been cancelled
golangci-lint / lint (push) Has been cancelled
Unit Tests / unit-test (push) Has been cancelled
Website Checks / markdown-link-check (push) Has been cancelled
Docs and Website Lint / website-generation (push) Has been cancelled
Docs and Website Lint / website-lint-spellcheck-tffmt (push) Has been cancelled
Docs and Website Lint / markdown-lint (push) Has been cancelled
103 lines
3.7 KiB
Go
103 lines
3.7 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"strings"
|
|
|
|
"github.com/docker/docker/api/types/image"
|
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
|
)
|
|
|
|
func dataSourceDockerImage() *schema.Resource {
|
|
return &schema.Resource{
|
|
Description: "`docker_image` provides details about a specific Docker Image which need to be present on the Docker Host",
|
|
|
|
ReadContext: dataSourceDockerImageRead,
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
"name": {
|
|
Type: schema.TypeString,
|
|
Description: "The name of the Docker image, including any tags or SHA256 repo digests.",
|
|
Required: true,
|
|
},
|
|
"repo_digest": {
|
|
Type: schema.TypeString,
|
|
Description: "The image sha256 digest in the form of `repo[:tag]@sha256:<hash>`. It may be empty in the edge case where the local image was pulled from a repo, tagged locally, and then referred to in the data source by that local name/tag.",
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func dataSourceDockerImageRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
|
client, err := meta.(*ProviderConfig).MakeClient(ctx, d)
|
|
if err != nil {
|
|
return diag.Errorf("failed to create Docker client: %v", err)
|
|
}
|
|
|
|
var data Data
|
|
if err := fetchLocalImages(ctx, &data, client); err != nil {
|
|
return diag.Errorf("Error reading docker image list: %s", err)
|
|
}
|
|
imageName := d.Get("name").(string)
|
|
|
|
foundImage, err := searchLocalImages(ctx, client, data, imageName)
|
|
if err != nil {
|
|
return diag.Errorf("dataSourceDockerImageRead: error looking up local image %q: %s", imageName, err)
|
|
}
|
|
if foundImage == nil {
|
|
return diag.Errorf("did not find docker image '%s'", imageName)
|
|
}
|
|
|
|
repoDigest := determineRepoDigest(imageName, foundImage)
|
|
|
|
d.SetId(foundImage.ID)
|
|
d.Set("name", imageName)
|
|
d.Set("repo_digest", repoDigest)
|
|
|
|
return nil
|
|
}
|
|
|
|
// determineRepoDigest determines the repo digest for a local image name.
|
|
// It will always return a digest and if none was found it returns an empty string.
|
|
// See https://github.com/kreuzwerker/terraform-provider-docker/pull/212#discussion_r646025706 for details
|
|
func determineRepoDigest(imageName string, imageToQuery *image.Summary) string {
|
|
// the edge case where the local image was pulled from a repo, tagged locally,
|
|
// and then referred to in the data source by that local name/tag...
|
|
if len(imageToQuery.RepoDigests) == 0 {
|
|
return ""
|
|
}
|
|
|
|
// the standard case when there is only one digest
|
|
if len(imageToQuery.RepoDigests) == 1 {
|
|
return imageToQuery.RepoDigests[0]
|
|
}
|
|
|
|
// the special case when the same image is in multiple registries
|
|
// we first need to strip a possible tag because the digest do not contain it
|
|
imageNameWithoutTag := imageName
|
|
tagColonIndex := strings.Index(imageName, ":")
|
|
// we have a tag
|
|
if tagColonIndex != -1 {
|
|
imageNameWithoutTag = imageName[:tagColonIndex]
|
|
}
|
|
|
|
for _, repoDigest := range imageToQuery.RepoDigests {
|
|
// we look explicitly at the beginning of the digest
|
|
// as the image name is e.g. nginx:1.19.1 or 127.0.0.1/nginx:1.19.1 and the digests are
|
|
// "RepoDigests": [
|
|
// "127.0.0.1:15000/nginx@sha256:a5a1e8e5148de5ebc9697b64e4edb2296b5aac1f05def82efdc00ccb7b457171",
|
|
// "nginx@sha256:36b74457bccb56fbf8b05f79c85569501b721d4db813b684391d63e02287c0b2"
|
|
// ],
|
|
if strings.HasPrefix(repoDigest, imageNameWithoutTag) {
|
|
return repoDigest
|
|
}
|
|
}
|
|
|
|
// another edge case where the image was pulled from somewhere, pushed somewhere else,
|
|
// but the tag being referenced in the data is that local-only tag
|
|
log.Printf("[WARN] could not determine repo digest for image name '%s' and repo digests: %v. Will fall back to '%s'", imageName, imageToQuery.RepoDigests, imageToQuery.RepoDigests[0])
|
|
return imageToQuery.RepoDigests[0]
|
|
}
|