Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: inject imageInfo when expanding templates for ko builder #9207

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions integration/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ var tests = []struct {
pods: []string{"getting-started"},
targetLog: "Hello world!",
},
{
description: "ko",
dir: "examples/ko",
deployments: []string{"ko"},
},
{
description: "nodejs",
dir: "examples/nodejs",
Expand Down
2 changes: 1 addition & 1 deletion pkg/skaffold/build/ko/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (b *Builder) Build(ctx context.Context, out io.Writer, a *latest.Artifact,
if b.pushImages && strings.HasPrefix(ref, build.StrictScheme) {
return "", fmt.Errorf("default repo must be set when using the 'ko://' prefix and pushing to a registry: %s, see https://skaffold.dev/docs/environment/image-registries/", a.ImageName)
}
koBuilder, err := b.newKoBuilder(ctx, a, platforms)
koBuilder, err := b.newKoBuilder(ctx, a, platforms, ref)
if err != nil {
return "", fmt.Errorf("error creating ko builder: %w", err)
}
Expand Down
35 changes: 24 additions & 11 deletions pkg/skaffold/build/ko/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,35 @@ import (
"github.com/google/ko/pkg/commands/options"

"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/config"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/constants"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/docker"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/platform"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/util"
"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/version"
)

func (b *Builder) newKoBuilder(ctx context.Context, a *latest.Artifact, platforms platform.Matcher) (build.Interface, error) {
bo, err := buildOptions(a, b.runMode, platforms)
func (b *Builder) newKoBuilder(ctx context.Context, a *latest.Artifact, platforms platform.Matcher, tag string) (build.Interface, error) {
ref, err := docker.ParseReference(tag)
if err != nil {
return nil, fmt.Errorf("parsing image %v: %w", tag, err)
}
imageInfoEnv := map[string]string{
constants.ImageRef.Repo: ref.Repo,
constants.ImageRef.Name: ref.Name,
constants.ImageRef.Tag: ref.Tag,
}
if err != nil {
return nil, fmt.Errorf("could not resolve skaffold runtime env for ko builder: %v", err)
}
bo, err := buildOptions(a, b.runMode, platforms, imageInfoEnv)
if err != nil {
return nil, fmt.Errorf("could not construct ko build options: %v", err)
}
return commands.NewBuilder(ctx, bo)
}

func buildOptions(a *latest.Artifact, runMode config.RunMode, platforms platform.Matcher) (*options.BuildOptions, error) {
buildconfig, err := buildConfig(a)
func buildOptions(a *latest.Artifact, runMode config.RunMode, platforms platform.Matcher, envs map[string]string) (*options.BuildOptions, error) {
buildconfig, err := buildConfig(a, envs)
if err != nil {
return nil, fmt.Errorf("could not create ko build config: %v", err)
}
Expand All @@ -68,7 +81,7 @@ func buildOptions(a *latest.Artifact, runMode config.RunMode, platforms platform
// A map entry is only required if the artifact config specifies fields that need to be part of ko build configs.
// If none of these are specified, we can provide an empty `BuildConfigs` map.
// In this case, ko falls back to build configs provided in `.ko.yaml`, or to the default zero config.
func buildConfig(a *latest.Artifact) (map[string]build.Config, error) {
func buildConfig(a *latest.Artifact, envs map[string]string) (map[string]build.Config, error) {
buildconfigs := map[string]build.Config{}
if !koArtifactSpecifiesBuildConfig(*a.KoArtifact) {
return buildconfigs, nil
Expand All @@ -77,15 +90,15 @@ func buildConfig(a *latest.Artifact) (map[string]build.Config, error) {
if err != nil {
return nil, fmt.Errorf("could not determine import path of image %s: %v", a.ImageName, err)
}
env, err := expand(a.KoArtifact.Env)
env, err := expand(a.KoArtifact.Env, envs)
if err != nil {
return nil, fmt.Errorf("could not expand env: %v", err)
}
flags, err := expand(a.KoArtifact.Flags)
flags, err := expand(a.KoArtifact.Flags, envs)
if err != nil {
return nil, fmt.Errorf("could not expand build flags: %v", err)
}
ldflags, err := expand(a.KoArtifact.Ldflags)
ldflags, err := expand(a.KoArtifact.Ldflags, envs)
if err != nil {
return nil, fmt.Errorf("could not expand linker flags: %v", err)
}
Expand Down Expand Up @@ -136,12 +149,12 @@ func labels(a *latest.Artifact) ([]string, error) {
return labels, nil
}

func expand(dryValues []string) ([]string, error) {
func expand(dryValues []string, envs map[string]string) ([]string, error) {
var expandedValues []string
for _, rawValue := range dryValues {
// support ko-style envvar templating syntax, see https://github.com/GoogleContainerTools/skaffold/issues/6916
rawValue = strings.ReplaceAll(rawValue, "{{.Env.", "{{.")
expandedValue, err := util.ExpandEnvTemplate(rawValue, nil)
expandedValue, err := util.ExpandEnvTemplate(rawValue, envs)
if err != nil {
return nil, err
}
Expand Down
36 changes: 35 additions & 1 deletion pkg/skaffold/build/ko/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const (
func TestBuildOptions(t *testing.T) {
tests := []struct {
description string
envs map[string]string
artifact latest.Artifact
platforms platform.Matcher
envVarValue string
Expand Down Expand Up @@ -150,11 +151,44 @@ func TestBuildOptions(t *testing.T) {
UserAgent: version.UserAgentWithClient(),
},
},
{
description: "test build option, inject envs for expanding templates",
artifact: latest.Artifact{
ArtifactType: latest.ArtifactType{
KoArtifact: &latest.KoArtifact{
Flags: []string{
"-v",
fmt.Sprintf("-flag-{{.%s}}", "IMAGE_NAME"),
},
Ldflags: []string{
"-s",
fmt.Sprintf("-ldflag-{{.%s}}", "IMAGE_TAG"),
},
},
},
ImageName: "ko://example.com/foo",
},
envs: map[string]string{"IMAGE_NAME": "name", "IMAGE_TAG": "tag"},
wantBo: options.BuildOptions{
BuildConfigs: map[string]build.Config{
"example.com/foo": {
ID: "ko://example.com/foo",
Dir: ".",
Flags: build.FlagArray{"-v", "-flag-name"},
Ldflags: build.StringArray{"-s", "-ldflag-tag"},
},
},
ConcurrentBuilds: 1,
SBOM: "none",
Trimpath: true,
UserAgent: version.UserAgentWithClient(),
},
},
}
for _, test := range tests {
testutil.Run(t, test.description, func(t *testutil.T) {
t.Setenv(testKoBuildOptionsEnvVar, test.envVarValue)
gotBo, err := buildOptions(&test.artifact, test.runMode, test.platforms)
gotBo, err := buildOptions(&test.artifact, test.runMode, test.platforms, test.envs)
t.CheckErrorAndFailNow(false, err)
t.CheckDeepEqual(test.wantBo, *gotBo,
cmpopts.EquateEmpty(),
Expand Down
2 changes: 2 additions & 0 deletions pkg/skaffold/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,12 @@ var ImageRef = struct {
Repo string
Tag string
Digest string
Name string
}{
Repo: "IMAGE_REPO",
Tag: "IMAGE_TAG",
Digest: "IMAGE_DIGEST",
Name: "IMAGE_NAME",
}
var DefaultKubectlManifests = []string{"k8s/*.yaml"}

Expand Down
Loading