mirror of
https://github.com/ko-build/ko.git
synced 2024-12-03 08:35:34 +02:00
moar fix
This commit is contained in:
parent
ab8152ad0a
commit
4f686b1e6c
8
Gopkg.lock
generated
8
Gopkg.lock
generated
@ -142,13 +142,10 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:9d25404d202ff8f0097f3086b18645b6ac1e6634ab35a193328c5b888776252b"
|
||||
digest = "1:2241fb4f2d265698118f5397b427f3c82c558494c38dcc90376bc1778fc00909"
|
||||
name = "github.com/google/go-containerregistry"
|
||||
packages = [
|
||||
"pkg/authn",
|
||||
"pkg/ko/build",
|
||||
"pkg/ko/publish",
|
||||
"pkg/ko/resolve",
|
||||
"pkg/name",
|
||||
"pkg/v1",
|
||||
"pkg/v1/daemon",
|
||||
@ -611,9 +608,6 @@
|
||||
"github.com/google/go-cmp/cmp",
|
||||
"github.com/google/go-cmp/cmp/cmpopts",
|
||||
"github.com/google/go-containerregistry/pkg/authn",
|
||||
"github.com/google/go-containerregistry/pkg/ko/build",
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish",
|
||||
"github.com/google/go-containerregistry/pkg/ko/resolve",
|
||||
"github.com/google/go-containerregistry/pkg/name",
|
||||
"github.com/google/go-containerregistry/pkg/v1",
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon",
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"encoding/hex"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish"
|
||||
"github.com/google/ko/pkg/publish"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -23,9 +23,9 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/ko/build"
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/ko/pkg/build"
|
||||
"github.com/google/ko/pkg/publish"
|
||||
)
|
||||
|
||||
func qualifyLocalImport(importpath, gopathsrc, pwd string) (string, error) {
|
||||
|
@ -23,10 +23,10 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/ko/build"
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish"
|
||||
"github.com/google/go-containerregistry/pkg/ko/resolve"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/ko/pkg/build"
|
||||
"github.com/google/ko/pkg/publish"
|
||||
"github.com/google/ko/pkg/resolve"
|
||||
"github.com/mattmoor/dep-notify/pkg/graph"
|
||||
)
|
||||
|
||||
|
@ -20,5 +20,5 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: obiwan
|
||||
image: github.com/google/go-containerregistry/cmd/ko/test
|
||||
image: github.com/google/ko/cmd/test
|
||||
restartPolicy: Never
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||
)
|
||||
@ -49,7 +48,7 @@ func init() {
|
||||
}
|
||||
|
||||
func TestDaemon(t *testing.T) {
|
||||
importpath := "github.com/google/go-containerregistry/cmd/ko"
|
||||
importpath := "github.com/google/ko/cmd/ko"
|
||||
img, err := random.Image(1024, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("random.Image() = %v", err)
|
||||
@ -66,7 +65,7 @@ func TestDaemon(t *testing.T) {
|
||||
func TestDaemonTags(t *testing.T) {
|
||||
Tags = nil
|
||||
|
||||
importpath := "github.com/google/go-containerregistry/cmd/ko"
|
||||
importpath := "github.com/google/ko/cmd/ko"
|
||||
img, err := random.Image(1024, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("random.Image() = %v", err)
|
||||
@ -79,7 +78,7 @@ func TestDaemonTags(t *testing.T) {
|
||||
t.Errorf("Publish() = %v, wanted prefix %v", got, want)
|
||||
}
|
||||
|
||||
expected := []string{"ko.local/d502d3a1d9858acbab6106d78a0e05f0:v2.0.0", "ko.local/d502d3a1d9858acbab6106d78a0e05f0:v1.2.3", "ko.local/d502d3a1d9858acbab6106d78a0e05f0:production"}
|
||||
expected := []string{"ko.local/099ba5bcefdead87f92606265fb99ac0:v2.0.0", "ko.local/099ba5bcefdead87f92606265fb99ac0:v1.2.3", "ko.local/099ba5bcefdead87f92606265fb99ac0:production"}
|
||||
|
||||
for i, v := range expected {
|
||||
if Tags[i] != v {
|
||||
|
@ -18,11 +18,11 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/ko/build"
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||
"github.com/google/ko/pkg/build"
|
||||
"github.com/google/ko/pkg/publish"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -20,12 +20,10 @@ import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/google/ko/pkg/build"
|
||||
"github.com/google/ko/pkg/publish"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/ko/build"
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ImageReferences resolves supported references to images within the input yaml
|
||||
|
31
vendor/github.com/google/go-containerregistry/pkg/ko/build/build.go
generated
vendored
31
vendor/github.com/google/go-containerregistry/pkg/ko/build/build.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
// 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 build
|
||||
|
||||
import (
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// Interface abstracts different methods for turning a supported importpath
|
||||
// reference into a v1.Image.
|
||||
type Interface interface {
|
||||
// IsSupportedReference determines whether the given reference is to an importpath reference
|
||||
// that Ko supports building.
|
||||
// TODO(mattmoor): Verify that some base repo: foo.io/bar can be suffixed with this reference and parsed.
|
||||
IsSupportedReference(string) bool
|
||||
|
||||
// Build turns the given importpath reference into a v1.Image containing the Go binary.
|
||||
Build(string) (v1.Image, error)
|
||||
}
|
17
vendor/github.com/google/go-containerregistry/pkg/ko/build/doc.go
generated
vendored
17
vendor/github.com/google/go-containerregistry/pkg/ko/build/doc.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
// 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 build defines methods for building a v1.Image reference from a
|
||||
// Go binary reference.
|
||||
package build
|
75
vendor/github.com/google/go-containerregistry/pkg/ko/build/future.go
generated
vendored
75
vendor/github.com/google/go-containerregistry/pkg/ko/build/future.go
generated
vendored
@ -1,75 +0,0 @@
|
||||
// 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 build
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
func newFuture(work func() (v1.Image, error)) *future {
|
||||
// Create a channel on which to send the result.
|
||||
ch := make(chan *result)
|
||||
// Initiate the actual work, sending its result
|
||||
// along the above channel.
|
||||
go func() {
|
||||
img, err := work()
|
||||
ch <- &result{img: img, err: err}
|
||||
}()
|
||||
// Return a future for the above work. Callers should
|
||||
// call .Get() on this result (as many times as needed).
|
||||
// One of these calls will receive the result, store it,
|
||||
// and close the channel so that the rest of the callers
|
||||
// can consume it.
|
||||
return &future{
|
||||
promise: ch,
|
||||
}
|
||||
}
|
||||
|
||||
type result struct {
|
||||
img v1.Image
|
||||
err error
|
||||
}
|
||||
|
||||
type future struct {
|
||||
m sync.RWMutex
|
||||
|
||||
result *result
|
||||
promise chan *result
|
||||
}
|
||||
|
||||
// Get blocks on the result of the future.
|
||||
func (f *future) Get() (v1.Image, error) {
|
||||
// Block on the promise of a result until we get one.
|
||||
result, ok := <-f.promise
|
||||
if ok {
|
||||
func() {
|
||||
f.m.Lock()
|
||||
defer f.m.Unlock()
|
||||
// If we got the result, then store it so that
|
||||
// others may access it.
|
||||
f.result = result
|
||||
// Close the promise channel so that others
|
||||
// are signaled that the result is available.
|
||||
close(f.promise)
|
||||
}()
|
||||
}
|
||||
|
||||
f.m.RLock()
|
||||
defer f.m.RUnlock()
|
||||
|
||||
return f.result.img, f.result.err
|
||||
}
|
346
vendor/github.com/google/go-containerregistry/pkg/ko/build/gobuild.go
generated
vendored
346
vendor/github.com/google/go-containerregistry/pkg/ko/build/gobuild.go
generated
vendored
@ -1,346 +0,0 @@
|
||||
// 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 build
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"errors"
|
||||
gb "go/build"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
||||
"github.com/google/go-containerregistry/pkg/v1/tarball"
|
||||
)
|
||||
|
||||
const (
|
||||
appDir = "/ko-app"
|
||||
defaultAppFilename = "ko-app"
|
||||
)
|
||||
|
||||
// GetBase takes an importpath and returns a base v1.Image.
|
||||
type GetBase func(string) (v1.Image, error)
|
||||
type builder func(string) (string, error)
|
||||
|
||||
type gobuild struct {
|
||||
getBase GetBase
|
||||
creationTime v1.Time
|
||||
build builder
|
||||
}
|
||||
|
||||
// Option is a functional option for NewGo.
|
||||
type Option func(*gobuildOpener) error
|
||||
|
||||
type gobuildOpener struct {
|
||||
getBase GetBase
|
||||
creationTime v1.Time
|
||||
build builder
|
||||
}
|
||||
|
||||
func (gbo *gobuildOpener) Open() (Interface, error) {
|
||||
if gbo.getBase == nil {
|
||||
return nil, errors.New("a way of providing base images must be specified, see build.WithBaseImages")
|
||||
}
|
||||
return &gobuild{
|
||||
getBase: gbo.getBase,
|
||||
creationTime: gbo.creationTime,
|
||||
build: gbo.build,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewGo returns a build.Interface implementation that:
|
||||
// 1. builds go binaries named by importpath,
|
||||
// 2. containerizes the binary on a suitable base,
|
||||
func NewGo(options ...Option) (Interface, error) {
|
||||
gbo := &gobuildOpener{
|
||||
build: build,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
if err := option(gbo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return gbo.Open()
|
||||
}
|
||||
|
||||
// IsSupportedReference implements build.Interface
|
||||
//
|
||||
// Only valid importpaths that provide commands (i.e., are "package main") are
|
||||
// supported.
|
||||
func (*gobuild) IsSupportedReference(s string) bool {
|
||||
p, err := gb.Import(s, gb.Default.GOPATH, gb.ImportComment)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return p.IsCommand()
|
||||
}
|
||||
|
||||
func build(ip string) (string, error) {
|
||||
tmpDir, err := ioutil.TempDir("", "ko")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
file := filepath.Join(tmpDir, "out")
|
||||
|
||||
cmd := exec.Command("go", "build", "-o", file, ip)
|
||||
|
||||
// Last one wins
|
||||
// TODO(mattmoor): GOARCH=amd64
|
||||
cmd.Env = append(os.Environ(), "CGO_ENABLED=0", "GOOS=linux")
|
||||
|
||||
var output bytes.Buffer
|
||||
cmd.Stderr = &output
|
||||
cmd.Stdout = &output
|
||||
|
||||
log.Printf("Building %s", ip)
|
||||
if err := cmd.Run(); err != nil {
|
||||
os.RemoveAll(tmpDir)
|
||||
log.Printf("Unexpected error running \"go build\": %v\n%v", err, output.String())
|
||||
return "", err
|
||||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func appFilename(importpath string) string {
|
||||
base := filepath.Base(importpath)
|
||||
|
||||
// If we fail to determine a good name from the importpath then use a
|
||||
// safe default.
|
||||
if base == "." || base == string(filepath.Separator) {
|
||||
return defaultAppFilename
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
func tarAddDirectories(tw *tar.Writer, dir string) error {
|
||||
if dir == "." || dir == string(filepath.Separator) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write parent directories first
|
||||
if err := tarAddDirectories(tw, filepath.Dir(dir)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write the directory header to the tarball archive
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
Name: dir,
|
||||
Typeflag: tar.TypeDir,
|
||||
// Use a fixed Mode, so that this isn't sensitive to the directory and umask
|
||||
// under which it was created. Additionally, windows can only set 0222,
|
||||
// 0444, or 0666, none of which are executable.
|
||||
Mode: 0555,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tarBinary(name, binary string) (*bytes.Buffer, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
tw := tar.NewWriter(buf)
|
||||
defer tw.Close()
|
||||
|
||||
// write the parent directories to the tarball archive
|
||||
if err := tarAddDirectories(tw, filepath.Dir(name)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file, err := os.Open(binary)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
header := &tar.Header{
|
||||
Name: name,
|
||||
Size: stat.Size(),
|
||||
Typeflag: tar.TypeReg,
|
||||
// Use a fixed Mode, so that this isn't sensitive to the directory and umask
|
||||
// under which it was created. Additionally, windows can only set 0222,
|
||||
// 0444, or 0666, none of which are executable.
|
||||
Mode: 0555,
|
||||
}
|
||||
// write the header to the tarball archive
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// copy the file data to the tarball
|
||||
if _, err := io.Copy(tw, file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func kodataPath(s string) (string, error) {
|
||||
p, err := gb.Import(s, gb.Default.GOPATH, gb.ImportComment)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(p.Dir, "kodata"), nil
|
||||
}
|
||||
|
||||
// Where kodata lives in the image.
|
||||
const kodataRoot = "/var/run/ko"
|
||||
|
||||
func tarKoData(importpath string) (*bytes.Buffer, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
tw := tar.NewWriter(buf)
|
||||
defer tw.Close()
|
||||
|
||||
root, err := kodataPath(importpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if path == root {
|
||||
// Add an entry for /var/run/ko
|
||||
return tw.WriteHeader(&tar.Header{
|
||||
Name: kodataRoot,
|
||||
Typeflag: tar.TypeDir,
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Skip other directories.
|
||||
if info.Mode().IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Chase symlinks.
|
||||
info, err = os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Open the file to copy it into the tarball.
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Copy the file into the image tarball.
|
||||
newPath := filepath.Join(kodataRoot, path[len(root):])
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
Name: newPath,
|
||||
Size: info.Size(),
|
||||
Typeflag: tar.TypeReg,
|
||||
// Use a fixed Mode, so that this isn't sensitive to the directory and umask
|
||||
// under which it was created. Additionally, windows can only set 0222,
|
||||
// 0444, or 0666, none of which are executable.
|
||||
Mode: 0555,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(tw, file)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// Build implements build.Interface
|
||||
func (gb *gobuild) Build(s string) (v1.Image, error) {
|
||||
// Do the build into a temporary file.
|
||||
file, err := gb.build(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.RemoveAll(filepath.Dir(file))
|
||||
|
||||
var layers []v1.Layer
|
||||
// Create a layer from the kodata directory under this import path.
|
||||
dataLayerBuf, err := tarKoData(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dataLayerBytes := dataLayerBuf.Bytes()
|
||||
dataLayer, err := tarball.LayerFromOpener(func() (io.ReadCloser, error) {
|
||||
return ioutil.NopCloser(bytes.NewBuffer(dataLayerBytes)), nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layers = append(layers, dataLayer)
|
||||
|
||||
appPath := filepath.Join(appDir, appFilename(s))
|
||||
|
||||
// Construct a tarball with the binary and produce a layer.
|
||||
binaryLayerBuf, err := tarBinary(appPath, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
binaryLayerBytes := binaryLayerBuf.Bytes()
|
||||
binaryLayer, err := tarball.LayerFromOpener(func() (io.ReadCloser, error) {
|
||||
return ioutil.NopCloser(bytes.NewBuffer(binaryLayerBytes)), nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layers = append(layers, binaryLayer)
|
||||
|
||||
// Determine the appropriate base image for this import path.
|
||||
base, err := gb.getBase(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Augment the base image with our application layer.
|
||||
withApp, err := mutate.AppendLayers(base, layers...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Start from a copy of the base image's config file, and set
|
||||
// the entrypoint to our app.
|
||||
cfg, err := withApp.ConfigFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg = cfg.DeepCopy()
|
||||
cfg.Config.Entrypoint = []string{appPath}
|
||||
cfg.Config.Env = append(cfg.Config.Env, "KO_DATA_PATH="+kodataRoot)
|
||||
|
||||
image, err := mutate.Config(withApp, cfg.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
empty := v1.Time{}
|
||||
if gb.creationTime != empty {
|
||||
return mutate.CreatedAt(image, gb.creationTime)
|
||||
}
|
||||
return image, nil
|
||||
}
|
46
vendor/github.com/google/go-containerregistry/pkg/ko/build/options.go
generated
vendored
46
vendor/github.com/google/go-containerregistry/pkg/ko/build/options.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
// 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 build
|
||||
|
||||
import (
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// WithBaseImages is a functional option for overriding the base images
|
||||
// that are used for different images.
|
||||
func WithBaseImages(gb GetBase) Option {
|
||||
return func(gbo *gobuildOpener) error {
|
||||
gbo.getBase = gb
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCreationTime is a functional option for overriding the creation
|
||||
// time given to images.
|
||||
func WithCreationTime(t v1.Time) Option {
|
||||
return func(gbo *gobuildOpener) error {
|
||||
gbo.creationTime = t
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// withBuilder is a functional option for overriding the way go binaries
|
||||
// are built. This is exposed for testing.
|
||||
func withBuilder(b builder) Option {
|
||||
return func(gbo *gobuildOpener) error {
|
||||
gbo.build = b
|
||||
return nil
|
||||
}
|
||||
}
|
46
vendor/github.com/google/go-containerregistry/pkg/ko/build/recorder.go
generated
vendored
46
vendor/github.com/google/go-containerregistry/pkg/ko/build/recorder.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
// 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 build
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// Recorder composes with another Interface to record the built import paths.
|
||||
type Recorder struct {
|
||||
m sync.Mutex
|
||||
ImportPaths []string
|
||||
Builder Interface
|
||||
}
|
||||
|
||||
// Recorder implements Interface
|
||||
var _ Interface = (*Recorder)(nil)
|
||||
|
||||
// IsSupportedReference implements Interface
|
||||
func (r *Recorder) IsSupportedReference(ip string) bool {
|
||||
return r.Builder.IsSupportedReference(ip)
|
||||
}
|
||||
|
||||
// Build implements Interface
|
||||
func (r *Recorder) Build(ip string) (v1.Image, error) {
|
||||
func() {
|
||||
r.m.Lock()
|
||||
defer r.m.Unlock()
|
||||
r.ImportPaths = append(r.ImportPaths, ip)
|
||||
}()
|
||||
return r.Builder.Build(ip)
|
||||
}
|
79
vendor/github.com/google/go-containerregistry/pkg/ko/build/shared.go
generated
vendored
79
vendor/github.com/google/go-containerregistry/pkg/ko/build/shared.go
generated
vendored
@ -1,79 +0,0 @@
|
||||
// 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 build
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// Caching wraps a builder implementation in a layer that shares build results
|
||||
// for the same inputs using a simple "future" implementation. Cached results
|
||||
// may be invalidated by calling Invalidate with the same input passed to Build.
|
||||
type Caching struct {
|
||||
inner Interface
|
||||
|
||||
m sync.Mutex
|
||||
results map[string]*future
|
||||
}
|
||||
|
||||
// Caching implements Interface
|
||||
var _ Interface = (*Caching)(nil)
|
||||
|
||||
// NewCaching wraps the provided build.Interface in an implementation that
|
||||
// shares build results for a given path until the result has been invalidated.
|
||||
func NewCaching(inner Interface) (*Caching, error) {
|
||||
return &Caching{
|
||||
inner: inner,
|
||||
results: make(map[string]*future),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Build implements Interface
|
||||
func (c *Caching) Build(ip string) (v1.Image, error) {
|
||||
f := func() *future {
|
||||
// Lock the map of futures.
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
// If a future for "ip" exists, then return it.
|
||||
f, ok := c.results[ip]
|
||||
if ok {
|
||||
return f
|
||||
}
|
||||
// Otherwise create and record a future for a Build of "ip".
|
||||
f = newFuture(func() (v1.Image, error) {
|
||||
return c.inner.Build(ip)
|
||||
})
|
||||
c.results[ip] = f
|
||||
return f
|
||||
}()
|
||||
|
||||
return f.Get()
|
||||
}
|
||||
|
||||
// IsSupportedReference implements Interface
|
||||
func (c *Caching) IsSupportedReference(ip string) bool {
|
||||
return c.inner.IsSupportedReference(ip)
|
||||
}
|
||||
|
||||
// Invalidate removes an import path's cached results.
|
||||
func (c *Caching) Invalidate(ip string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
delete(c.results, ip)
|
||||
}
|
80
vendor/github.com/google/go-containerregistry/pkg/ko/publish/daemon.go
generated
vendored
80
vendor/github.com/google/go-containerregistry/pkg/ko/publish/daemon.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
||||
)
|
||||
|
||||
const (
|
||||
// LocalDomain is a sentinel "registry" that represents side-loading images into the daemon.
|
||||
LocalDomain = "ko.local"
|
||||
)
|
||||
|
||||
// demon is intentionally misspelled to avoid name collision (and drive Jon nuts).
|
||||
type demon struct {
|
||||
namer Namer
|
||||
tags []string
|
||||
}
|
||||
|
||||
// NewDaemon returns a new publish.Interface that publishes images to a container daemon.
|
||||
func NewDaemon(namer Namer, tags []string) Interface {
|
||||
return &demon{namer, tags}
|
||||
}
|
||||
|
||||
// Publish implements publish.Interface
|
||||
func (d *demon) Publish(img v1.Image, s string) (name.Reference, error) {
|
||||
// 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", LocalDomain, d.namer(s), h.Hex), name.WeakValidation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Printf("Loading %v", digestTag)
|
||||
if _, err := daemon.Write(digestTag, img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("Loaded %v", digestTag)
|
||||
|
||||
for _, tagName := range d.tags {
|
||||
log.Printf("Adding tag %v", tagName)
|
||||
tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", LocalDomain, d.namer(s), tagName), name.WeakValidation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = daemon.Tag(digestTag, tag)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("Added tag %v", tagName)
|
||||
}
|
||||
|
||||
return &digestTag, nil
|
||||
}
|
121
vendor/github.com/google/go-containerregistry/pkg/ko/publish/default.go
generated
vendored
121
vendor/github.com/google/go-containerregistry/pkg/ko/publish/default.go
generated
vendored
@ -1,121 +0,0 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
)
|
||||
|
||||
// defalt is intentionally misspelled to avoid keyword collision (and drive Jon nuts).
|
||||
type defalt struct {
|
||||
base string
|
||||
t http.RoundTripper
|
||||
auth authn.Authenticator
|
||||
namer Namer
|
||||
tags []string
|
||||
}
|
||||
|
||||
// Option is a functional option for NewDefault.
|
||||
type Option func(*defaultOpener) error
|
||||
|
||||
type defaultOpener struct {
|
||||
base string
|
||||
t http.RoundTripper
|
||||
auth authn.Authenticator
|
||||
namer Namer
|
||||
tags []string
|
||||
}
|
||||
|
||||
// Namer is a function from a supported import path to the portion of the resulting
|
||||
// image name that follows the "base" repository name.
|
||||
type Namer func(string) string
|
||||
|
||||
// identity is the default namer, so import paths are affixed as-is under the repository
|
||||
// name for maximum clarity, e.g.
|
||||
// gcr.io/foo/github.com/bar/baz/cmd/blah
|
||||
// ^--base--^ ^-------import path-------^
|
||||
func identity(in string) string { return in }
|
||||
|
||||
// As some registries do not support pushing an image by digest, the default tag for pushing
|
||||
// is the 'latest' tag.
|
||||
var defaultTags = []string{"latest"}
|
||||
|
||||
func (do *defaultOpener) Open() (Interface, error) {
|
||||
return &defalt{
|
||||
base: do.base,
|
||||
t: do.t,
|
||||
auth: do.auth,
|
||||
namer: do.namer,
|
||||
tags: do.tags,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDefault returns a new publish.Interface that publishes references under the provided base
|
||||
// repository using the default keychain to authenticate and the default naming scheme.
|
||||
func NewDefault(base string, options ...Option) (Interface, error) {
|
||||
do := &defaultOpener{
|
||||
base: base,
|
||||
t: http.DefaultTransport,
|
||||
auth: authn.Anonymous,
|
||||
namer: identity,
|
||||
tags: defaultTags,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
if err := option(do); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return do.Open()
|
||||
}
|
||||
|
||||
// Publish implements publish.Interface
|
||||
func (d *defalt) Publish(img v1.Image, s string) (name.Reference, error) {
|
||||
// https://github.com/google/go-containerregistry/issues/212
|
||||
s = strings.ToLower(s)
|
||||
|
||||
for _, tagName := range d.tags {
|
||||
tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", d.base, d.namer(s), tagName), name.WeakValidation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Printf("Publishing %v", tag)
|
||||
// TODO: This is slow because we have to load the image multiple times.
|
||||
// Figure out some way to publish the manifest with another tag.
|
||||
if err := remote.Write(tag, img, d.auth, d.t); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
h, err := img.Digest()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dig, err := name.NewDigest(fmt.Sprintf("%s/%s@%s", d.base, d.namer(s), h), name.WeakValidation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("Published %v", dig)
|
||||
return &dig, nil
|
||||
}
|
17
vendor/github.com/google/go-containerregistry/pkg/ko/publish/doc.go
generated
vendored
17
vendor/github.com/google/go-containerregistry/pkg/ko/publish/doc.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
// 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 defines methods for publishing a v1.Image reference and
|
||||
// returning the published digest for embedding back into a Kubernetes yaml.
|
||||
package publish
|
75
vendor/github.com/google/go-containerregistry/pkg/ko/publish/future.go
generated
vendored
75
vendor/github.com/google/go-containerregistry/pkg/ko/publish/future.go
generated
vendored
@ -1,75 +0,0 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
)
|
||||
|
||||
func newFuture(work func() (name.Reference, error)) *future {
|
||||
// Create a channel on which to send the result.
|
||||
ch := make(chan *result)
|
||||
// Initiate the actual work, sending its result
|
||||
// along the above channel.
|
||||
go func() {
|
||||
ref, err := work()
|
||||
ch <- &result{ref: ref, err: err}
|
||||
}()
|
||||
// Return a future for the above work. Callers should
|
||||
// call .Get() on this result (as many times as needed).
|
||||
// One of these calls will receive the result, store it,
|
||||
// and close the channel so that the rest of the callers
|
||||
// can consume it.
|
||||
return &future{
|
||||
promise: ch,
|
||||
}
|
||||
}
|
||||
|
||||
type result struct {
|
||||
ref name.Reference
|
||||
err error
|
||||
}
|
||||
|
||||
type future struct {
|
||||
m sync.RWMutex
|
||||
|
||||
result *result
|
||||
promise chan *result
|
||||
}
|
||||
|
||||
// Get blocks on the result of the future.
|
||||
func (f *future) Get() (name.Reference, error) {
|
||||
// Block on the promise of a result until we get one.
|
||||
result, ok := <-f.promise
|
||||
if ok {
|
||||
func() {
|
||||
f.m.Lock()
|
||||
defer f.m.Unlock()
|
||||
// If we got the result, then store it so that
|
||||
// others may access it.
|
||||
f.result = result
|
||||
// Close the promise channel so that others
|
||||
// are signaled that the result is available.
|
||||
close(f.promise)
|
||||
}()
|
||||
}
|
||||
|
||||
f.m.RLock()
|
||||
defer f.m.RUnlock()
|
||||
|
||||
return f.result.ref, f.result.err
|
||||
}
|
82
vendor/github.com/google/go-containerregistry/pkg/ko/publish/options.go
generated
vendored
82
vendor/github.com/google/go-containerregistry/pkg/ko/publish/options.go
generated
vendored
@ -1,82 +0,0 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
)
|
||||
|
||||
// WithTransport is a functional option for overriding the default transport
|
||||
// on a default publisher.
|
||||
func WithTransport(t http.RoundTripper) Option {
|
||||
return func(i *defaultOpener) error {
|
||||
i.t = t
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuth is a functional option for overriding the default authenticator
|
||||
// on a default publisher.
|
||||
func WithAuth(auth authn.Authenticator) Option {
|
||||
return func(i *defaultOpener) error {
|
||||
i.auth = auth
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuthFromKeychain is a functional option for overriding the default
|
||||
// authenticator on a default publisher using an authn.Keychain
|
||||
func WithAuthFromKeychain(keys authn.Keychain) Option {
|
||||
return func(i *defaultOpener) error {
|
||||
// We parse this lazily because it is a repository prefix, which
|
||||
// means that docker.io/mattmoor actually gets interpreted as
|
||||
// docker.io/library/mattmoor, which gets tricky when we start
|
||||
// appending things to it in the publisher.
|
||||
repo, err := name.NewRepository(i.base, name.WeakValidation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
auth, err := keys.Resolve(repo.Registry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if auth == authn.Anonymous {
|
||||
log.Println("No matching credentials were found, falling back on anonymous")
|
||||
}
|
||||
i.auth = auth
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithNamer is a functional option for overriding the image naming behavior
|
||||
// in our default publisher.
|
||||
func WithNamer(n Namer) Option {
|
||||
return func(i *defaultOpener) error {
|
||||
i.namer = n
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithTags is a functional option for overriding the image tags
|
||||
func WithTags(tags []string) Option {
|
||||
return func(i *defaultOpener) error {
|
||||
i.tags = tags
|
||||
return nil
|
||||
}
|
||||
}
|
28
vendor/github.com/google/go-containerregistry/pkg/ko/publish/publish.go
generated
vendored
28
vendor/github.com/google/go-containerregistry/pkg/ko/publish/publish.go
generated
vendored
@ -1,28 +0,0 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// Interface abstracts different methods for publishing images.
|
||||
type Interface interface {
|
||||
// Publish uploads the given v1.Image to a registry incorporating the
|
||||
// provided string into the image's repository name. Returns the digest
|
||||
// of the published image.
|
||||
Publish(v1.Image, string) (name.Reference, error)
|
||||
}
|
76
vendor/github.com/google/go-containerregistry/pkg/ko/publish/shared.go
generated
vendored
76
vendor/github.com/google/go-containerregistry/pkg/ko/publish/shared.go
generated
vendored
@ -1,76 +0,0 @@
|
||||
// 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
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// caching wraps a publisher implementation in a layer that shares publish results
|
||||
// for the same inputs using a simple "future" implementation.
|
||||
type caching struct {
|
||||
inner Interface
|
||||
|
||||
m sync.Mutex
|
||||
results map[string]*entry
|
||||
}
|
||||
|
||||
// entry holds the last image published and the result of publishing it for a
|
||||
// particular reference.
|
||||
type entry struct {
|
||||
img v1.Image
|
||||
f *future
|
||||
}
|
||||
|
||||
// caching implements Interface
|
||||
var _ Interface = (*caching)(nil)
|
||||
|
||||
// NewCaching wraps the provided publish.Interface in an implementation that
|
||||
// shares publish results for a given path until the passed image object changes.
|
||||
func NewCaching(inner Interface) (Interface, error) {
|
||||
return &caching{
|
||||
inner: inner,
|
||||
results: make(map[string]*entry),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Publish implements Interface
|
||||
func (c *caching) Publish(img v1.Image, ref string) (name.Reference, error) {
|
||||
f := func() *future {
|
||||
// Lock the map of futures.
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
// If a future for "ref" exists, then return it.
|
||||
ent, ok := c.results[ref]
|
||||
if ok {
|
||||
// If the image matches, then return the same future.
|
||||
if ent.img == img {
|
||||
return ent.f
|
||||
}
|
||||
}
|
||||
// Otherwise create and record a future for publishing "img" to "ref".
|
||||
f := newFuture(func() (name.Reference, error) {
|
||||
return c.inner.Publish(img, ref)
|
||||
})
|
||||
c.results[ref] = &entry{img: img, f: f}
|
||||
return f
|
||||
}()
|
||||
|
||||
return f.Get()
|
||||
}
|
16
vendor/github.com/google/go-containerregistry/pkg/ko/resolve/doc.go
generated
vendored
16
vendor/github.com/google/go-containerregistry/pkg/ko/resolve/doc.go
generated
vendored
@ -1,16 +0,0 @@
|
||||
// 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 resolve defines logic for resolving K8s yaml inputs to ko.
|
||||
package resolve
|
160
vendor/github.com/google/go-containerregistry/pkg/ko/resolve/resolve.go
generated
vendored
160
vendor/github.com/google/go-containerregistry/pkg/ko/resolve/resolve.go
generated
vendored
@ -1,160 +0,0 @@
|
||||
// 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 resolve
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/ko/build"
|
||||
"github.com/google/go-containerregistry/pkg/ko/publish"
|
||||
)
|
||||
|
||||
// ImageReferences resolves supported references to images within the input yaml
|
||||
// to published image digests.
|
||||
func ImageReferences(input []byte, builder build.Interface, publisher publish.Interface) ([]byte, error) {
|
||||
// First, walk the input objects and collect a list of supported references
|
||||
refs := make(map[string]struct{})
|
||||
// The loop is to support multi-document yaml files.
|
||||
// This is handled by using a yaml.Decoder and reading objects until io.EOF, see:
|
||||
// https://github.com/go-yaml/yaml/blob/v2.2.1/yaml.go#L124
|
||||
decoder := yaml.NewDecoder(bytes.NewBuffer(input))
|
||||
for {
|
||||
var obj interface{}
|
||||
if err := decoder.Decode(&obj); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
// This simply returns the replaced object, which we discard during the gathering phase.
|
||||
if _, err := replaceRecursive(obj, func(ref string) (string, error) {
|
||||
if builder.IsSupportedReference(ref) {
|
||||
refs[ref] = struct{}{}
|
||||
}
|
||||
return ref, nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Next, perform parallel builds for each of the supported references.
|
||||
var sm sync.Map
|
||||
var errg errgroup.Group
|
||||
for ref := range refs {
|
||||
ref := ref
|
||||
errg.Go(func() error {
|
||||
img, err := builder.Build(ref)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
digest, err := publisher.Publish(img, ref)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sm.Store(ref, digest.String())
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if err := errg.Wait(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Last, walk the inputs again and replace the supported references with their published images.
|
||||
decoder = yaml.NewDecoder(bytes.NewBuffer(input))
|
||||
buf := bytes.NewBuffer(nil)
|
||||
encoder := yaml.NewEncoder(buf)
|
||||
for {
|
||||
var obj interface{}
|
||||
if err := decoder.Decode(&obj); err != nil {
|
||||
if err == io.EOF {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
// Recursively walk input, replacing supported reference with our computed digests.
|
||||
obj2, err := replaceRecursive(obj, func(ref string) (string, error) {
|
||||
if !builder.IsSupportedReference(ref) {
|
||||
return ref, nil
|
||||
}
|
||||
if val, ok := sm.Load(ref); ok {
|
||||
return val.(string), nil
|
||||
}
|
||||
return "", fmt.Errorf("resolved reference to %q not found", ref)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := encoder.Encode(obj2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type replaceString func(string) (string, error)
|
||||
|
||||
// replaceRecursive walks the provided untyped object recursively by switching
|
||||
// on the type of the object at each level. It supports walking through the
|
||||
// keys and values of maps, and the elements of an array. When a leaf of type
|
||||
// string is encountered, this will call the provided replaceString function on
|
||||
// it. This function does not support walking through struct types, but also
|
||||
// should not need to as the input is expected to be the result of parsing yaml
|
||||
// or json into an interface{}, which should only produce primitives, maps and
|
||||
// arrays. This function will return a copy of the object rebuilt by the walk
|
||||
// with the replacements made.
|
||||
func replaceRecursive(obj interface{}, rs replaceString) (interface{}, error) {
|
||||
switch typed := obj.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
m2 := make(map[interface{}]interface{}, len(typed))
|
||||
for k, v := range typed {
|
||||
k2, err := replaceRecursive(k, rs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v2, err := replaceRecursive(v, rs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m2[k2] = v2
|
||||
}
|
||||
return m2, nil
|
||||
|
||||
case []interface{}:
|
||||
a2 := make([]interface{}, len(typed))
|
||||
for idx, v := range typed {
|
||||
v2, err := replaceRecursive(v, rs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a2[idx] = v2
|
||||
}
|
||||
return a2, nil
|
||||
|
||||
case string:
|
||||
// call our replaceString on this string leaf.
|
||||
return rs(typed)
|
||||
|
||||
default:
|
||||
// leave other leaves alone.
|
||||
return typed, nil
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user