| 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 |
| } |