mirror of
https://github.com/project-zot/zot.git
synced 2026-06-15 20:07:55 +08:00
api: implement delete by tag
This commit is contained in:
committed by
Ramkumar Chinchani
parent
fed5c09b71
commit
c6670b1329
+34
-6
@@ -588,11 +588,14 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
||||
return errors.ErrRepoNotFound
|
||||
}
|
||||
|
||||
// as per spec "reference" can only be a digest and not a tag
|
||||
isTag := false
|
||||
|
||||
// as per spec "reference" can be a digest and a tag
|
||||
digest, err := godigest.Parse(reference)
|
||||
if err != nil {
|
||||
is.log.Error().Err(err).Msg("invalid reference")
|
||||
return errors.ErrBadManifest
|
||||
is.log.Debug().Str("invalid digest: ", reference).Msg("storage: assuming tag")
|
||||
|
||||
isTag = true
|
||||
}
|
||||
|
||||
is.Lock()
|
||||
@@ -620,7 +623,19 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
||||
outIndex.Manifests = []ispec.Descriptor{}
|
||||
|
||||
for _, m = range index.Manifests {
|
||||
if reference == m.Digest.String() {
|
||||
if isTag {
|
||||
tag, ok := m.Annotations[ispec.AnnotationRefName]
|
||||
if ok && tag == reference {
|
||||
is.log.Debug().Str("deleting tag", tag).Msg("")
|
||||
|
||||
digest = m.Digest
|
||||
|
||||
found = true
|
||||
|
||||
continue
|
||||
}
|
||||
} else if reference == m.Digest.String() {
|
||||
is.log.Debug().Str("deleting reference", reference).Msg("")
|
||||
found = true
|
||||
continue
|
||||
}
|
||||
@@ -657,9 +672,22 @@ func (is *ImageStore) DeleteImageManifest(repo string, reference string) error {
|
||||
}
|
||||
}
|
||||
|
||||
p := path.Join(dir, "blobs", digest.Algorithm().String(), digest.Encoded())
|
||||
// Delete blob only when blob digest not present in manifest entry.
|
||||
// e.g. 1.0.1 & 1.0.2 have same blob digest so if we delete 1.0.1, blob should not be removed.
|
||||
toDelete := true
|
||||
|
||||
_ = os.Remove(p)
|
||||
for _, m = range outIndex.Manifests {
|
||||
if digest.String() == m.Digest.String() {
|
||||
toDelete = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if toDelete {
|
||||
p := path.Join(dir, "blobs", digest.Algorithm().String(), digest.Encoded())
|
||||
|
||||
_ = os.Remove(p)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -129,6 +129,8 @@ func TestAPIs(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Good image manifest", func() {
|
||||
annotationsMap := make(map[string]string)
|
||||
annotationsMap[ispec.AnnotationRefName] = "1.0"
|
||||
m := ispec.Manifest{
|
||||
Config: ispec.Descriptor{
|
||||
Digest: d,
|
||||
@@ -141,29 +143,57 @@ func TestAPIs(t *testing.T) {
|
||||
Size: int64(l),
|
||||
},
|
||||
},
|
||||
Annotations: map[string]string{ispec.AnnotationRefName: "1.0"},
|
||||
Annotations: annotationsMap,
|
||||
}
|
||||
|
||||
m.SchemaVersion = 2
|
||||
mb, _ = json.Marshal(m)
|
||||
mb, _ := json.Marshal(m)
|
||||
d := godigest.FromBytes(mb)
|
||||
_, err = il.PutImageManifest("test", d.String(), ispec.MediaTypeImageManifest, mb)
|
||||
_, err = il.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, mb)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = il.GetImageTags("test")
|
||||
_, err = il.PutImageManifest("test", "2.0", ispec.MediaTypeImageManifest, mb)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = il.PutImageManifest("test", "3.0", ispec.MediaTypeImageManifest, mb)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// total tags should be 3 but they have same reference.
|
||||
tags, err := il.GetImageTags("test")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tags), ShouldEqual, 3)
|
||||
|
||||
_, _, _, err = il.GetImageManifest("test", d.String())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = il.DeleteImageManifest("test", "1.0")
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
err = il.DeleteBlob("test", blobDigest.String())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
tags, err = il.GetImageTags("test")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tags), ShouldEqual, 2)
|
||||
|
||||
// We deleted only one tag, make sure blob should not be removed.
|
||||
hasBlob, _, err := il.CheckBlob("test", d.String())
|
||||
So(err, ShouldBeNil)
|
||||
So(hasBlob, ShouldEqual, true)
|
||||
|
||||
// If we pass reference all manifest with input reference should be deleted.
|
||||
err = il.DeleteImageManifest("test", d.String())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
tags, err = il.GetImageTags("test")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tags), ShouldEqual, 0)
|
||||
|
||||
// All tags/references are deleted, blob should not be present in disk.
|
||||
hasBlob, _, err = il.CheckBlob("test", d.String())
|
||||
So(err, ShouldNotBeNil)
|
||||
So(hasBlob, ShouldEqual, false)
|
||||
|
||||
err = il.DeleteBlob("test", blobDigest.String())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, _, _, err = il.GetImageManifest("test", d.String())
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user