diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 08c74beb9..c005cd159 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -23,8 +23,7 @@ import ( "time" "github.com/GoogleContainerTools/kaniko/pkg/config" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/authn/k8schain" + "github.com/GoogleContainerTools/kaniko/pkg/creds" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/remote" @@ -55,12 +54,7 @@ func (rc *RegistryCache) RetrieveLayer(ck string) (v1.Image, error) { if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("getting reference for %s", cache)) } - k8sc, err := k8schain.NewNoClient() - if err != nil { - return nil, err - } - kc := authn.NewMultiKeychain(authn.DefaultKeychain, k8sc) - img, err := remote.Image(cacheRef, remote.WithAuthFromKeychain(kc)) + img, err := remote.Image(cacheRef, remote.WithAuthFromKeychain(creds.GetKeychain())) if err != nil { return nil, err } diff --git a/pkg/creds/creds_darwin.go b/pkg/creds/creds_darwin.go new file mode 100644 index 000000000..e3bdb2c94 --- /dev/null +++ b/pkg/creds/creds_darwin.go @@ -0,0 +1,36 @@ +/* +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 creds + +import ( + "sync" + + "github.com/google/go-containerregistry/pkg/authn" +) + +var ( + setupKeyChainOnce sync.Once + keyChain authn.Keychain +) + +// GetKeychain returns a keychain for accessing container registries. +func GetKeychain() authn.Keychain { + setupKeyChainOnce.Do(func() { + keyChain = authn.NewMultiKeychain(authn.DefaultKeychain) + }) + return keyChain +} diff --git a/pkg/creds/creds_linux.go b/pkg/creds/creds_linux.go new file mode 100644 index 000000000..3ced3e6c2 --- /dev/null +++ b/pkg/creds/creds_linux.go @@ -0,0 +1,54 @@ +/* +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 creds + +import ( + "sync" + + "github.com/genuinetools/amicontained/container" + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/authn/k8schain" + "github.com/sirupsen/logrus" +) + +var ( + setupKeyChainOnce sync.Once + keyChain authn.Keychain +) + +// GetKeychain returns a keychain for accessing container registries. +func GetKeychain() authn.Keychain { + setupKeyChainOnce.Do(func() { + keyChain = authn.NewMultiKeychain(authn.DefaultKeychain) + + // Add the Kubernetes keychain if we're on Kubernetes + r, err := container.DetectRuntime() + if err != nil { + logrus.Warnf("Error detecting container runtime. Using default keychain: %s", err) + return + } + if r == container.RuntimeKubernetes { + k8sc, err := k8schain.NewNoClient() + if err != nil { + logrus.Warnf("Error setting up k8schain. Using default keychain %s", err) + return + } + keyChain = authn.NewMultiKeychain(keyChain, k8sc) + } + }) + return keyChain +} diff --git a/pkg/executor/push.go b/pkg/executor/push.go index 77c0d0ee7..a0956adcf 100644 --- a/pkg/executor/push.go +++ b/pkg/executor/push.go @@ -25,10 +25,9 @@ import ( "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/timing" "github.com/GoogleContainerTools/kaniko/pkg/version" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/authn/k8schain" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/empty" @@ -82,12 +81,7 @@ func DoPush(image v1.Image, opts *config.KanikoOptions) error { destRef.Repository.Registry = newReg } - k8sc, err := k8schain.NewNoClient() - if err != nil { - return errors.Wrap(err, "getting k8schain client") - } - kc := authn.NewMultiKeychain(authn.DefaultKeychain, k8sc) - pushAuth, err := kc.Resolve(destRef.Context().Registry) + pushAuth, err := creds.GetKeychain().Resolve(destRef.Context().Registry) if err != nil { return errors.Wrap(err, "resolving pushAuth") } diff --git a/pkg/util/image_util.go b/pkg/util/image_util.go index 03dd1a442..9a870a830 100644 --- a/pkg/util/image_util.go +++ b/pkg/util/image_util.go @@ -23,8 +23,8 @@ import ( "path/filepath" "strconv" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/authn/k8schain" + "github.com/GoogleContainerTools/kaniko/pkg/creds" + "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/empty" @@ -130,12 +130,7 @@ func remoteImage(image string, opts *config.KanikoOptions, forceNoCache bool) (v } } - k8sc, err := k8schain.NewNoClient() - if err != nil { - return nil, err - } - kc := authn.NewMultiKeychain(authn.DefaultKeychain, k8sc) - return remote.Image(ref, remote.WithTransport(tr), remote.WithAuthFromKeychain(kc)) + return remote.Image(ref, remote.WithTransport(tr), remote.WithAuthFromKeychain(creds.GetKeychain())) } func cachedImage(opts *config.KanikoOptions, image string) (v1.Image, error) {