MCPcopy Create free account
hub / github.com/containers/common / RemoveImages

Method RemoveImages

libimage/runtime.go:618–739  ·  view source on GitHub ↗

RemoveImages removes images specified by names. If no names are specified, remove images as specified via the options' filters. All images are expected to exist in the local containers storage. If an image has more names than one name, the image will be untagged with the specified name. RemoveIm

(ctx context.Context, names []string, options *RemoveImagesOptions)

Source from the content-addressed store, hash-verified

616// Note that most errors are non-fatal and collected into `rmErrors` return
617// value.
618func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *RemoveImagesOptions) (reports []*RemoveImageReport, rmErrors []error) {
619 if options == nil {
620 options = &RemoveImagesOptions{}
621 }
622
623 if options.ExternalContainers && options.IsExternalContainerFunc == nil {
624 return nil, []error{fmt.Errorf("libimage error: cannot remove external containers without callback")}
625 }
626
627 // The logic here may require some explanation. Image removal is
628 // surprisingly complex since it is recursive (intermediate parents are
629 // removed) and since multiple items in `names` may resolve to the
630 // *same* image. On top, the data in the containers storage is shared,
631 // so we need to be careful and the code must be robust. That is why
632 // users can only remove images via this function; the logic may be
633 // complex but the execution path is clear.
634
635 // Bundle an image with a possible empty slice of names to untag. That
636 // allows for a decent untagging logic and to bundle multiple
637 // references to the same *Image (and circumvent consistency issues).
638 type deleteMe struct {
639 image *Image
640 referencedBy []string
641 }
642
643 appendError := func(err error) {
644 rmErrors = append(rmErrors, err)
645 }
646
647 deleteMap := make(map[string]*deleteMe) // ID -> deleteMe
648 toDelete := []string{}
649 // Look up images in the local containers storage and fill out
650 // toDelete and the deleteMap.
651
652 switch {
653 case len(names) > 0:
654 // prepare lookupOptions
655 var lookupOptions *LookupImageOptions
656 if options.LookupManifest {
657 // LookupManifest configured as true make sure we only remove manifests and no referenced images.
658 lookupOptions = &LookupImageOptions{lookupManifest: true}
659 } else {
660 lookupOptions = &LookupImageOptions{returnManifestIfNoInstance: true}
661 }
662 // Look up the images one-by-one. That allows for removing
663 // images that have been looked up successfully while reporting
664 // lookup errors at the end.
665 for _, name := range names {
666 img, resolvedName, err := r.LookupImage(name, lookupOptions)
667 if err != nil {
668 appendError(err)
669 continue
670 }
671 dm, exists := deleteMap[img.ID()]
672 if !exists {
673 toDelete = append(toDelete, img.ID())
674 dm = &deleteMe{image: img}
675 deleteMap[img.ID()] = dm

Callers 7

TestLoadFunction · 0.80
TestPushFunction · 0.80
TestCreateManifestListFunction · 0.80
TestRemoveImagesFunction · 0.80
TestSaveFunction · 0.80
TestPullFunction · 0.80

Calls 4

LookupImageMethod · 0.95
ListImagesMethod · 0.95
removeMethod · 0.80
IDMethod · 0.45

Tested by 7

TestLoadFunction · 0.64
TestPushFunction · 0.64
TestCreateManifestListFunction · 0.64
TestRemoveImagesFunction · 0.64
TestSaveFunction · 0.64
TestPullFunction · 0.64