c8d/builder: Store parent in c8d image label
Images built by classic builder will have an additional label (in the containerd image object, not image config) pointing to a parent of that image. This allows to differentiate intermediate images (dangling images created as a result of a each Dockerfile instruction) from the final images. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
152036f0aa
commit
081b74b97d
4 changed files with 49 additions and 1 deletions
|
@ -36,6 +36,8 @@ import (
|
|||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
const imageLabelClassicBuilderParent = "org.mobyproject.image.parent"
|
||||
|
||||
// GetImageAndReleasableLayer returns an image and releaseable layer for a
|
||||
// reference or ID. Every call to GetImageAndReleasableLayer MUST call
|
||||
// releasableLayer.Release() to prevent leaking of layers.
|
||||
|
@ -392,6 +394,8 @@ func (i *ImageService) CreateImage(ctx context.Context, config []byte, parent st
|
|||
ociImgToCreate := dockerImageToDockerOCIImage(*imgToCreate)
|
||||
|
||||
var layers []ocispec.Descriptor
|
||||
|
||||
var parentDigest digest.Digest
|
||||
// if the image has a parent, we need to start with the parents layers descriptors
|
||||
if parent != "" {
|
||||
parentDesc, err := i.resolveDescriptor(ctx, parent)
|
||||
|
@ -404,6 +408,7 @@ func (i *ImageService) CreateImage(ctx context.Context, config []byte, parent st
|
|||
}
|
||||
|
||||
layers = parentImageManifest.Layers
|
||||
parentDigest = parentDesc.Digest
|
||||
}
|
||||
|
||||
// get the info for the new layers
|
||||
|
@ -443,6 +448,9 @@ func (i *ImageService) CreateImage(ctx context.Context, config []byte, parent st
|
|||
Name: danglingImageName(commitManifestDesc.Digest),
|
||||
Target: commitManifestDesc,
|
||||
CreatedAt: time.Now(),
|
||||
Labels: map[string]string{
|
||||
imageLabelClassicBuilderParent: parentDigest.String(),
|
||||
},
|
||||
}
|
||||
|
||||
createdImage, err := i.client.ImageService().Update(ctx, img)
|
||||
|
|
|
@ -106,6 +106,9 @@ func (i *ImageService) CommitImage(ctx context.Context, cc backend.CommitConfig)
|
|||
Name: danglingImageName(commitManifestDesc.Digest),
|
||||
Target: commitManifestDesc,
|
||||
CreatedAt: time.Now(),
|
||||
Labels: map[string]string{
|
||||
imageLabelClassicBuilderParent: cc.ParentImageID,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := i.client.ImageService().Update(ctx, img); err != nil {
|
||||
|
|
|
@ -98,8 +98,34 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
|
|||
contentStore := i.client.ContentStore()
|
||||
uniqueImages := map[digest.Digest]images.Image{}
|
||||
tagsByDigest := map[digest.Digest][]string{}
|
||||
intermediateImages := map[digest.Digest]struct{}{}
|
||||
|
||||
hideIntermediate := !opts.All
|
||||
if hideIntermediate {
|
||||
for _, img := range imgs {
|
||||
parent, ok := img.Labels[imageLabelClassicBuilderParent]
|
||||
if ok && parent != "" {
|
||||
dgst, err := digest.Parse(parent)
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"error": err,
|
||||
"value": parent,
|
||||
}).Warnf("invalid %s label value", imageLabelClassicBuilderParent)
|
||||
}
|
||||
intermediateImages[dgst] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, img := range imgs {
|
||||
isDangling := isDanglingImage(img)
|
||||
|
||||
if hideIntermediate && isDangling {
|
||||
if _, ok := intermediateImages[img.Target.Digest]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if !filter(img) {
|
||||
continue
|
||||
}
|
||||
|
@ -107,7 +133,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
|
|||
dgst := img.Target.Digest
|
||||
uniqueImages[dgst] = img
|
||||
|
||||
if isDanglingImage(img) {
|
||||
if isDangling {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,17 @@ func (i *ImageService) TagImage(ctx context.Context, imageID image.ID, newTag re
|
|||
return nil
|
||||
}
|
||||
|
||||
builderLabel, ok := sourceDanglingImg.Labels[imageLabelClassicBuilderParent]
|
||||
if ok {
|
||||
newImg.Labels = map[string]string{
|
||||
imageLabelClassicBuilderParent: builderLabel,
|
||||
}
|
||||
|
||||
if _, err := is.Update(context.Background(), newImg, "labels"); err != nil {
|
||||
logger.WithError(err).Warnf("failed to set %s label on the newly tagged image", imageLabelClassicBuilderParent)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the source dangling image, as it's no longer dangling.
|
||||
if err := is.Delete(context.Background(), sourceDanglingImg.Name); err != nil {
|
||||
logger.WithError(err).Warn("unexpected error when deleting dangling image")
|
||||
|
|
Loading…
Add table
Reference in a new issue