executor/docker: pull init image only when needed

Use the same logic of k8s and pull init image only when has the latest (or
empty) tag or it doesn't exist.
This commit is contained in:
Simone Gotti 2021-05-25 10:27:36 +02:00
parent 0b0d05f2a0
commit b403fd558a
2 changed files with 36 additions and 19 deletions

View File

@ -15,7 +15,6 @@
package driver
import (
"bufio"
"context"
"encoding/base64"
"encoding/json"
@ -73,16 +72,8 @@ func (d *DockerDriver) Setup(ctx context.Context) error {
return nil
}
func (d *DockerDriver) createToolboxVolume(ctx context.Context, podID string) (*dockertypes.Volume, error) {
reader, err := d.client.ImagePull(ctx, d.initImage, dockertypes.ImagePullOptions{})
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
d.log.Infof("create toolbox volume image pull output: %s", scanner.Text())
}
if err := scanner.Err(); err != nil {
func (d *DockerDriver) createToolboxVolume(ctx context.Context, podID string, out io.Writer) (*dockertypes.Volume, error) {
if err := d.fetchImage(ctx, d.initImage, false, nil, out); err != nil {
return nil, err
}
@ -153,7 +144,7 @@ func (d *DockerDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.
return nil, errors.Errorf("empty container config")
}
toolboxVol, err := d.createToolboxVolume(ctx, podConfig.ID)
toolboxVol, err := d.createToolboxVolume(ctx, podConfig.ID, out)
if err != nil {
return nil, err
}
@ -240,7 +231,7 @@ func (d *DockerDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.
return pod, nil
}
func (d *DockerDriver) fetchImage(ctx context.Context, image string, registryConfig *registry.DockerConfig, out io.Writer) error {
func (d *DockerDriver) fetchImage(ctx context.Context, image string, alwaysFetch bool, registryConfig *registry.DockerConfig, out io.Writer) error {
regName, err := registry.GetRegistry(image)
if err != nil {
return err
@ -257,21 +248,39 @@ func (d *DockerDriver) fetchImage(ctx context.Context, image string, registryCon
}
registryAuthEnc := base64.URLEncoding.EncodeToString(buf)
// by default always try to pull the image so we are sure only authorized users can fetch them
// see https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages
reader, err := d.client.ImagePull(ctx, image, dockertypes.ImagePullOptions{RegistryAuth: registryAuthEnc})
tag, err := registry.GetImageTagOrDigest(image)
if err != nil {
return err
}
_, err = io.Copy(out, reader)
return err
args := filters.NewArgs()
args.Add("reference", image)
img, err := d.client.ImageList(ctx, dockertypes.ImageListOptions{Filters: args})
if err != nil {
return err
}
exists := len(img) > 0
// fetch only if forced, is latest tag or image doesn't exist
if alwaysFetch || tag == "latest" || !exists {
reader, err := d.client.ImagePull(ctx, image, dockertypes.ImagePullOptions{RegistryAuth: registryAuthEnc})
if err != nil {
return err
}
_, err = io.Copy(out, reader)
return err
}
return nil
}
func (d *DockerDriver) createContainer(ctx context.Context, index int, podConfig *PodConfig, maincontainerID string, toolboxVol *dockertypes.Volume, out io.Writer) (*container.ContainerCreateCreatedBody, error) {
containerConfig := podConfig.Containers[index]
if err := d.fetchImage(ctx, containerConfig.Image, podConfig.DockerConfig, out); err != nil {
// by default always try to pull the image so we are sure only authorized users can fetch them
// see https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages
if err := d.fetchImage(ctx, containerConfig.Image, true, podConfig.DockerConfig, out); err != nil {
return nil, err
}

View File

@ -76,6 +76,14 @@ var (
}
)
func GetImageTagOrDigest(image string) (string, error) {
ref, err := name.ParseReference(image, name.WeakValidation)
if err != nil {
return "", err
}
return ref.Identifier(), nil
}
func GetRegistry(image string) (string, error) {
ref, err := name.ParseReference(image, name.WeakValidation)
if err != nil {