mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 20:38:08 +08:00
fix(storage): do not open/download blobs when validating manifests (#1566)
when pushing manifests, zot will validate blobs (layers + config blob) are present in repo, currently it opens(in case of filesystem storage) or download( in case of cloud storage) each blob. fixed that by adding a new method ImageStore.CheckBlobPresence() on storage to check blobs presence without checking the cache like ImageStore.CheckBlob() method does. Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
This commit is contained in:
@@ -1087,7 +1087,11 @@ func (is *ImageStoreLocal) BlobPath(repo string, digest godigest.Digest) string
|
||||
return path.Join(is.rootDir, repo, "blobs", digest.Algorithm().String(), digest.Encoded())
|
||||
}
|
||||
|
||||
// CheckBlob verifies a blob and returns true if the blob is correct.
|
||||
/*
|
||||
CheckBlob verifies a blob and returns true if the blob is correct
|
||||
|
||||
If the blob is not found but it's found in cache then it will be copied over.
|
||||
*/
|
||||
func (is *ImageStoreLocal) CheckBlob(repo string, digest godigest.Digest) (bool, int64, error) {
|
||||
var lockLatency time.Time
|
||||
|
||||
@@ -1095,8 +1099,6 @@ func (is *ImageStoreLocal) CheckBlob(repo string, digest godigest.Digest) (bool,
|
||||
return false, -1, err
|
||||
}
|
||||
|
||||
blobPath := is.BlobPath(repo, digest)
|
||||
|
||||
if is.dedupe && fmt.Sprintf("%v", is.cache) != fmt.Sprintf("%v", nil) {
|
||||
is.Lock(&lockLatency)
|
||||
defer is.Unlock(&lockLatency)
|
||||
@@ -1105,14 +1107,13 @@ func (is *ImageStoreLocal) CheckBlob(repo string, digest godigest.Digest) (bool,
|
||||
defer is.RUnlock(&lockLatency)
|
||||
}
|
||||
|
||||
binfo, err := os.Stat(blobPath)
|
||||
if err == nil {
|
||||
is.log.Debug().Str("blob path", blobPath).Msg("blob path found")
|
||||
|
||||
return true, binfo.Size(), nil
|
||||
if ok, size, err := is.StatBlob(repo, digest); err == nil || ok {
|
||||
return true, size, nil
|
||||
}
|
||||
|
||||
is.log.Debug().Err(err).Str("blob", blobPath).Msg("failed to find blob, searching it in cache")
|
||||
blobPath := is.BlobPath(repo, digest)
|
||||
|
||||
is.log.Debug().Str("blob", blobPath).Msg("failed to find blob, searching it in cache")
|
||||
|
||||
// Check blobs in cache
|
||||
dstRecord, err := is.checkCacheBlob(digest)
|
||||
@@ -1135,6 +1136,24 @@ func (is *ImageStoreLocal) CheckBlob(repo string, digest godigest.Digest) (bool,
|
||||
return true, blobSize, nil
|
||||
}
|
||||
|
||||
// StatBlob verifies if a blob is present inside a repository. The caller function SHOULD lock from outside.
|
||||
func (is *ImageStoreLocal) StatBlob(repo string, digest godigest.Digest) (bool, int64, error) {
|
||||
if err := digest.Validate(); err != nil {
|
||||
return false, -1, err
|
||||
}
|
||||
|
||||
blobPath := is.BlobPath(repo, digest)
|
||||
|
||||
binfo, err := os.Stat(blobPath)
|
||||
if err != nil {
|
||||
is.log.Debug().Str("blob path", blobPath).Msg("failed to find blob")
|
||||
|
||||
return false, -1, zerr.ErrBlobNotFound
|
||||
}
|
||||
|
||||
return true, binfo.Size(), nil
|
||||
}
|
||||
|
||||
func (is *ImageStoreLocal) checkCacheBlob(digest godigest.Digest) (string, error) {
|
||||
if err := digest.Validate(); err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -2191,10 +2191,18 @@ func TestGarbageCollect(t *testing.T) {
|
||||
So(err, ShouldNotBeNil)
|
||||
So(hasBlob, ShouldEqual, false)
|
||||
|
||||
hasBlob, _, err = imgStore.StatBlob(repoName, odigest)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(hasBlob, ShouldEqual, false)
|
||||
|
||||
hasBlob, _, err = imgStore.CheckBlob(repoName, bdigest)
|
||||
So(err, ShouldBeNil)
|
||||
So(hasBlob, ShouldEqual, true)
|
||||
|
||||
hasBlob, _, err = imgStore.StatBlob(repoName, bdigest)
|
||||
So(err, ShouldBeNil)
|
||||
So(hasBlob, ShouldEqual, true)
|
||||
|
||||
// sleep so orphan blob can be GC'ed
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user