added locker into image checker; added blob digest checking

This commit is contained in:
2026-03-31 13:21:27 +02:00
parent 1c894e190d
commit 323825b7ff
2 changed files with 80 additions and 30 deletions
+58 -10
View File
@@ -6,8 +6,12 @@ package imageoper
import (
"context"
"encoding/json"
"io"
"net/http"
"mstore/pkg/descr"
ocidigest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -23,44 +27,88 @@ func (oper *Operator) CheckImages(ctx context.Context, params *CheckImagesParams
res := &CheckImagesResult{
Repositories: make([]string, 0),
}
manDescrs, err := oper.mdb.ListAllManifests(ctx)
var manDescrs []descr.Manifest
if params.Name == "" {
manDescrs, err = oper.mdb.ListAllManifests(ctx)
if err != nil {
return res, http.StatusInternalServerError, err
}
} else {
manDescrs, err = oper.mdb.ListManifestsByName(ctx, params.Name)
if err != nil {
return res, http.StatusInternalServerError, err
}
}
for _, manDescr := range manDescrs {
incorrectImage, err := oper.checkImage(ctx, manDescr)
if err != nil {
return res, http.StatusInternalServerError, err
}
if incorrectImage {
repo := manDescr.Name + ":" + manDescr.Reference
res.Repositories = append(res.Repositories, repo)
}
}
return res, http.StatusOK, err
}
func (oper *Operator) checkImage(ctx context.Context, manDescr descr.Manifest) (bool, error) {
resName := manDescr.Name
oper.iLock.WaitAndLock(resName)
defer oper.iLock.Done(resName)
var err error
incorrectImage := false
oper.logg.Debugf("Check image %s:%s", manDescr.Name, manDescr.Reference)
man := &ocispec.Manifest{}
err = json.Unmarshal([]byte(manDescr.Payload), man)
if err != nil {
return res, http.StatusInternalServerError, err
return incorrectImage, err
}
blobs := make([]ocispec.Descriptor, 0)
blobs = append(blobs, man.Config)
blobs = append(blobs, man.Layers...)
incorrectImage := false
for _, blob := range blobs {
oper.logg.Debugf("Check block %s", blob.Digest.String())
oper.logg.Debugf("Check blob %s", blob.Digest.String())
blobExists, blobDescr, err := oper.mdb.GetBlobByNameRefDigest(ctx, manDescr.Name, manDescr.Reference, blob.Digest.String())
if err != nil {
return res, http.StatusInternalServerError, err
return incorrectImage, err
}
blobExists, blobSize, err := oper.store.BlobExists(blobDescr.Name, blobDescr.Digest)
if err != nil {
return res, http.StatusInternalServerError, err
return incorrectImage, err
}
if !blobExists || blobSize != blobDescr.Size {
incorrectImage = true
} else {
digstr := blobDescr.Digest
digobj, err := ocidigest.Parse(digstr)
if err != nil {
oper.logg.Debugf("Incorrect blob name: %s", digstr)
incorrectImage = true
}
_, blobReadCloser, err := oper.store.BlobReader(blobDescr.Name, blobDescr.Digest)
if err != nil {
return incorrectImage, err
}
defer blobReadCloser.Close()
verifier := digobj.Verifier()
_, err = io.Copy(verifier, blobReadCloser)
if !verifier.Verified() {
oper.logg.Debugf("Incorrect blob digest: %s", digstr)
incorrectImage = true
}
}
}
if incorrectImage {
repo := manDescr.Name + ":" + manDescr.Reference
oper.logg.Debugf("Delete incomplete image: %s", repo)
res.Repositories = append(res.Repositories, repo)
err = oper.deleteManifestObjects(ctx, manDescr.Name, manDescr.Reference)
if err != nil {
return res, http.StatusInternalServerError, err
return incorrectImage, err
}
}
}
return res, http.StatusOK, err
return incorrectImage, err
}
+2
View File
@@ -103,6 +103,8 @@ func (svc *Service) Build() error {
svc.rout.Post(`/v3/api/grant/delete`, svc.hand.DeleteGrant)
svc.rout.Post(`/v3/api/grants/list`, svc.hand.ListGrants)
svc.rout.Get(`/{filepath}`, svc.hand.GetFile)
svc.rout.NotFound(svc.hand.NotFound)
selector := svc.rout.Selector()