
Automatic merge from submit-queue (batch tested with PRs 57824, 58806, 59410, 59280). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. 2nd try at using a vanity GCR name The 2nd commit here is the changes relative to the reverted PR. Please focus review attention on that. This is the 2nd attempt. The previous try (#57573) was reverted while we figured out the regional mirrors (oops). New plan: k8s.gcr.io is a read-only facade that auto-detects your source region (us, eu, or asia for now) and pulls from the closest. To publish an image, push k8s-staging.gcr.io and it will be synced to the regionals automatically (similar to today). For now the staging is an alias to gcr.io/google_containers (the legacy URL). When we move off of google-owned projects (working on it), then we just do a one-time sync, and change the google-internal config, and nobody outside should notice. We can, in parallel, change the auto-sync into a manual sync - send a PR to "promote" something from staging, and a bot activates it. Nice and visible, easy to keep track of. xref https://github.com/kubernetes/release/issues/281 TL;DR: * The new `staging-k8s.gcr.io` is where we push images. It is literally an alias to `gcr.io/google_containers` (the existing repo) and is hosted in the US. * The contents of `staging-k8s.gcr.io` are automatically synced to `{asia,eu,us)-k8s.gcr.io`. * The new `k8s.gcr.io` will be a read-only alias to whichever regional repo is closest to you. * In the future, images will be promoted from `staging` to regional "prod" more explicitly and auditably. ```release-note Use "k8s.gcr.io" for pulling container images rather than "gcr.io/google_containers". Images are already synced, so this should not impact anyone materially. Documentation and tools should all convert to the new name. Users should take note of this in case they see this new name in the system. ```
151 lines
4.2 KiB
Go
151 lines
4.2 KiB
Go
/*
|
|
Copyright 2016 The Kubernetes Authors.
|
|
|
|
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 e2e_node
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"os/user"
|
|
"time"
|
|
|
|
"github.com/golang/glog"
|
|
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
|
internalapi "k8s.io/kubernetes/pkg/kubelet/apis/cri"
|
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
|
commontest "k8s.io/kubernetes/test/e2e/common"
|
|
"k8s.io/kubernetes/test/e2e/framework"
|
|
imageutils "k8s.io/kubernetes/test/utils/image"
|
|
)
|
|
|
|
const (
|
|
// Number of attempts to pull an image.
|
|
maxImagePullRetries = 5
|
|
// Sleep duration between image pull retry attempts.
|
|
imagePullRetryDelay = time.Second
|
|
)
|
|
|
|
// NodeImageWhiteList is a list of images used in node e2e test. These images will be prepulled
|
|
// before test running so that the image pulling won't fail in actual test.
|
|
var NodeImageWhiteList = sets.NewString(
|
|
"google/cadvisor:latest",
|
|
"k8s.gcr.io/stress:v1",
|
|
busyboxImage,
|
|
"k8s.gcr.io/busybox@sha256:4bdd623e848417d96127e16037743f0cd8b528c026e9175e22a84f639eca58ff",
|
|
"k8s.gcr.io/node-problem-detector:v0.4.1",
|
|
imageutils.GetE2EImage(imageutils.NginxSlim),
|
|
imageutils.GetE2EImage(imageutils.ServeHostname),
|
|
imageutils.GetE2EImage(imageutils.Netexec),
|
|
imageutils.GetE2EImage(imageutils.Nonewprivs),
|
|
imageutils.GetPauseImageNameForHostArch(),
|
|
framework.GetGPUDevicePluginImage(),
|
|
)
|
|
|
|
func init() {
|
|
// Union NodeImageWhiteList and CommonImageWhiteList into the framework image white list.
|
|
framework.ImageWhiteList = NodeImageWhiteList.Union(commontest.CommonImageWhiteList)
|
|
}
|
|
|
|
// puller represents a generic image puller
|
|
type puller interface {
|
|
// Pull pulls an image by name
|
|
Pull(image string) ([]byte, error)
|
|
// Name returns the name of the specific puller implementation
|
|
Name() string
|
|
}
|
|
|
|
type dockerPuller struct {
|
|
}
|
|
|
|
func (dp *dockerPuller) Name() string {
|
|
return "docker"
|
|
}
|
|
|
|
func (dp *dockerPuller) Pull(image string) ([]byte, error) {
|
|
// TODO(random-liu): Use docker client to get rid of docker binary dependency.
|
|
return exec.Command("docker", "pull", image).CombinedOutput()
|
|
}
|
|
|
|
type remotePuller struct {
|
|
imageService internalapi.ImageManagerService
|
|
}
|
|
|
|
func (rp *remotePuller) Name() string {
|
|
return "CRI"
|
|
}
|
|
|
|
func (rp *remotePuller) Pull(image string) ([]byte, error) {
|
|
imageStatus, err := rp.imageService.ImageStatus(&runtimeapi.ImageSpec{Image: image})
|
|
if err == nil && imageStatus != nil {
|
|
return nil, nil
|
|
}
|
|
_, err = rp.imageService.PullImage(&runtimeapi.ImageSpec{Image: image}, nil)
|
|
return nil, err
|
|
}
|
|
|
|
func getPuller() (puller, error) {
|
|
runtime := framework.TestContext.ContainerRuntime
|
|
switch runtime {
|
|
case "docker":
|
|
return &dockerPuller{}, nil
|
|
case "remote":
|
|
_, is, err := getCRIClient()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &remotePuller{
|
|
imageService: is,
|
|
}, nil
|
|
}
|
|
return nil, fmt.Errorf("can't prepull images, unknown container runtime %q", runtime)
|
|
}
|
|
|
|
// Pre-fetch all images tests depend on so that we don't fail in an actual test.
|
|
func PrePullAllImages() error {
|
|
puller, err := getPuller()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
usr, err := user.Current()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
images := framework.ImageWhiteList.List()
|
|
glog.V(4).Infof("Pre-pulling images with %s %+v", puller.Name(), images)
|
|
for _, image := range images {
|
|
var (
|
|
err error
|
|
output []byte
|
|
)
|
|
for i := 0; i < maxImagePullRetries; i++ {
|
|
if i > 0 {
|
|
time.Sleep(imagePullRetryDelay)
|
|
}
|
|
if output, err = puller.Pull(image); err == nil {
|
|
break
|
|
}
|
|
glog.Warningf("Failed to pull %s as user %q, retrying in %s (%d of %d): %v",
|
|
image, usr.Username, imagePullRetryDelay.String(), i+1, maxImagePullRetries, err)
|
|
}
|
|
if err != nil {
|
|
glog.Warningf("Could not pre-pull image %s %v output: %s", image, err, output)
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|