Skip to content

Commit

Permalink
Merge pull request #6768 from jackfrancis/e2e-kind-local-image-priming
Browse files Browse the repository at this point in the history
🌱 pull non-existent images when building kind bootstrap cluster
  • Loading branch information
k8s-ci-robot authored Jul 5, 2022
2 parents e53cab0 + 2e2148f commit 6b58c06
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
17 changes: 16 additions & 1 deletion test/framework/bootstrap/kind_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ func LoadImagesToKindCluster(ctx context.Context, input LoadImagesToKindClusterI
}

// LoadImage will put a local image onto the kind node.
// If the image doesn't exist locally we will attempt to pull it remotely.
func loadImage(ctx context.Context, cluster, image string) error {
// Save the image into a tar
dir, err := os.MkdirTemp("", "image-tar")
Expand All @@ -147,7 +148,21 @@ func loadImage(ctx context.Context, cluster, image string) error {
if err != nil {
return errors.Wrap(err, "failed to access container runtime")
}

// in the nominal E2E scenario images have been locally built and added to cache
exists, err := containerRuntime.ImageExistsLocally(ctx, image)
if err != nil {
return errors.Wrapf(err, "error listing local image %s", image)
}
// in some scenarios we refer to a real reference image which may not have been pre-downloaded
if !exists {
log.Logf("Image %s not present in local container image cache, will pull", image)
err := containerRuntime.PullContainerImage(ctx, image)
if err != nil {
return errors.Wrapf(err, "error pulling image %q", image)
}
} else {
log.Logf("Image %s is present in local container image cache", image)
}
err = containerRuntime.SaveContainerImage(ctx, image, imageTarPath)
if err != nil {
return errors.Wrapf(err, "error saving image %q to %q", image, imageTarPath)
Expand Down
32 changes: 24 additions & 8 deletions test/infrastructure/container/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,19 @@ func (d *dockerRuntime) SaveContainerImage(ctx context.Context, image, dest stri
// already exist. This is important when we're using locally build images in CI which
// do not exist remotely.
func (d *dockerRuntime) PullContainerImageIfNotExists(ctx context.Context, image string) error {
filters := dockerfilters.NewArgs()
filters.Add("reference", image)
images, err := d.dockerClient.ImageList(ctx, types.ImageListOptions{
Filters: filters,
})
imageExistsLocally, err := d.ImageExistsLocally(ctx, image)
if err != nil {
return fmt.Errorf("failure listing container images: %v", err)
return errors.Wrapf(err, "failure determining if the image exists in local cache: %s", image)
}
// Nothing to do as the image already exists locally.
if len(images) > 0 {
if imageExistsLocally {
return nil
}

return d.PullContainerImage(ctx, image)
}

// PullContainerImage triggers the Docker engine to pull an image.
func (d *dockerRuntime) PullContainerImage(ctx context.Context, image string) error {
pullResp, err := d.dockerClient.ImagePull(ctx, image, types.ImagePullOptions{})
if err != nil {
return fmt.Errorf("failure pulling container image: %v", err)
Expand All @@ -124,6 +124,22 @@ func (d *dockerRuntime) PullContainerImageIfNotExists(ctx context.Context, image
return nil
}

// ImageExistsLocally returns if the specified image exists in local container image cache.
func (d *dockerRuntime) ImageExistsLocally(ctx context.Context, image string) (bool, error) {
filters := dockerfilters.NewArgs()
filters.Add("reference", image)
images, err := d.dockerClient.ImageList(ctx, types.ImageListOptions{
Filters: filters,
})
if err != nil {
return false, errors.Wrapf(err, "failure listing container image: %s", image)
}
if len(images) > 0 {
return true, nil
}
return false, nil
}

// GetHostPort looks up the host port bound for the port and protocol (e.g. "6443/tcp").
func (d *dockerRuntime) GetHostPort(ctx context.Context, containerName, portAndProtocol string) (string, error) {
// Get details about the container
Expand Down
10 changes: 10 additions & 0 deletions test/infrastructure/container/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ func (f *FakeRuntime) PullContainerImageIfNotExists(ctx context.Context, image s
return nil
}

// PullContainerImage triggers the Docker engine to pull an image.
func (f *FakeRuntime) PullContainerImage(ctx context.Context, image string) error {
return nil
}

// ImageExistsLocally returns if the specified image exists in local container image cache.
func (f *FakeRuntime) ImageExistsLocally(ctx context.Context, image string) (bool, error) {
return false, nil
}

// GetHostPort looks up the host port bound for the port and protocol (e.g. "6443/tcp").
func (f *FakeRuntime) GetHostPort(ctx context.Context, containerName, portAndProtocol string) (string, error) {
return "", nil
Expand Down
2 changes: 2 additions & 0 deletions test/infrastructure/container/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type providerKey struct{}
type Runtime interface {
SaveContainerImage(ctx context.Context, image, dest string) error
PullContainerImageIfNotExists(ctx context.Context, image string) error
PullContainerImage(ctx context.Context, image string) error
ImageExistsLocally(ctx context.Context, image string) (bool, error)
GetHostPort(ctx context.Context, containerName, portAndProtocol string) (string, error)
GetContainerIPs(ctx context.Context, containerName string) (string, string, error)
ExecContainer(ctx context.Context, containerName string, config *ExecContainerInput, command string, args ...string) error
Expand Down

0 comments on commit 6b58c06

Please sign in to comment.