Remove tags referencing deleted manifests.
When a manifest is deleted by digest, look up the referenced tags in the tag store and remove all associations. Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
This commit is contained in:
parent
1c6c0c8a2d
commit
fea0a7ed49
4 changed files with 181 additions and 7 deletions
|
@ -116,15 +116,19 @@ func (ts *tagStore) Get(ctx context.Context, tag string) (distribution.Descripto
|
|||
return distribution.Descriptor{Digest: revision}, nil
|
||||
}
|
||||
|
||||
// delete removes the tag from repository, including the history of all
|
||||
// revisions that have the specified tag.
|
||||
// Untag removes the tag association
|
||||
func (ts *tagStore) Untag(ctx context.Context, tag string) error {
|
||||
tagPath, err := pathFor(manifestTagPathSpec{
|
||||
name: ts.repository.Name(),
|
||||
tag: tag,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case storagedriver.PathNotFoundError:
|
||||
return distribution.ErrTagUnknown{Tag: tag}
|
||||
case nil:
|
||||
break
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -153,7 +157,35 @@ func (ts *tagStore) linkedBlobStore(ctx context.Context, tag string) *linkedBlob
|
|||
|
||||
// Lookup recovers a list of tags which refer to this digest. When a manifest is deleted by
|
||||
// digest, tag entries which point to it need to be recovered to avoid dangling tags.
|
||||
func (ts *tagStore) Lookup(ctx context.Context, digest distribution.Descriptor) ([]string, error) {
|
||||
// An efficient implementation of this will require changes to the S3 driver.
|
||||
return make([]string, 0), nil
|
||||
func (ts *tagStore) Lookup(ctx context.Context, desc distribution.Descriptor) ([]string, error) {
|
||||
allTags, err := ts.All(ctx)
|
||||
switch err.(type) {
|
||||
case distribution.ErrRepositoryUnknown:
|
||||
// This tag store has been initialized but not yet populated
|
||||
break
|
||||
case nil:
|
||||
break
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tags []string
|
||||
for _, tag := range allTags {
|
||||
tagLinkPathSpec := manifestTagCurrentPathSpec{
|
||||
name: ts.repository.Name(),
|
||||
tag: tag,
|
||||
}
|
||||
|
||||
tagLinkPath, err := pathFor(tagLinkPathSpec)
|
||||
tagDigest, err := ts.blobStore.readlink(ctx, tagLinkPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tagDigest == desc.Digest {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ func TestTagStoreUnTag(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTagAll(t *testing.T) {
|
||||
func TestTagStoreAll(t *testing.T) {
|
||||
env := testTagStore(t)
|
||||
tagStore := env.ts
|
||||
ctx := env.ctx
|
||||
|
@ -148,3 +148,59 @@ func TestTagAll(t *testing.T) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTagLookup(t *testing.T) {
|
||||
env := testTagStore(t)
|
||||
tagStore := env.ts
|
||||
ctx := env.ctx
|
||||
|
||||
descA := distribution.Descriptor{Digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
|
||||
desc0 := distribution.Descriptor{Digest: "sha256:0000000000000000000000000000000000000000000000000000000000000000"}
|
||||
|
||||
tags, err := tagStore.Lookup(ctx, descA)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(tags) != 0 {
|
||||
t.Fatalf("Lookup returned > 0 tags from empty store")
|
||||
}
|
||||
|
||||
err = tagStore.Tag(ctx, "a", descA)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = tagStore.Tag(ctx, "b", descA)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = tagStore.Tag(ctx, "0", desc0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = tagStore.Tag(ctx, "1", desc0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tags, err = tagStore.Lookup(ctx, descA)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(tags) != 2 {
|
||||
t.Errorf("Lookup of descA returned %d tags, expected 2", len(tags))
|
||||
}
|
||||
|
||||
tags, err = tagStore.Lookup(ctx, desc0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(tags) != 2 {
|
||||
t.Errorf("Lookup of descB returned %d tags, expected 2", len(tags))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue