Merge pull request #1221 from antechrestos/refactoring/default_transport
Remove direct use of DefaultTransport
This commit is contained in:
commit
d86e09bac1
|
|
@ -17,9 +17,7 @@ limitations under the License.
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -27,6 +25,7 @@ import (
|
||||||
|
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/creds"
|
"github.com/GoogleContainerTools/kaniko/pkg/creds"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
|
|
@ -67,12 +66,7 @@ func (rc *RegistryCache) RetrieveLayer(ck string) (v1.Image, error) {
|
||||||
cacheRef.Repository.Registry = newReg
|
cacheRef.Repository.Registry = newReg
|
||||||
}
|
}
|
||||||
|
|
||||||
tr := http.DefaultTransport.(*http.Transport)
|
tr := util.MakeTransport(rc.Opts, registryName)
|
||||||
if rc.Opts.SkipTLSVerifyRegistries.Contains(registryName) {
|
|
||||||
tr.TLSClientConfig = &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img, err := remote.Image(cacheRef, remote.WithTransport(tr), remote.WithAuthFromKeychain(creds.GetKeychain()))
|
img, err := remote.Image(cacheRef, remote.WithTransport(tr), remote.WithAuthFromKeychain(creds.GetKeychain()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ import (
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||||
|
image_util "github.com/GoogleContainerTools/kaniko/pkg/image"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/snapshot"
|
"github.com/GoogleContainerTools/kaniko/pkg/snapshot"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||||
|
|
@ -84,7 +85,7 @@ type stageBuilder struct {
|
||||||
|
|
||||||
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
|
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
|
||||||
func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dcm map[string]string, sid map[string]string, stageNameToIdx map[string]string) (*stageBuilder, error) {
|
func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dcm map[string]string, sid map[string]string, stageNameToIdx map[string]string) (*stageBuilder, error) {
|
||||||
sourceImage, err := util.RetrieveSourceImage(stage, opts)
|
sourceImage, err := image_util.RetrieveSourceImage(stage, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -517,7 +518,7 @@ func CalculateDependencies(stages []config.KanikoStage, opts *config.KanikoOptio
|
||||||
} else if s.Name == constants.NoBaseImage {
|
} else if s.Name == constants.NoBaseImage {
|
||||||
image = empty.Image
|
image = empty.Image
|
||||||
} else {
|
} else {
|
||||||
image, err = util.RetrieveSourceImage(s, opts)
|
image, err = image_util.RetrieveSourceImage(s, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -751,7 +752,7 @@ func fetchExtraStages(stages []config.KanikoStage, opts *config.KanikoOptions) e
|
||||||
|
|
||||||
// This must be an image name, fetch it.
|
// This must be an image name, fetch it.
|
||||||
logrus.Debugf("Found extra base image stage %s", c.From)
|
logrus.Debugf("Found extra base image stage %s", c.From)
|
||||||
sourceImage, err := util.RetrieveRemoteImage(c.From, opts)
|
sourceImage, err := image_util.RetrieveRemoteImage(c.From, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
||||||
package executor
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
@ -34,6 +32,7 @@ import (
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/creds"
|
"github.com/GoogleContainerTools/kaniko/pkg/creds"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/version"
|
"github.com/GoogleContainerTools/kaniko/pkg/version"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
|
@ -48,15 +47,15 @@ import (
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type withUserAgent struct {
|
||||||
|
t http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
// for testing
|
// for testing
|
||||||
var (
|
var (
|
||||||
newRetry = transport.NewRetry
|
newRetry = transport.NewRetry
|
||||||
)
|
)
|
||||||
|
|
||||||
type withUserAgent struct {
|
|
||||||
t http.RoundTripper
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UpstreamClientUaKey = "UPSTREAM_CLIENT_TYPE"
|
UpstreamClientUaKey = "UPSTREAM_CLIENT_TYPE"
|
||||||
)
|
)
|
||||||
|
|
@ -82,41 +81,6 @@ func (w *withUserAgent) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
return w.t.RoundTrip(r)
|
return w.t.RoundTrip(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CertPool interface {
|
|
||||||
value() *x509.CertPool
|
|
||||||
append(path string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type X509CertPool struct {
|
|
||||||
inner x509.CertPool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *X509CertPool) value() *x509.CertPool {
|
|
||||||
return &p.inner
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *X509CertPool) append(path string) error {
|
|
||||||
pem, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.inner.AppendCertsFromPEM(pem)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type systemCertLoader func() CertPool
|
|
||||||
|
|
||||||
var defaultX509Handler systemCertLoader = func() CertPool {
|
|
||||||
systemCertPool, err := x509.SystemCertPool()
|
|
||||||
if err != nil {
|
|
||||||
logrus.Warn("Failed to load system cert pool. Loading empty one instead.")
|
|
||||||
systemCertPool = x509.NewCertPool()
|
|
||||||
}
|
|
||||||
return &X509CertPool{
|
|
||||||
inner: *systemCertPool,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for testing
|
// for testing
|
||||||
var (
|
var (
|
||||||
fs = afero.NewOsFs()
|
fs = afero.NewOsFs()
|
||||||
|
|
@ -161,7 +125,7 @@ func CheckPushPermissions(opts *config.KanikoOptions) error {
|
||||||
}
|
}
|
||||||
destRef.Repository.Registry = newReg
|
destRef.Repository.Registry = newReg
|
||||||
}
|
}
|
||||||
tr := makeTransport(opts, registryName, defaultX509Handler)
|
tr := newRetry(util.MakeTransport(opts, registryName))
|
||||||
if err := checkRemotePushPermission(destRef, creds.GetKeychain(), tr); err != nil {
|
if err := checkRemotePushPermission(destRef, creds.GetKeychain(), tr); err != nil {
|
||||||
return errors.Wrapf(err, "checking push permission for %q", destRef)
|
return errors.Wrapf(err, "checking push permission for %q", destRef)
|
||||||
}
|
}
|
||||||
|
|
@ -258,7 +222,7 @@ func DoPush(image v1.Image, opts *config.KanikoOptions) error {
|
||||||
return errors.Wrap(err, "resolving pushAuth")
|
return errors.Wrap(err, "resolving pushAuth")
|
||||||
}
|
}
|
||||||
|
|
||||||
tr := makeTransport(opts, registryName, defaultX509Handler)
|
tr := newRetry(util.MakeTransport(opts, registryName))
|
||||||
rt := &withUserAgent{t: tr}
|
rt := &withUserAgent{t: tr}
|
||||||
|
|
||||||
if err := remote.Write(destRef, image, remote.WithAuth(pushAuth), remote.WithTransport(rt)); err != nil {
|
if err := remote.Write(destRef, image, remote.WithAuth(pushAuth), remote.WithTransport(rt)); err != nil {
|
||||||
|
|
@ -300,26 +264,6 @@ func writeImageOutputs(image v1.Image, destRefs []name.Tag) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTransport(opts *config.KanikoOptions, registryName string, loader systemCertLoader) http.RoundTripper {
|
|
||||||
// Create a transport to set our user-agent.
|
|
||||||
var tr http.RoundTripper = http.DefaultTransport.(*http.Transport).Clone()
|
|
||||||
if opts.SkipTLSVerify || opts.SkipTLSVerifyRegistries.Contains(registryName) {
|
|
||||||
tr.(*http.Transport).TLSClientConfig = &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
}
|
|
||||||
} else if certificatePath := opts.RegistriesCertificates[registryName]; certificatePath != "" {
|
|
||||||
systemCertPool := loader()
|
|
||||||
if err := systemCertPool.append(certificatePath); err != nil {
|
|
||||||
logrus.WithError(err).Warnf("Failed to load certificate %s for %s\n", certificatePath, registryName)
|
|
||||||
} else {
|
|
||||||
tr.(*http.Transport).TLSClientConfig = &tls.Config{
|
|
||||||
RootCAs: systemCertPool.value(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newRetry(tr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pushLayerToCache pushes layer (tagged with cacheKey) to opts.Cache
|
// pushLayerToCache pushes layer (tagged with cacheKey) to opts.Cache
|
||||||
// if opts.Cache doesn't exist, infer the cache from the given destination
|
// if opts.Cache doesn't exist, infer the cache from the given destination
|
||||||
func pushLayerToCache(opts *config.KanikoOptions, cacheKey string, tarPath string, createdBy string) error {
|
func pushLayerToCache(opts *config.KanikoOptions, cacheKey string, tarPath string, createdBy string) error {
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@ package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -34,7 +32,6 @@ import (
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/random"
|
"github.com/google/go-containerregistry/pkg/v1/random"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/validate"
|
"github.com/google/go-containerregistry/pkg/v1/validate"
|
||||||
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
|
|
@ -272,103 +269,6 @@ func TestImageNameDigestFile(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockedCertPool struct {
|
|
||||||
certificatesPath []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockedCertPool) value() *x509.CertPool {
|
|
||||||
return &x509.CertPool{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *mockedCertPool) append(path string) error {
|
|
||||||
m.certificatesPath = append(m.certificatesPath, path)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type retryTransport struct {
|
|
||||||
inner http.RoundTripper
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *retryTransport) RoundTrip(in *http.Request) (out *http.Response, err error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_makeTransport(t *testing.T) {
|
|
||||||
registryName := "my.registry.name"
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
opts *config.KanikoOptions
|
|
||||||
check func(*tls.Config, *mockedCertPool)
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "SkipTLSVerify set",
|
|
||||||
opts: &config.KanikoOptions{SkipTLSVerify: true},
|
|
||||||
check: func(config *tls.Config, pool *mockedCertPool) {
|
|
||||||
if !config.InsecureSkipVerify {
|
|
||||||
t.Errorf("makeTransport().TLSClientConfig.InsecureSkipVerify not set while SkipTLSVerify set")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "SkipTLSVerifyRegistries set with expected registry",
|
|
||||||
opts: &config.KanikoOptions{SkipTLSVerifyRegistries: []string{registryName}},
|
|
||||||
check: func(config *tls.Config, pool *mockedCertPool) {
|
|
||||||
if !config.InsecureSkipVerify {
|
|
||||||
t.Errorf("makeTransport().TLSClientConfig.InsecureSkipVerify not set while SkipTLSVerifyRegistries set with registry name")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "SkipTLSVerifyRegistries set with other registry",
|
|
||||||
opts: &config.KanikoOptions{SkipTLSVerifyRegistries: []string{fmt.Sprintf("other.%s", registryName)}},
|
|
||||||
check: func(config *tls.Config, pool *mockedCertPool) {
|
|
||||||
if config.InsecureSkipVerify {
|
|
||||||
t.Errorf("makeTransport().TLSClientConfig.InsecureSkipVerify set while SkipTLSVerifyRegistries not set with registry name")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "RegistriesCertificates set for registry",
|
|
||||||
opts: &config.KanikoOptions{RegistriesCertificates: map[string]string{registryName: "/path/to/the/certificate.cert"}},
|
|
||||||
check: func(config *tls.Config, pool *mockedCertPool) {
|
|
||||||
if len(pool.certificatesPath) != 1 || pool.certificatesPath[0] != "/path/to/the/certificate.cert" {
|
|
||||||
t.Errorf("makeTransport().RegistriesCertificates certificate not appended to system certificates")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "RegistriesCertificates set for another registry",
|
|
||||||
opts: &config.KanikoOptions{RegistriesCertificates: map[string]string{fmt.Sprintf("other.%s=", registryName): "/path/to/the/certificate.cert"}},
|
|
||||||
check: func(config *tls.Config, pool *mockedCertPool) {
|
|
||||||
if len(pool.certificatesPath) != 0 {
|
|
||||||
t.Errorf("makeTransport().RegistriesCertificates certificate appended to system certificates while added for other registry")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
originalRetry := newRetry
|
|
||||||
newRetry = func(inner http.RoundTripper, _ ...transport.Option) http.RoundTripper {
|
|
||||||
return &retryTransport{
|
|
||||||
inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
defer func() { newRetry = originalRetry }()
|
|
||||||
var certificatesPath []string
|
|
||||||
certPool := mockedCertPool{
|
|
||||||
certificatesPath: certificatesPath,
|
|
||||||
}
|
|
||||||
var mockedSystemCertLoader systemCertLoader = func() CertPool {
|
|
||||||
return &certPool
|
|
||||||
}
|
|
||||||
actual := makeTransport(tt.opts, registryName, mockedSystemCertLoader)
|
|
||||||
tt.check(actual.(*retryTransport).inner.(*http.Transport).TLSClientConfig, &certPool)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var calledExecCommand = false
|
var calledExecCommand = false
|
||||||
var calledCheckPushPermission = false
|
var calledCheckPushPermission = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 Google LLC
|
|
||||||
|
|
||||||
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 image
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetEnvVariables sets environment variables as specified in the image
|
|
||||||
func SetEnvVariables(img v1.Image) error {
|
|
||||||
cfg, err := img.ConfigFile()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
envVars := cfg.Config.Env
|
|
||||||
for _, envVar := range envVars {
|
|
||||||
split := strings.SplitN(envVar, "=", 2)
|
|
||||||
if err := os.Setenv(split[0], split[1]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logrus.Infof("Setting environment variable %s", envVar)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -14,29 +14,28 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
"github.com/GoogleContainerTools/kaniko/pkg/cache"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/creds"
|
"github.com/GoogleContainerTools/kaniko/pkg/creds"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||||
|
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
"github.com/google/go-containerregistry/pkg/v1/empty"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/tarball"
|
"github.com/google/go-containerregistry/pkg/v1/tarball"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/cache"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -55,7 +54,7 @@ func RetrieveSourceImage(stage config.KanikoStage, opts *config.KanikoOptions) (
|
||||||
buildArgs = append(buildArgs, fmt.Sprintf("%s=%s", arg.Key, arg.ValueString()))
|
buildArgs = append(buildArgs, fmt.Sprintf("%s=%s", arg.Key, arg.ValueString()))
|
||||||
}
|
}
|
||||||
buildArgs = append(buildArgs, opts.BuildArgs...)
|
buildArgs = append(buildArgs, opts.BuildArgs...)
|
||||||
currentBaseName, err := ResolveEnvironmentReplacement(stage.BaseName, buildArgs, false)
|
currentBaseName, err := util.ResolveEnvironmentReplacement(stage.BaseName, buildArgs, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -146,12 +145,7 @@ func remoteImage(image string, opts *config.KanikoOptions) (v1.Image, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func remoteOptions(registryName string, opts *config.KanikoOptions) []remote.Option {
|
func remoteOptions(registryName string, opts *config.KanikoOptions) []remote.Option {
|
||||||
tr := http.DefaultTransport.(*http.Transport)
|
tr := util.MakeTransport(opts, registryName)
|
||||||
if opts.SkipTLSVerifyPull || opts.SkipTLSVerifyRegistries.Contains(registryName) {
|
|
||||||
tr.TLSClientConfig = &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// on which v1.Platform is this currently running?
|
// on which v1.Platform is this currently running?
|
||||||
platform := currentPlatform()
|
platform := currentPlatform()
|
||||||
|
|
@ -182,3 +176,11 @@ func cachedImage(opts *config.KanikoOptions, image string) (v1.Image, error) {
|
||||||
}
|
}
|
||||||
return cache.LocalSource(&opts.CacheOptions, cacheKey)
|
return cache.LocalSource(&opts.CacheOptions, cacheKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentPlatform returns the v1.Platform on which the code runs
|
||||||
|
func currentPlatform() v1.Platform {
|
||||||
|
return v1.Platform{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
Architecture: runtime.GOARCH,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,18 +14,19 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package util
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
|
||||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
"github.com/google/go-containerregistry/pkg/v1/empty"
|
||||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||||
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
||||||
|
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 Google LLC
|
||||||
|
|
||||||
|
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 util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CertPool interface {
|
||||||
|
value() *x509.CertPool
|
||||||
|
append(path string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type X509CertPool struct {
|
||||||
|
inner x509.CertPool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *X509CertPool) value() *x509.CertPool {
|
||||||
|
return &p.inner
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *X509CertPool) append(path string) error {
|
||||||
|
pem, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.inner.AppendCertsFromPEM(pem)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var systemCertLoader CertPool
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
systemCertPool, err := x509.SystemCertPool()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warn("Failed to load system cert pool. Loading empty one instead.")
|
||||||
|
systemCertPool = x509.NewCertPool()
|
||||||
|
}
|
||||||
|
systemCertLoader = &X509CertPool{
|
||||||
|
inner: *systemCertPool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeTransport(opts *config.KanikoOptions, registryName string) http.RoundTripper {
|
||||||
|
// Create a transport to set our user-agent.
|
||||||
|
var tr http.RoundTripper = http.DefaultTransport.(*http.Transport).Clone()
|
||||||
|
if opts.SkipTLSVerify || opts.SkipTLSVerifyRegistries.Contains(registryName) {
|
||||||
|
tr.(*http.Transport).TLSClientConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
} else if certificatePath := opts.RegistriesCertificates[registryName]; certificatePath != "" {
|
||||||
|
if err := systemCertLoader.append(certificatePath); err != nil {
|
||||||
|
logrus.WithError(err).Warnf("Failed to load certificate %s for %s\n", certificatePath, registryName)
|
||||||
|
} else {
|
||||||
|
tr.(*http.Transport).TLSClientConfig = &tls.Config{
|
||||||
|
RootCAs: systemCertLoader.value(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tr
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
Copyright 2020 Google LLC
|
||||||
|
|
||||||
|
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 util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockedCertPool struct {
|
||||||
|
certificatesPath []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockedCertPool) value() *x509.CertPool {
|
||||||
|
return &x509.CertPool{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockedCertPool) append(path string) error {
|
||||||
|
m.certificatesPath = append(m.certificatesPath, path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_makeTransport(t *testing.T) {
|
||||||
|
registryName := "my.registry.name"
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
opts *config.KanikoOptions
|
||||||
|
check func(*tls.Config, *mockedCertPool)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "SkipTLSVerify set",
|
||||||
|
opts: &config.KanikoOptions{SkipTLSVerify: true},
|
||||||
|
check: func(config *tls.Config, pool *mockedCertPool) {
|
||||||
|
if !config.InsecureSkipVerify {
|
||||||
|
t.Errorf("makeTransport().TLSClientConfig.InsecureSkipVerify not set while SkipTLSVerify set")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SkipTLSVerifyRegistries set with expected registry",
|
||||||
|
opts: &config.KanikoOptions{SkipTLSVerifyRegistries: []string{registryName}},
|
||||||
|
check: func(config *tls.Config, pool *mockedCertPool) {
|
||||||
|
if !config.InsecureSkipVerify {
|
||||||
|
t.Errorf("makeTransport().TLSClientConfig.InsecureSkipVerify not set while SkipTLSVerifyRegistries set with registry name")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "SkipTLSVerifyRegistries set with other registry",
|
||||||
|
opts: &config.KanikoOptions{SkipTLSVerifyRegistries: []string{fmt.Sprintf("other.%s", registryName)}},
|
||||||
|
check: func(config *tls.Config, pool *mockedCertPool) {
|
||||||
|
if config.InsecureSkipVerify {
|
||||||
|
t.Errorf("makeTransport().TLSClientConfig.InsecureSkipVerify set while SkipTLSVerifyRegistries not set with registry name")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "RegistriesCertificates set for registry",
|
||||||
|
opts: &config.KanikoOptions{RegistriesCertificates: map[string]string{registryName: "/path/to/the/certificate.cert"}},
|
||||||
|
check: func(config *tls.Config, pool *mockedCertPool) {
|
||||||
|
if len(pool.certificatesPath) != 1 || pool.certificatesPath[0] != "/path/to/the/certificate.cert" {
|
||||||
|
t.Errorf("makeTransport().RegistriesCertificates certificate not appended to system certificates")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "RegistriesCertificates set for another registry",
|
||||||
|
opts: &config.KanikoOptions{RegistriesCertificates: map[string]string{fmt.Sprintf("other.%s=", registryName): "/path/to/the/certificate.cert"}},
|
||||||
|
check: func(config *tls.Config, pool *mockedCertPool) {
|
||||||
|
if len(pool.certificatesPath) != 0 {
|
||||||
|
t.Errorf("makeTransport().RegistriesCertificates certificate appended to system certificates while added for other registry")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
savedSystemCertLoader := systemCertLoader
|
||||||
|
defer func() { systemCertLoader = savedSystemCertLoader }()
|
||||||
|
for _, tt := range tests {
|
||||||
|
var certificatesPath []string
|
||||||
|
certPool := &mockedCertPool{
|
||||||
|
certificatesPath: certificatesPath,
|
||||||
|
}
|
||||||
|
systemCertLoader = certPool
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tr := MakeTransport(tt.opts, registryName)
|
||||||
|
tt.check(tr.(*http.Transport).TLSClientConfig, certPool)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,14 +23,11 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/minio/highwayhash"
|
"github.com/minio/highwayhash"
|
||||||
|
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hasher returns a hash function, used in snapshotting to determine if a file has changed
|
// Hasher returns a hash function, used in snapshotting to determine if a file has changed
|
||||||
|
|
@ -128,14 +125,6 @@ func SHA256(r io.Reader) (string, error) {
|
||||||
return hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))), nil
|
return hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentPlatform returns the v1.Platform on which the code runs
|
|
||||||
func currentPlatform() v1.Platform {
|
|
||||||
return v1.Platform{
|
|
||||||
OS: runtime.GOOS,
|
|
||||||
Architecture: runtime.GOARCH,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInputFrom returns Reader content
|
// GetInputFrom returns Reader content
|
||||||
func GetInputFrom(r io.Reader) ([]byte, error) {
|
func GetInputFrom(r io.Reader) ([]byte, error) {
|
||||||
output, err := ioutil.ReadAll(r)
|
output, err := ioutil.ReadAll(r)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue