Merge pull request #269 from sgotti/executor_docker_pull_initimage_only_when_needed

executor/docker: pull init image only when needed
This commit is contained in:
Simone Gotti 2021-05-25 14:02:41 +02:00 committed by GitHub
commit 875e118817
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 19 deletions

View File

@ -15,7 +15,6 @@
package driver package driver
import ( import (
"bufio"
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
@ -73,16 +72,8 @@ func (d *DockerDriver) Setup(ctx context.Context) error {
return nil return nil
} }
func (d *DockerDriver) createToolboxVolume(ctx context.Context, podID string) (*dockertypes.Volume, error) { func (d *DockerDriver) createToolboxVolume(ctx context.Context, podID string, out io.Writer) (*dockertypes.Volume, error) {
reader, err := d.client.ImagePull(ctx, d.initImage, dockertypes.ImagePullOptions{}) if err := d.fetchImage(ctx, d.initImage, false, nil, out); err != nil {
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 {
return nil, err 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") 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 { if err != nil {
return nil, err return nil, err
} }
@ -240,7 +231,7 @@ func (d *DockerDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.
return pod, nil 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) regName, err := registry.GetRegistry(image)
if err != nil { if err != nil {
return err return err
@ -257,21 +248,39 @@ func (d *DockerDriver) fetchImage(ctx context.Context, image string, registryCon
} }
registryAuthEnc := base64.URLEncoding.EncodeToString(buf) registryAuthEnc := base64.URLEncoding.EncodeToString(buf)
// by default always try to pull the image so we are sure only authorized users can fetch them tag, err := registry.GetImageTagOrDigest(image)
// see https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages
reader, err := d.client.ImagePull(ctx, image, dockertypes.ImagePullOptions{RegistryAuth: registryAuthEnc})
if err != nil { if err != nil {
return err return err
} }
_, err = io.Copy(out, reader) args := filters.NewArgs()
return err 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) { 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] 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 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) { func GetRegistry(image string) (string, error) {
ref, err := name.ParseReference(image, name.WeakValidation) ref, err := name.ParseReference(image, name.WeakValidation)
if err != nil { if err != nil {