MCPcopy Create free account
hub / github.com/containers/image / deleteImage

Function deleteImage

docker/docker_image_src.go:660–739  ·  view source on GitHub ↗

deleteImage deletes the named image from the registry, if supported.

(ctx context.Context, sys *types.SystemContext, ref dockerReference)

Source from the content-addressed store, hash-verified

658
659// deleteImage deletes the named image from the registry, if supported.
660func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerReference) error {
661 if ref.isUnknownDigest {
662 return fmt.Errorf("Docker reference without a tag or digest cannot be deleted")
663 }
664
665 registryConfig, err := loadRegistryConfiguration(sys)
666 if err != nil {
667 return err
668 }
669 // docker/distribution does not document what action should be used for deleting images.
670 //
671 // Current docker/distribution requires "pull" for reading the manifest and "delete" for deleting it.
672 // quay.io requires "push" (an explicit "pull" is unnecessary), does not grant any token (fails parsing the request) if "delete" is included.
673 // OpenShift ignores the action string (both the password and the token is an OpenShift API token identifying a user).
674 //
675 // We have to hard-code a single string, luckily both docker/distribution and quay.io support "*" to mean "everything".
676 c, err := newDockerClientFromRef(sys, ref, registryConfig, true, "*")
677 if err != nil {
678 return err
679 }
680 defer c.Close()
681
682 headers := map[string][]string{
683 "Accept": manifest.DefaultRequestedManifestMIMETypes,
684 }
685 refTail, err := ref.tagOrDigest()
686 if err != nil {
687 return err
688 }
689 getPath := fmt.Sprintf(manifestPath, reference.Path(ref.ref), refTail)
690 get, err := c.makeRequest(ctx, http.MethodGet, getPath, headers, nil, v2Auth, nil)
691 if err != nil {
692 return err
693 }
694 defer get.Body.Close()
695 switch get.StatusCode {
696 case http.StatusOK:
697 case http.StatusNotFound:
698 return fmt.Errorf("Unable to delete %v. Image may not exist or is not stored with a v2 Schema in a v2 registry", ref.ref)
699 default:
700 return fmt.Errorf("deleting %v: %w", ref.ref, registryHTTPResponseToError(get))
701 }
702 manifestBody, err := iolimits.ReadAtMost(get.Body, iolimits.MaxManifestBodySize)
703 if err != nil {
704 return err
705 }
706
707 manifestDigest, err := manifest.Digest(manifestBody)
708 if err != nil {
709 return fmt.Errorf("computing manifest digest: %w", err)
710 }
711 deletePath := fmt.Sprintf(manifestPath, reference.Path(ref.ref), manifestDigest)
712
713 // When retrieving the digest from a registry >= 2.3 use the following header:
714 // "Accept": "application/vnd.docker.distribution.manifest.v2+json"
715 delete, err := c.makeRequest(ctx, http.MethodDelete, deletePath, headers, nil, v2Auth, nil)
716 if err != nil {
717 return err

Callers 1

DeleteImageMethod · 0.85

Calls 11

PathFunction · 0.92
ReadAtMostFunction · 0.92
DigestFunction · 0.92
newDockerClientFromRefFunction · 0.85
lookasideStorageURLFunction · 0.85
tagOrDigestMethod · 0.80
deleteOneSignatureMethod · 0.80
CloseMethod · 0.65
makeRequestMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…