mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 20:38:08 +08:00
feat: propagate detailed error msgs to client (OCI dist-spec format) (#1681)
Signed-off-by: Alexei Dodon <adodon@cisco.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"path"
|
||||
@@ -27,8 +28,7 @@ import (
|
||||
|
||||
const (
|
||||
manifestWithEmptyLayersErrMsg = "layers: Array must have at least 1 items"
|
||||
|
||||
cosignSignatureTagSuffix = "sig"
|
||||
cosignSignatureTagSuffix = "sig"
|
||||
)
|
||||
|
||||
func GetTagsByIndex(index ispec.Index) []string {
|
||||
@@ -86,7 +86,7 @@ func ValidateManifest(imgStore storageTypes.ImageStore, repo, reference, mediaTy
|
||||
if err := ValidateManifestSchema(body); err != nil {
|
||||
log.Error().Err(err).Msg("OCIv1 image manifest schema validation failed")
|
||||
|
||||
return "", zerr.ErrBadManifest
|
||||
return "", zerr.NewError(zerr.ErrBadManifest).AddDetail("jsonSchemaValidation", err.Error())
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(body, &manifest); err != nil {
|
||||
@@ -125,7 +125,7 @@ func ValidateManifest(imgStore storageTypes.ImageStore, repo, reference, mediaTy
|
||||
if err := ValidateImageIndexSchema(body); err != nil {
|
||||
log.Error().Err(err).Msg("OCIv1 image index manifest schema validation failed")
|
||||
|
||||
return "", err
|
||||
return "", zerr.NewError(zerr.ErrBadManifest).AddDetail("jsonSchemaValidation", err.Error())
|
||||
}
|
||||
|
||||
var indexManifest ispec.Index
|
||||
@@ -219,8 +219,10 @@ func CheckIfIndexNeedsUpdate(index *ispec.Index, desc *ispec.Descriptor,
|
||||
log.Error().Err(err).
|
||||
Str("old mediaType", manifest.MediaType).
|
||||
Str("new mediaType", desc.MediaType).Msg("cannot change media-type")
|
||||
reason := fmt.Sprintf("changing manifest media-type from \"%s\" to \"%s\" is disallowed",
|
||||
manifest.MediaType, desc.MediaType)
|
||||
|
||||
return false, "", err
|
||||
return false, "", zerr.NewError(err).AddDetail("reason", reason)
|
||||
}
|
||||
|
||||
oldDesc := *desc
|
||||
@@ -780,7 +782,7 @@ func IsNonDistributable(mediaType string) bool {
|
||||
func ValidateManifestSchema(buf []byte) error {
|
||||
if err := schema.ValidatorMediaTypeManifest.Validate(bytes.NewBuffer(buf)); err != nil {
|
||||
if !IsEmptyLayersError(err) {
|
||||
return zerr.ErrBadManifest
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,7 +791,7 @@ func ValidateManifestSchema(buf []byte) error {
|
||||
|
||||
func ValidateImageIndexSchema(buf []byte) error {
|
||||
if err := schema.ValidatorMediaTypeImageIndex.Validate(bytes.NewBuffer(buf)); err != nil {
|
||||
return zerr.ErrBadManifest
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -3,6 +3,7 @@ package storage_test
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
|
||||
"zotregistry.io/zot/errors"
|
||||
zerr "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
@@ -74,6 +75,10 @@ func TestValidateManifest(t *testing.T) {
|
||||
|
||||
_, _, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, body)
|
||||
So(err, ShouldNotBeNil)
|
||||
var internalErr *zerr.Error
|
||||
So(errors.As(err, &internalErr), ShouldBeTrue)
|
||||
So(internalErr.GetDetails(), ShouldContainKey, "jsonSchemaValidation")
|
||||
So(internalErr.GetDetails()["jsonSchemaValidation"], ShouldEqual, "[schemaVersion: Must be less than or equal to 2]")
|
||||
})
|
||||
|
||||
Convey("manifest with non-distributable layers", func() {
|
||||
@@ -169,7 +174,7 @@ func TestGetReferrersErrors(t *testing.T) {
|
||||
return indexBuf, nil
|
||||
},
|
||||
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
||||
return []byte{}, errors.ErrBlobNotFound
|
||||
return []byte{}, zerr.ErrBlobNotFound
|
||||
},
|
||||
}
|
||||
|
||||
@@ -188,7 +193,7 @@ func TestGetReferrersErrors(t *testing.T) {
|
||||
return indexBuf, nil
|
||||
},
|
||||
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
||||
return []byte{}, errors.ErrBadBlob
|
||||
return []byte{}, zerr.ErrBadBlob
|
||||
},
|
||||
}
|
||||
|
||||
@@ -363,7 +368,7 @@ func TestGetImageIndexErrors(t *testing.T) {
|
||||
Convey("Trigger GetBlobContent error", t, func(c C) {
|
||||
imgStore := &mocks.MockedImageStore{
|
||||
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
||||
return []byte{}, errors.ErrBlobNotFound
|
||||
return []byte{}, zerr.ErrBlobNotFound
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user