in cmd/common/image_functions.go [152:215]
func GetUntaggedManifests(ctx context.Context, acrClient api.AcrCLIClientInterface, loginURL string, repoName string, dryRun bool, ignoreReferrerManifests bool) (*[]string, error) {
lastManifestDigest := ""
var manifestsForCommand []string
resultManifests, err := acrClient.GetAcrManifests(ctx, repoName, "", lastManifestDigest)
if err != nil {
if resultManifests != nil && resultManifests.Response.Response != nil && resultManifests.StatusCode == http.StatusNotFound {
fmt.Printf("%s repository not found\n", repoName)
return &manifestsForCommand, nil
}
return nil, err
}
// This will act as a set. If a key is present, then the command shouldn't be executed because it is referenced by a multiarch manifest
// or the manifest has subjects attached
ignoreList := set.New[string]()
var candidates []acr.ManifestAttributesBase
for resultManifests != nil && resultManifests.ManifestsAttributes != nil {
manifests := *resultManifests.ManifestsAttributes
for _, manifest := range manifests {
if manifest.Tags != nil {
// If a manifest has Tags and its media type supports multiarch manifest, we will
// iterate all its dependent manifests and mark them to not have the command execute on them.
if err = AddDependentManifestsToIgnoreList(ctx, manifest, ignoreList, acrClient, repoName); err != nil {
return nil, err
}
} else {
if ignoreReferrerManifests {
// If a manifest does not have Tags and its media type supports subject, we will
// check if the subject exists. If so, the manifest is marked not to be affected by the command.
if candidates, err = UpdateForManifestWithoutSubjectToDelete(ctx, manifest, ignoreList, candidates, acrClient, repoName); err != nil {
return nil, err
}
} else {
if *manifest.MediaType != v1.MediaTypeImageManifest {
candidates = append(candidates, manifest)
}
}
}
}
// Get the last manifest digest from the last manifest from manifests.
lastManifestDigest = *manifests[len(manifests)-1].Digest
// Use this new digest to find next batch of manifests.
resultManifests, err = acrClient.GetAcrManifests(ctx, repoName, "", lastManifestDigest)
if err != nil {
return nil, err
}
}
// Remove all manifests that should not be deleted
for i := 0; i < len(candidates); i++ {
if !ignoreList.Contains(*candidates[i].Digest) {
// if a manifest has no tags, is not part of a manifest list and can be deleted then it is added to the
// manifestsForCommand array.
if *(candidates[i].ChangeableAttributes).DeleteEnabled && *(candidates[i].ChangeableAttributes).WriteEnabled {
manifestsForCommand = append(manifestsForCommand, *candidates[i].Digest)
if dryRun && !ignoreReferrerManifests {
fmt.Printf("%s/%s@%s\n", loginURL, repoName, *candidates[i].Digest)
}
}
}
}
return &manifestsForCommand, nil
}