fix: cache tags for check manifests

This commit is contained in:
Устюжанин Антон Александрович 2020-12-23 22:25:29 +05:00
parent 35f1369d37
commit fe655cdd26

View file

@ -27,6 +27,17 @@ type ManifestDel struct {
Tags []string Tags []string
} }
func getTags(manifest distribution.Descriptor, tagsDescriptors []distribution.Descriptor) []distribution.Descriptor {
var result []distribution.Descriptor
for _, tag := range tagsDescriptors {
if tag.Digest == manifest.Digest {
result = append(result, tag)
}
}
return result
}
// MarkAndSweep performs a mark and sweep of registry data // MarkAndSweep performs a mark and sweep of registry data
func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, registry distribution.Namespace, opts GCOpts) error { func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, registry distribution.Namespace, opts GCOpts) error {
repositoryEnumerator, ok := registry.(distribution.RepositoryEnumerator) repositoryEnumerator, ok := registry.(distribution.RepositoryEnumerator)
@ -60,22 +71,39 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
return fmt.Errorf("unable to convert ManifestService into ManifestEnumerator") return fmt.Errorf("unable to convert ManifestService into ManifestEnumerator")
} }
allTags, err := repository.Tags(ctx).All(ctx)
switch err.(type) {
case distribution.ErrRepositoryUnknown:
// This tag store has been initialized but not yet populated
break
case nil:
break
default:
return fmt.Errorf("failed to get tags for repository %s: %v", repoName, err)
}
var tagsDescriptors []distribution.Descriptor
for _, tagName := range allTags {
tagDescriptor, err := repository.Tags(ctx).Get(ctx, tagName)
switch err.(type) {
case distribution.ErrTagUnknown:
continue
case nil:
break
default:
return fmt.Errorf("failed to get tag %s in repository %s: %v", tagName, repoName, err)
}
tagsDescriptors = append(tagsDescriptors, tagDescriptor)
}
err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error { err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error {
if opts.RemoveUntagged { if opts.RemoveUntagged {
// fetch all tags where this manifest is the latest one // fetch all tags where this manifest is the latest one
tags, err := repository.Tags(ctx).Lookup(ctx, distribution.Descriptor{Digest: dgst}) tags := getTags(distribution.Descriptor{Digest: dgst}, tagsDescriptors)
if err != nil {
return fmt.Errorf("failed to retrieve tags for digest %v: %v", dgst, err)
}
if len(tags) == 0 { if len(tags) == 0 {
emit("manifest eligible for deletion: %s", dgst) emit("manifest eligible for deletion: %s", dgst)
// fetch all tags from repository // fetch all tags from repository
// all of these tags could contain manifest in history // all of these tags could contain manifest in history
// which means that we need check (and delete) those references when deleting manifest // which means that we need check (and delete) those references when deleting manifest
allTags, err := repository.Tags(ctx).All(ctx)
if err != nil {
return fmt.Errorf("failed to retrieve tags %v", err)
}
manifestArr = append(manifestArr, ManifestDel{Name: repoName, Digest: dgst, Tags: allTags}) manifestArr = append(manifestArr, ManifestDel{Name: repoName, Digest: dgst, Tags: allTags})
return nil return nil
} }