forked from ko-build/ko
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow images to be loaded into kind using 'kind.local'. (ko-build#180)
* Allow images to be loaded into kind using 'kind.local'. * Add documentation for kind.
- Loading branch information
1 parent
b7b0435
commit 1aa3b37
Showing
334 changed files
with
62,109 additions
and
37,592 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Copyright 2020 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 | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strings" | ||
|
||
"github.com/google/go-containerregistry/pkg/name" | ||
v1 "github.com/google/go-containerregistry/pkg/v1" | ||
"github.com/google/ko/pkg/build" | ||
"github.com/google/ko/pkg/publish/kind" | ||
) | ||
|
||
const ( | ||
// KindDomain is a sentinel "registry" that represents side-loading images into kind nodes. | ||
KindDomain = "kind.local" | ||
) | ||
|
||
type kindPublisher struct { | ||
namer Namer | ||
tags []string | ||
} | ||
|
||
// NewKindPublisher returns a new publish.Interface that loads images into kind nodes. | ||
func NewKindPublisher(namer Namer, tags []string) Interface { | ||
return &kindPublisher{ | ||
namer: namer, | ||
tags: tags, | ||
} | ||
} | ||
|
||
// Publish implements publish.Interface. | ||
func (t *kindPublisher) Publish(img v1.Image, s string) (name.Reference, error) { | ||
s = strings.TrimPrefix(s, build.StrictScheme) | ||
// https://github.com/google/go-containerregistry/issues/212 | ||
s = strings.ToLower(s) | ||
|
||
h, err := img.Digest() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
digestTag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", KindDomain, t.namer(s), h.Hex)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Printf("Loading %v", digestTag) | ||
if err := kind.Write(digestTag, img); err != nil { | ||
return nil, err | ||
} | ||
log.Printf("Loaded %v", digestTag) | ||
|
||
for _, tagName := range t.tags { | ||
log.Printf("Adding tag %v", tagName) | ||
tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", KindDomain, t.namer(s), tagName)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if err := kind.Tag(digestTag, tag); err != nil { | ||
return nil, err | ||
} | ||
log.Printf("Added tag %v", tagName) | ||
} | ||
|
||
return &digestTag, nil | ||
} | ||
|
||
func (t *kindPublisher) Close() error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2020 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 kind defines methods for publishing images into kind nodes. | ||
package kind |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright 2020 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 kind | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
|
||
"golang.org/x/sync/errgroup" | ||
|
||
"github.com/google/go-containerregistry/pkg/name" | ||
v1 "github.com/google/go-containerregistry/pkg/v1" | ||
"github.com/google/go-containerregistry/pkg/v1/tarball" | ||
|
||
"sigs.k8s.io/kind/pkg/cluster" | ||
"sigs.k8s.io/kind/pkg/cluster/nodes" | ||
) | ||
|
||
// Supported since kind 0.8.0 (https://github.com/kubernetes-sigs/kind/releases/tag/v0.8.0) | ||
const clusterNameEnvKey = "KIND_CLUSTER_NAME" | ||
|
||
// provider is an interface for kind providers to facilitate testing. | ||
type provider interface { | ||
ListInternalNodes(name string) ([]nodes.Node, error) | ||
} | ||
|
||
// GetProvider is a variable so we can override in tests. | ||
var GetProvider = func() provider { | ||
return cluster.NewProvider() | ||
} | ||
|
||
// Tag adds a tag to an already existent image. | ||
func Tag(src, dest name.Tag) error { | ||
return onEachNode(func(n nodes.Node) error { | ||
cmd := n.Command("ctr", "--namespace=k8s.io", "images", "tag", "--force", src.String(), dest.String()) | ||
if err := cmd.Run(); err != nil { | ||
return fmt.Errorf("failed to tag image: %w", err) | ||
} | ||
return nil | ||
}) | ||
} | ||
|
||
// Write saves the image into the kind nodes as the given tag. | ||
func Write(tag name.Tag, img v1.Image) error { | ||
return onEachNode(func(n nodes.Node) error { | ||
pr, pw := io.Pipe() | ||
|
||
grp := errgroup.Group{} | ||
grp.Go(func() error { | ||
return pw.CloseWithError(tarball.Write(tag, img, pw)) | ||
}) | ||
|
||
cmd := n.Command("ctr", "--namespace=k8s.io", "images", "import", "-").SetStdin(pr) | ||
if err := cmd.Run(); err != nil { | ||
return fmt.Errorf("failed to load image to node %q: %w", n, err) | ||
} | ||
|
||
if err := grp.Wait(); err != nil { | ||
return fmt.Errorf("failed to write intermediate tarball representation: %w", err) | ||
} | ||
|
||
return nil | ||
}) | ||
} | ||
|
||
// onEachNode executes the given function on each node. Exits on first error. | ||
func onEachNode(f func(nodes.Node) error) error { | ||
nodeList, err := getNodes() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, n := range nodeList { | ||
if err := f(n); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// getNodes gets all the nodes of the default cluster. | ||
// Returns an error if none were found. | ||
func getNodes() ([]nodes.Node, error) { | ||
provider := GetProvider() | ||
|
||
clusterName := os.Getenv(clusterNameEnvKey) | ||
if clusterName == "" { | ||
clusterName = cluster.DefaultName | ||
} | ||
|
||
nodeList, err := provider.ListInternalNodes(clusterName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if len(nodeList) == 0 { | ||
return nil, fmt.Errorf("no nodes found for cluster %q", cluster.DefaultName) | ||
} | ||
|
||
return nodeList, nil | ||
} |
Oops, something went wrong.