Skip to content

Commit

Permalink
Merge pull request #38 from imjasonh/image-repo
Browse files Browse the repository at this point in the history
allow image resource to configure exact repo
  • Loading branch information
imjasonh authored Dec 21, 2022
2 parents e38c66a + dabe3a2 commit c68eafd
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 32 deletions.
5 changes: 2 additions & 3 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ TF_ACC=1 go test ./internal/provider/...
This relies on https://www.terraform.io/cli/config/config-file#implied-local-mirror-directories

```
KO_DOCKER_REPO=gcr.io/jason-chainguard
rm .terraform.lock.hcl && \
go build -o ~/.terraform.d/plugins/registry.terraform.io/chainguard-dev/ko/0.0.100/darwin_arm64/terraform-provider-ko && \
terraform init && \
terraform apply -var project=jason-chainguard
terraform apply
```

Also update `version = "0.0.0"` in the .tf file.

This builds the provider code into the correct local mirror location, installs the provider using that location,
This builds the provider code into the correct local mirror location, installs the provider using that location,

Don't forget to delete the provider from the local mirror if you want to use the released provider later.
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ provider "ko" {

### Optional

- `docker_repo` (String) Container repositor to publish images to. Defaults to `KO_DOCKER_REPO` env var
- `docker_repo` (String) [DEPRECATED: use `repo`] Container repository to publish images to. Defaults to `KO_DOCKER_REPO` env var
- `repo` (String) Container repository to publish images to. Defaults to `KO_DOCKER_REPO` env var
1 change: 1 addition & 0 deletions docs/resources/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ resource "ko_image" "example" {

- `base_image` (String) base image to use
- `platforms` (List of String) Which platform to use when pulling a multi-platform base. Format: all | <os>[/<arch>[/<variant>]][,platform]*
- `repo` (String) Container repository to publish images to. If set, this overrides the provider's docker_repo, and the image name will be exactly the specified `repo`, without the importpath appended.
- `sbom` (String) The SBOM media type to use (none will disable SBOM synthesis and upload, also supports: spdx, cyclonedx, go.version-m).
- `working_dir` (String) working directory for the build

Expand Down
16 changes: 9 additions & 7 deletions internal/provider/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,22 @@ const (
BaseImageKey = "base_image"
// TagsKey is used for common "tags" resource attribute
TagsKey = "tags"
// TagOnlyKey used for common "tag_only" resource attribute
// TagOnlyKey is used for common "tag_only" resource attribute
TagOnlyKey = "tag_only"
// PushKey used for common "push" resource attribute
// PushKey is used for common "push" resource attribute
PushKey = "push"
// FilenamesKey used for common "filenames" resource attribute
// FilenamesKey is used for common "filenames" resource attribute
FilenamesKey = "filenames"
// RecursiveKey used for common "recursive" resource attribute
// RecursiveKey is used for common "recursive" resource attribute
RecursiveKey = "recursive"
// SelectorKey used for common "selector" resource attribute
// SelectorKey is used for common "selector" resource attribute
SelectorKey = "selector"
// ImageRefKey used for common "image_ref" resource attribute
// ImageRefKey is used for common "image_ref" resource attribute
ImageRefKey = "image_ref"
// ManifestsKey used for common "manifests" resource attribute
// ManifestsKey is used for common "manifests" resource attribute
ManifestsKey = "manifests"
// RepoKey is used for common "repo" resource attribute
RepoKey = "repo"
)

func StringSlice(in []interface{}) []string {
Expand Down
21 changes: 15 additions & 6 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ func New(version string) func() *schema.Provider {
p := &schema.Provider{
Schema: map[string]*schema.Schema{
"docker_repo": {
Description: "Container repositor to publish images to. Defaults to `KO_DOCKER_REPO` env var",
Description: "[DEPRECATED: use `repo`] Container repository to publish images to. Defaults to `KO_DOCKER_REPO` env var",
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("KO_DOCKER_REPO", ""),
Type: schema.TypeString,
},
"repo": {
Description: "Container repository to publish images to. Defaults to `KO_DOCKER_REPO` env var",
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("KO_DOCKER_REPO", ""),
Type: schema.TypeString,
Expand All @@ -53,18 +59,21 @@ func New(version string) func() *schema.Provider {
// configure initializes the global provider with sensible defaults (that mimic what ko does with cli/cobra defaults)
func configure(version string, p *schema.Provider) func(context.Context, *schema.ResourceData) (interface{}, diag.Diagnostics) {
return func(ctx context.Context, s *schema.ResourceData) (interface{}, diag.Diagnostics) {
repo, ok := s.Get("docker_repo").(string)
koDockerRepo, ok := s.Get("repo").(string)
if !ok {
return nil, diag.Errorf("expected docker_repo to be string")
return nil, diag.Errorf("expected repo to be string")
}
if repo == "" {
return nil, diag.Errorf("docker_repo attribute or KO_DOCKER_REPO environment variable must be set")
if koDockerRepo == "" {
koDockerRepo, ok = s.Get("docker_repo").(string)
if !ok {
return nil, diag.Errorf("expected docker_repo to be string")
}
}

return &providerOpts{
bo: &options.BuildOptions{},
po: &options.PublishOptions{
DockerRepo: repo,
DockerRepo: koDockerRepo,
},
}, nil
}
Expand Down
56 changes: 41 additions & 15 deletions internal/provider/resource_ko_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package provider

import (
"context"
"errors"
"fmt"
"log"
"sync"
Expand Down Expand Up @@ -85,6 +86,13 @@ func resourceImage() *schema.Resource {
return nil
},
},
RepoKey: {
Description: "Container repository to publish images to. If set, this overrides the provider's docker_repo, and the image name will be exactly the specified `repo`, without the importpath appended.",
Default: "",
Optional: true,
Type: schema.TypeString,
ForceNew: true, // Any time this changes, don't try to update in-place, just create it.
},
ImageRefKey: {
Description: "built image reference by digest",
Type: schema.TypeString,
Expand Down Expand Up @@ -116,12 +124,13 @@ func (o *publishOpts) makePublisher() (publish.Interface, error) {
}

type buildOptions struct {
ip string
workingDir string
dockerRepo string
platforms []string
baseImage string
sbom string
ip string
workingDir string
koDockerRepo string // KO_DOCKER_REPO env var, or the provider's configured repo if set.
imageRepo string // The image's repo, if set.
platforms []string
baseImage string
sbom string
}

func (o *buildOptions) makeBuilder(ctx context.Context) (*build.Caching, error) {
Expand Down Expand Up @@ -178,6 +187,23 @@ func (o *buildOptions) makeBuilder(ctx context.Context) (*build.Caching, error)
var baseImages sync.Map // Cache of base image lookups.

func doBuild(ctx context.Context, opts buildOptions) (string, error) {
if opts.koDockerRepo == "" && opts.imageRepo == "" {
return "", errors.New("one of KO_DOCKER_REPO env var, or provider `docker_repo` or `repo`, or image resource `repo` must be set")
}
po := []publish.Option{publish.WithAuthFromKeychain(authn.DefaultKeychain)}
var repo string
if opts.imageRepo != "" {
// image resource's `repo` takes precedence if set, and selects the
// `--bare` namer so the image is named exactly `repo`.
repo = opts.imageRepo
po = append(po, publish.WithNamer(options.MakeNamer(&options.PublishOptions{
DockerRepo: opts.imageRepo,
Bare: true,
})))
} else {
repo = opts.koDockerRepo
}

b, err := opts.makeBuilder(ctx)
if err != nil {
return "", fmt.Errorf("NewGo: %v", err)
Expand All @@ -187,8 +213,7 @@ func doBuild(ctx context.Context, opts buildOptions) (string, error) {
return "", fmt.Errorf("build: %v", err)
}

p, err := publish.NewDefault(opts.dockerRepo,
publish.WithAuthFromKeychain(authn.DefaultKeychain))
p, err := publish.NewDefault(repo, po...)
if err != nil {
return "", fmt.Errorf("NewDefault: %v", err)
}
Expand All @@ -199,14 +224,15 @@ func doBuild(ctx context.Context, opts buildOptions) (string, error) {
return ref.String(), nil
}

func fromData(d *schema.ResourceData, repo string) buildOptions {
func fromData(d *schema.ResourceData, providerRepo string) buildOptions {
return buildOptions{
ip: d.Get("importpath").(string),
workingDir: d.Get("working_dir").(string),
dockerRepo: repo,
platforms: toStringSlice(d.Get("platforms").([]interface{})),
baseImage: d.Get("base_image").(string),
sbom: d.Get("sbom").(string),
ip: d.Get("importpath").(string),
workingDir: d.Get("working_dir").(string),
koDockerRepo: providerRepo,
imageRepo: d.Get("repo").(string),
platforms: toStringSlice(d.Get("platforms").([]interface{})),
baseImage: d.Get("base_image").(string),
sbom: d.Get("sbom").(string),
}
}

Expand Down

0 comments on commit c68eafd

Please sign in to comment.