package containerd import ( "context" containerdimages "github.com/containerd/containerd/images" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) // 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")) } var children []image.ID for _, img := range imgs { children = append(children, image.ID(img.Target.Digest)) } 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. func (i *ImageService) parents(ctx context.Context, id image.ID) ([]containerdimages.Image, error) { targetImage, err := i.resolveImage(ctx, id.String()) if err != nil { return nil, errors.Wrap(err, "failed to get child image") } var imgs []containerdimages.Image for { parent, ok := targetImage.Labels[imageLabelClassicBuilderParent] if !ok || parent == "" { break } parentDigest, err := digest.Parse(parent) if err != nil { return nil, err } img, err := i.resolveImage(ctx, parentDigest.String()) if err != nil { return nil, err } imgs = append(imgs, img) targetImage = img } return imgs, nil }