c8d/cache: Optimize FROM scratch
case
Consider only images that were built `FROM scratch` as valid candidates for the `FROM scratch` + INSTRUCTION build step. The images are marked as `FROM scratch` based by the classic builder with a special label. It must be a new label instead of empty parent label, because empty label values are not persisted. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
71ebfc7c63
commit
a5a15c7782
3 changed files with 22 additions and 14 deletions
|
@ -5,7 +5,6 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
imagetype "github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/builder"
|
||||
|
@ -57,17 +56,11 @@ func (ic *localCache) GetCache(parentID string, cfg *container.Config) (imageID
|
|||
|
||||
// FROM scratch
|
||||
if parentID == "" {
|
||||
imgs, err := ic.imageService.Images(ctx, types.ImageListOptions{
|
||||
All: true,
|
||||
})
|
||||
c, err := ic.imageService.getImagesWithLabel(ctx, imageLabelClassicBuilderFromScratch, "1")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, img := range imgs {
|
||||
if img.ParentID == parentID {
|
||||
children = append(children, image.ID(img.ID))
|
||||
}
|
||||
}
|
||||
children = c
|
||||
} else {
|
||||
c, err := ic.imageService.Children(ctx, image.ID(parentID))
|
||||
if err != nil {
|
||||
|
|
|
@ -41,8 +41,13 @@ import (
|
|||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// Digest of the image which was the base image of the committed container.
|
||||
const imageLabelClassicBuilderParent = "org.mobyproject.image.parent"
|
||||
const (
|
||||
// Digest of the image which was the base image of the committed container.
|
||||
imageLabelClassicBuilderParent = "org.mobyproject.image.parent"
|
||||
|
||||
// "1" means that the image was created directly from the "FROM scratch".
|
||||
imageLabelClassicBuilderFromScratch = "org.mobyproject.image.fromscratch"
|
||||
)
|
||||
|
||||
// GetImageAndReleasableLayer returns an image and releaseable layer for a
|
||||
// reference or ID. Every call to GetImageAndReleasableLayer MUST call
|
||||
|
@ -483,6 +488,10 @@ func (i *ImageService) createImageOCI(ctx context.Context, imgToCreate imagespec
|
|||
},
|
||||
}
|
||||
|
||||
if parentDigest == "" {
|
||||
img.Labels[imageLabelClassicBuilderFromScratch] = "1"
|
||||
}
|
||||
|
||||
createdImage, err := i.client.ImageService().Update(ctx, img)
|
||||
if err != nil {
|
||||
if !cerrdefs.IsNotFound(err) {
|
||||
|
|
|
@ -10,9 +10,10 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Children returns a slice of image IDs that are children of the `id` image
|
||||
func (i *ImageService) Children(ctx context.Context, id image.ID) ([]image.ID, error) {
|
||||
imgs, err := i.images.List(ctx, "labels."+imageLabelClassicBuilderParent+"=="+string(id))
|
||||
// getImagesWithLabel returns all images that have the matching label key and value.
|
||||
func (i *ImageService) getImagesWithLabel(ctx context.Context, labelKey string, labelValue string) ([]image.ID, error) {
|
||||
imgs, err := i.images.List(ctx, "labels."+labelKey+"=="+labelValue)
|
||||
|
||||
if err != nil {
|
||||
return []image.ID{}, errdefs.System(errors.Wrap(err, "failed to list all images"))
|
||||
}
|
||||
|
@ -25,6 +26,11 @@ func (i *ImageService) Children(ctx context.Context, id image.ID) ([]image.ID, e
|
|||
return children, nil
|
||||
}
|
||||
|
||||
// Children returns a slice of image IDs that are children of the `id` image
|
||||
func (i *ImageService) Children(ctx context.Context, id image.ID) ([]image.ID, error) {
|
||||
return i.getImagesWithLabel(ctx, imageLabelClassicBuilderParent, string(id))
|
||||
}
|
||||
|
||||
// parents returns a slice of image IDs that are parents of the `id` image
|
||||
//
|
||||
// Called from image_delete.go to prune dangling parents.
|
||||
|
|
Loading…
Reference in a new issue