Skip to content

fix: specifying platforms in ko builder #7135

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

Merged
merged 1 commit into from
Feb 22, 2022
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
10 changes: 2 additions & 8 deletions docs/content/en/docs/pipeline-stages/builders/ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,8 @@ a shell, you can use this configuration:

The ko builder supports building multi-platform images. The default platform
is `linux/amd64`, but you can configure a list of platforms using the
`platforms` configuration field, e.g.:

```yaml
ko:
platforms:
- linux/amd64
- linux/arm64
```
artifact's `platforms` configuration field, e.g.:
{{% readfile file="samples/builders/ko-platforms.yaml" %}}

You can also supply `["all"]` as the value of `platforms`. `all` means that the
ko builder builds images for all platforms supported by the base image.
Expand Down
7 changes: 7 additions & 0 deletions docs/content/en/samples/builders/ko-platforms.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
build:
artifacts:
- image: foo
ko: {}
platforms:
- linux/amd64
- linux/arm64
12 changes: 1 addition & 11 deletions docs/content/en/schemas/v2beta28.json
Original file line number Diff line number Diff line change
Expand Up @@ -2714,15 +2714,6 @@
"type": "string",
"description": "location of the main package. It is the pattern passed to `go build`. If main is specified as a relative path, it is relative to the `context` directory. If main is empty, the ko builder uses a default value of `.`. If main is a pattern with wildcards, such as `./...`, the expansion must contain only one main package, otherwise ko fails. Main is ignored if the `ImageName` starts with `ko://`. Example: `./cmd/foo`.",
"x-intellij-html-description": "location of the main package. It is the pattern passed to <code>go build</code>. If main is specified as a relative path, it is relative to the <code>context</code> directory. If main is empty, the ko builder uses a default value of <code>.</code>. If main is a pattern with wildcards, such as <code>./...</code>, the expansion must contain only one main package, otherwise ko fails. Main is ignored if the <code>ImageName</code> starts with <code>ko://</code>. Example: <code>./cmd/foo</code>."
},
"platforms": {
"items": {
"type": "string"
},
"type": "array",
"description": "list of platforms to build images for. Each platform is of the format `os[/arch[/variant]]`, e.g., `linux/amd64`. Use `[\"all\"]` to build for all platforms supported by the base image. If empty, the builder uses the ko default (`[\"linux/amd64\"]`). Example: `[\"linux/amd64\", \"linux/arm64\"]`.",
"x-intellij-html-description": "list of platforms to build images for. Each platform is of the format <code>os[/arch[/variant]]</code>, e.g., <code>linux/amd64</code>. Use <code>[&quot;all&quot;]</code> to build for all platforms supported by the base image. If empty, the builder uses the ko default (<code>[&quot;linux/amd64&quot;]</code>). Example: <code>[&quot;linux/amd64&quot;, &quot;linux/arm64&quot;]</code>.",
"default": "[]"
}
},
"preferredOrder": [
Expand All @@ -2733,8 +2724,7 @@
"flags",
"labels",
"ldflags",
"main",
"platforms"
"main"
],
"additionalProperties": false,
"type": "object",
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 *latestV1.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)
koBuilder, err := b.newKoBuilder(ctx, a, platforms)
if err != nil {
return "", fmt.Errorf("error creating ko builder: %w", err)
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/skaffold/build/ko/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,21 @@ import (
"github.com/google/ko/pkg/commands/options"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/version"
)

func (b *Builder) newKoBuilder(ctx context.Context, a *latestV1.Artifact) (build.Interface, error) {
bo, err := buildOptions(a, b.runMode)
func (b *Builder) newKoBuilder(ctx context.Context, a *latestV1.Artifact, platforms platform.Matcher) (build.Interface, error) {
bo, err := buildOptions(a, b.runMode, platforms)
if err != nil {
return nil, fmt.Errorf("could not construct ko build options: %v", err)
}
return commands.NewBuilder(ctx, bo)
}

func buildOptions(a *latestV1.Artifact, runMode config.RunMode) (*options.BuildOptions, error) {
func buildOptions(a *latestV1.Artifact, runMode config.RunMode, platforms platform.Matcher) (*options.BuildOptions, error) {
buildconfig, err := buildConfig(a)
if err != nil {
return nil, fmt.Errorf("could not create ko build config: %v", err)
Expand All @@ -55,7 +56,7 @@ func buildOptions(a *latestV1.Artifact, runMode config.RunMode) (*options.BuildO
ConcurrentBuilds: 1, // we could plug in Skaffold's max builds here, but it'd be incorrect if users build more than one artifact
DisableOptimizations: runMode == config.RunModes.Debug,
Labels: imageLabels,
Platform: strings.Join(a.KoArtifact.Platforms, ","),
Platform: platforms.String(),
Trimpath: runMode != config.RunModes.Debug,
UserAgent: version.UserAgentWithClient(),
WorkingDirectory: filepath.Join(a.Workspace, a.KoArtifact.Dir),
Expand Down
10 changes: 7 additions & 3 deletions pkg/skaffold/build/ko/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/ko/pkg/build"
"github.com/google/ko/pkg/commands/options"
specs "github.com/opencontainers/image-spec/specs-go/v1"

"github.com/GoogleContainerTools/skaffold/pkg/skaffold/config"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/platform"
latestV1 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest/v1"
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/version"
"github.com/GoogleContainerTools/skaffold/testutil"
Expand All @@ -40,6 +42,7 @@ func TestBuildOptions(t *testing.T) {
tests := []struct {
description string
artifact latestV1.Artifact
platforms platform.Matcher
envVarValue string
runMode config.RunMode
wantBo options.BuildOptions
Expand Down Expand Up @@ -82,13 +85,14 @@ func TestBuildOptions(t *testing.T) {
fmt.Sprintf("-ldflag-{{.%s}}", testKoBuildOptionsEnvVar),
fmt.Sprintf("-ldflag2-{{.Env.%s}}", testKoBuildOptionsEnvVar),
},
Main: "cmd/app",
Platforms: []string{"linux/amd64", "linux/arm64"},
Main: "cmd/app",
},
},
ImageName: "ko://example.com/foo",
Workspace: "workdir",
},
platforms: platform.Matcher{Platforms: []specs.Platform{{OS: "linux", Architecture: "amd64"}, {OS: "linux", Architecture: "arm64"}}},

envVarValue: "baz",
runMode: config.RunModes.Debug,
wantBo: options.BuildOptions{
Expand Down Expand Up @@ -148,7 +152,7 @@ func TestBuildOptions(t *testing.T) {
for _, test := range tests {
testutil.Run(t, test.description, func(t *testutil.T) {
os.Setenv(testKoBuildOptionsEnvVar, test.envVarValue)
gotBo, err := buildOptions(&test.artifact, test.runMode)
gotBo, err := buildOptions(&test.artifact, test.runMode, test.platforms)
defer os.Unsetenv(testKoBuildOptionsEnvVar)
t.CheckErrorAndFailNow(false, err)
t.CheckDeepEqual(test.wantBo, *gotBo,
Expand Down
3 changes: 3 additions & 0 deletions pkg/skaffold/platform/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ func (m Matcher) Intersect(other Matcher) Matcher {
func Parse(ps []string) (Matcher, error) {
var sl []specs.Platform
for _, p := range ps {
if strings.ToLower(p) == "all" {
return All, nil
}
platform, err := platforms.Parse(p)
if err != nil {
return Matcher{}, UnknownPlatformCLIFlag(p, err)
Expand Down
7 changes: 0 additions & 7 deletions pkg/skaffold/schema/latest/v1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1403,13 +1403,6 @@ type KoArtifact struct {
// Main is ignored if the `ImageName` starts with `ko://`.
// Example: `./cmd/foo`.
Main string `yaml:"main,omitempty"`

// Platforms is the list of platforms to build images for.
// Each platform is of the format `os[/arch[/variant]]`, e.g., `linux/amd64`.
// Use `["all"]` to build for all platforms supported by the base image.
// If empty, the builder uses the ko default (`["linux/amd64"]`).
// Example: `["linux/amd64", "linux/arm64"]`.
Platforms []string `yaml:"platforms,omitempty"`
}

// KoDependencies is used to specify dependencies for an artifact built by ko.
Expand Down
13 changes: 13 additions & 0 deletions pkg/skaffold/schema/v2beta27/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,18 @@ func (c *SkaffoldConfig) Upgrade() (util.VersionedConfig, error) {
}

func upgradeOnePipeline(oldPipeline, newPipeline interface{}) error {
oldBuild := &oldPipeline.(*Pipeline).Build
newBuild := &newPipeline.(*next.Pipeline).Build

// move: artifact.ko.Platforms
// to: artifact.Platforms
for i, newArtifact := range newBuild.Artifacts {
oldArtifact := oldBuild.Artifacts[i]
if oldArtifact.KoArtifact == nil || len(oldArtifact.KoArtifact.Platforms) == 0 {
continue
}
newArtifact.Platforms = oldArtifact.KoArtifact.Platforms
}

return nil
}
4 changes: 3 additions & 1 deletion pkg/skaffold/schema/v2beta27/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ build:
sync:
auto: true
- image: ko://github.com/GoogleContainerTools/skaffold/cmd/skaffold
ko: {}
ko:
platforms: ['linux/arm64', 'linux/amd64']
googleCloudBuild:
projectId: test-project
test:
Expand Down Expand Up @@ -133,6 +134,7 @@ build:
auto: true
- image: ko://github.com/GoogleContainerTools/skaffold/cmd/skaffold
ko: {}
platforms: ['linux/arm64', 'linux/amd64']
googleCloudBuild:
projectId: test-project
test:
Expand Down