1
0
mirror of https://github.com/ko-build/ko.git synced 2025-07-15 23:54:17 +02:00

Enable override of daemon publisher local domain (#362)

* Enable override of daemon publisher local domain

Add a `LocalDomain` field to `PublishOptions`, but no flag (yet?).

This allows use of a domain (base repo) other than `ko.local` for images
that are side-loaded to the local Docker daemon.

An alternative implementation would be to add a boolean field that
indicates that `ko publish` should use the value of the `KO_DOCKER_REPO`
environment variable (or the `DockerRepo` field in `PublishOptions`) as
the base name for images side-loaded to the local Docker daemon. I'd be
happy to get feedback on which option would work best.

* Restore NewDaemon tags positional arg
This commit is contained in:
Halvard Skogsrud
2021-05-18 01:25:47 +10:00
committed by GitHub
parent 9814e6e0e4
commit a68d0ab75f
4 changed files with 95 additions and 33 deletions

View File

@ -32,6 +32,9 @@ type PublishOptions struct {
// In normal ko usage, this is populated with the value of $KO_DOCKER_REPO.
DockerRepo string
// LocalDomain overrides the default domain for images loaded into the local Docker daemon. Use with Local=true.
LocalDomain string
Tags []string
// Push publishes images to a registry.

View File

@ -139,7 +139,8 @@ func makePublisher(po *options.PublishOptions) (publish.Interface, error) {
// TODO(jonjohnsonjr): I'm assuming that nobody will
// use local with other publishers, but that might
// not be true.
return publish.NewDaemon(namer, po.Tags), nil
return publish.NewDaemon(namer, po.Tags,
publish.WithLocalDomain(po.LocalDomain))
}
if repoName == publish.KindDomain {
return publish.NewKindPublisher(namer, po.Tags), nil

View File

@ -1,16 +1,18 @@
// 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.
// 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.
/*
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.
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 publish
@ -34,13 +36,37 @@ const (
// demon is intentionally misspelled to avoid name collision (and drive Jon nuts).
type demon struct {
base string
namer Namer
tags []string
}
// DaemonOption is a functional option for NewDaemon.
type DaemonOption func(*demon) error
// WithLocalDomain is a functional option for overriding the domain used for images that are side-loaded into the daemon.
func WithLocalDomain(domain string) DaemonOption {
return func(i *demon) error {
if domain != "" {
i.base = domain
}
return nil
}
}
// NewDaemon returns a new publish.Interface that publishes images to a container daemon.
func NewDaemon(namer Namer, tags []string) Interface {
return &demon{namer, tags}
func NewDaemon(namer Namer, tags []string, opts ...DaemonOption) (Interface, error) {
d := &demon{
base: LocalDomain,
namer: namer,
tags: tags,
}
for _, option := range opts {
if err := option(d); err != nil {
return nil, err
}
}
return d, nil
}
// getOpts returns daemon.Options. It's a var to allow it to be overridden during tests.
@ -99,7 +125,7 @@ func (d *demon) Publish(ctx context.Context, br build.Result, s string) (name.Re
return nil, err
}
digestTag, err := name.NewTag(fmt.Sprintf("%s:%s", d.namer(LocalDomain, s), h.Hex))
digestTag, err := name.NewTag(fmt.Sprintf("%s:%s", d.namer(d.base, s), h.Hex))
if err != nil {
return nil, err
}
@ -112,7 +138,7 @@ func (d *demon) Publish(ctx context.Context, br build.Result, s string) (name.Re
for _, tagName := range d.tags {
log.Printf("Adding tag %v", tagName)
tag, err := name.NewTag(fmt.Sprintf("%s:%s", d.namer(LocalDomain, s), tagName))
tag, err := name.NewTag(fmt.Sprintf("%s:%s", d.namer(d.base, s), tagName))
if err != nil {
return nil, err
}

View File

@ -1,16 +1,18 @@
// 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.
// 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.
/*
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.
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 publish
@ -60,7 +62,11 @@ func TestDaemon(t *testing.T) {
t.Fatalf("random.Image() = %v", err)
}
def := NewDaemon(md5Hash, []string{})
def, err := NewDaemon(md5Hash, []string{})
if err != nil {
t.Fatalf("NewDaemon() = %v", err)
}
if d, err := def.Publish(context.Background(), img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if got, want := d.String(), md5Hash("ko.local", importpath); !strings.HasPrefix(got, want) {
@ -77,7 +83,11 @@ func TestDaemonTags(t *testing.T) {
t.Fatalf("random.Image() = %v", err)
}
def := NewDaemon(md5Hash, []string{"v2.0.0", "v1.2.3", "production"})
def, err := NewDaemon(md5Hash, []string{"v2.0.0", "v1.2.3", "production"})
if err != nil {
t.Fatalf("NewDaemon() = %v", err)
}
if d, err := def.Publish(context.Background(), img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if got, want := d.String(), md5Hash("ko.local", importpath); !strings.HasPrefix(got, want) {
@ -92,3 +102,25 @@ func TestDaemonTags(t *testing.T) {
}
}
}
func TestDaemonDomain(t *testing.T) {
Tags = nil
importpath := "github.com/google/ko"
img, err := random.Image(1024, 1)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
localDomain := "registry.example.com/repository"
def, err := NewDaemon(md5Hash, []string{}, WithLocalDomain(localDomain))
if err != nil {
t.Fatalf("NewDaemon() = %v", err)
}
if d, err := def.Publish(context.Background(), img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if got, want := d.String(), md5Hash(localDomain, importpath); !strings.HasPrefix(got, want) {
t.Errorf("Publish() = %v, wanted prefix %v", got, want)
}
}