-
Notifications
You must be signed in to change notification settings - Fork 404
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
Enable embedding of ko publish #348
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
Copyright 2021 Google LLC All Rights Reserved. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package commands | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/google/ko/pkg/commands/options" | ||
) | ||
|
||
func TestOverrideDefaultBaseImageUsingBuildOption(t *testing.T) { | ||
wantDigest := "sha256:76c39a6f76890f8f8b026f89e081084bc8c64167d74e6c93da7a053cb4ccb5dd" | ||
wantImage := "gcr.io/distroless/static-debian9@" + wantDigest | ||
bo := &options.BuildOptions{ | ||
BaseImage: wantImage, | ||
} | ||
|
||
baseFn := getBaseImage("all", bo) | ||
res, err := baseFn(context.Background(), "ko://example.com/helloworld") | ||
if err != nil { | ||
t.Fatalf("getBaseImage(): %v", err) | ||
} | ||
|
||
digest, err := res.Digest() | ||
if err != nil { | ||
t.Fatalf("res.Digest(): %v", err) | ||
} | ||
gotDigest := digest.String() | ||
if gotDigest != wantDigest { | ||
t.Errorf("got digest %s, wanted %s", gotDigest, wantDigest) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
Copyright 2021 Google LLC All Rights Reserved. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package commands | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"path/filepath" | ||
"runtime" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/google/ko/pkg/build" | ||
"github.com/google/ko/pkg/commands/options" | ||
) | ||
|
||
func TestPublishImages(t *testing.T) { | ||
repo := "registry.example.com/repository" | ||
sampleAppDir, err := sampleAppRelDir() | ||
if err != nil { | ||
t.Fatalf("sampleAppRelDir(): %v", err) | ||
} | ||
tests := []struct { | ||
description string | ||
publishArg string | ||
importpath string | ||
}{ | ||
{ | ||
description: "import path with ko scheme", | ||
publishArg: "ko://github.com/google/ko/test", | ||
importpath: "github.com/google/ko/test", | ||
}, | ||
{ | ||
description: "import path without ko scheme", | ||
publishArg: "github.com/google/ko/test", | ||
importpath: "github.com/google/ko/test", | ||
}, | ||
{ | ||
description: "file path", | ||
publishArg: sampleAppDir, | ||
importpath: "github.com/google/ko/test", | ||
}, | ||
} | ||
for _, test := range tests { | ||
ctx := context.Background() | ||
bo := &options.BuildOptions{ | ||
ConcurrentBuilds: 1, | ||
} | ||
builder, err := NewBuilder(ctx, bo) | ||
if err != nil { | ||
t.Fatalf("%s: MakeBuilder(): %v", test.description, err) | ||
} | ||
po := &options.PublishOptions{ | ||
DockerRepo: repo, | ||
PreserveImportPaths: true, | ||
} | ||
publisher, err := NewPublisher(po) | ||
if err != nil { | ||
t.Fatalf("%s: MakePublisher(): %v", test.description, err) | ||
} | ||
importpathWithScheme := build.StrictScheme + test.importpath | ||
refs, err := PublishImages(ctx, []string{test.publishArg}, publisher, builder) | ||
if err != nil { | ||
t.Fatalf("%s: PublishImages(): %v", test.description, err) | ||
} | ||
ref, exists := refs[importpathWithScheme] | ||
if !exists { | ||
t.Errorf("%s: could not find image for importpath %s", test.description, importpathWithScheme) | ||
} | ||
gotImageName := ref.Context().Name() | ||
wantImageName := strings.ToLower(fmt.Sprintf("%s/%s", repo, test.importpath)) | ||
if gotImageName != wantImageName { | ||
t.Errorf("%s: got %s, wanted %s", test.description, gotImageName, wantImageName) | ||
} | ||
} | ||
} | ||
|
||
func sampleAppRelDir() (string, error) { | ||
_, filename, _, ok := runtime.Caller(0) | ||
if !ok { | ||
return "", fmt.Errorf("could not get current filename") | ||
} | ||
basepath := filepath.Dir(filename) | ||
testAppDir := filepath.Join(basepath, "..", "..", "test") | ||
return filepath.Rel(basepath, testAppDir) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
Copyright 2021 Google LLC All Rights Reserved. | ||
Copyright 2018 Google LLC All Rights Reserved. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
|
@@ -41,6 +41,7 @@ import ( | |
"k8s.io/apimachinery/pkg/labels" | ||
) | ||
|
||
// ua returns the ko user agent. | ||
func ua() string { | ||
if v := version(); v != "" { | ||
return "ko/" + v | ||
|
@@ -79,7 +80,7 @@ func gobuildOptions(bo *options.BuildOptions) ([]build.Option, error) { | |
} | ||
|
||
opts := []build.Option{ | ||
build.WithBaseImages(getBaseImage(platform)), | ||
build.WithBaseImages(getBaseImage(platform, bo)), | ||
build.WithPlatforms(platform), | ||
} | ||
if creationTime != nil { | ||
|
@@ -98,6 +99,11 @@ func gobuildOptions(bo *options.BuildOptions) ([]build.Option, error) { | |
return opts, nil | ||
} | ||
|
||
// NewBuilder creates a ko builder | ||
func NewBuilder(ctx context.Context, bo *options.BuildOptions) (build.Interface, error) { | ||
return makeBuilder(ctx, bo) | ||
} | ||
|
||
func makeBuilder(ctx context.Context, bo *options.BuildOptions) (*build.Caching, error) { | ||
opt, err := gobuildOptions(bo) | ||
if err != nil { | ||
|
@@ -129,6 +135,11 @@ func makeBuilder(ctx context.Context, bo *options.BuildOptions) (*build.Caching, | |
return build.NewCaching(innerBuilder) | ||
} | ||
|
||
// NewPublisher creates a ko publisher | ||
func NewPublisher(po *options.PublishOptions) (publish.Interface, error) { | ||
return makePublisher(po) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above. I was thinking of an expand-and-contract style of approach (https://www.martinfowler.com/bliki/ParallelChange.html). |
||
} | ||
|
||
func makePublisher(po *options.PublishOptions) (publish.Interface, error) { | ||
// Create the publish.Interface that we will use to publish image references | ||
// to either a docker daemon or a container image registry. | ||
|
@@ -151,7 +162,7 @@ func makePublisher(po *options.PublishOptions) (publish.Interface, error) { | |
} | ||
if _, err := name.NewRegistry(repoName); err != nil { | ||
if _, err := name.NewRepository(repoName); err != nil { | ||
return nil, fmt.Errorf("failed to parse environment variable KO_DOCKER_REPO=%q as repository: %v", repoName, err) | ||
return nil, fmt.Errorf("failed to parse %q as repository: %v", repoName, err) | ||
} | ||
} | ||
|
||
|
@@ -167,9 +178,13 @@ func makePublisher(po *options.PublishOptions) (publish.Interface, error) { | |
tp := publish.NewTarball(po.TarballFile, repoName, namer, po.Tags) | ||
publishers = append(publishers, tp) | ||
} | ||
userAgent := ua() | ||
if po.UserAgent != "" { | ||
userAgent = po.UserAgent | ||
} | ||
if po.Push { | ||
dp, err := publish.NewDefault(repoName, | ||
publish.WithUserAgent(ua()), | ||
publish.WithUserAgent(userAgent), | ||
publish.WithAuthFromKeychain(authn.DefaultKeychain), | ||
publish.WithNamer(namer), | ||
publish.WithTags(po.Tags), | ||
|
@@ -208,6 +223,7 @@ type nopPublisher struct { | |
} | ||
|
||
func (n nopPublisher) Publish(_ context.Context, br build.Result, s string) (name.Reference, error) { | ||
s = strings.TrimPrefix(s, build.StrictScheme) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this change necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, that was unrelated - the nopPublisher failed in a unit test because the scheme prefix wasn't trimmed. |
||
h, err := br.Digest() | ||
if err != nil { | ||
return nil, err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to prefer exporting this new wrapper method, versus exporting
publishImages
directly?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes the diff smaller, which is nice. I kind of like it :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be okay with it as a specific diff-shrinking measure that we intend to clean up with a followup PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was just to keep the diff small.