feat(pagination): move pagination and sorting image summary results after conversion (#1637)

fix(config): check for config media type when pushing to repodb

Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
This commit is contained in:
LaurentiuNiculae
2023-07-31 22:16:09 +03:00
committed by GitHub
parent 20391a21c0
commit 9e38ca51e3
39 changed files with 2361 additions and 3182 deletions
+26
View File
@@ -14,6 +14,10 @@ import (
storageConstants "zotregistry.io/zot/pkg/storage/constants"
)
const (
TestFakeSignatureArtType = "application/test.fake.signature"
)
// LayerBuilder abstracts the first step in creating an OCI image, specifying the layers of the image.
type LayerBuilder interface {
// LayerBlobs sets the image layers from the gives blobs array, adding a default zipped layer media type.
@@ -46,6 +50,8 @@ type ConfigBuilder interface {
ArtifactConfig(artifactType string) ManifestBuilder
// DefaultConfig sets the default config, platform linux/amd64.
DefaultConfig() ManifestBuilder
// CustomConfigBlob will set a custom blob as the image config without other checks.
CustomConfigBlob(configBlob []byte, mediaType string) ManifestBuilder
// RandomConfig sets a randomly generated config.
RandomConfig() ManifestBuilder
}
@@ -163,6 +169,13 @@ func CreateRandomVulnerableImageWith() ManifestBuilder {
return CreateImageWith().VulnerableLayers().RandomVulnConfig()
}
// CreateFakeTestSignature returns a test signature that is used to mark a image as signed
// when creating a test Repo. It won't be recognized as a signature if uploaded to the repository directly.
func CreateFakeTestSignature(subject *ispec.Descriptor) Image {
return CreateImageWith().RandomLayers(1, 10).DefaultConfig().
ArtifactType(TestFakeSignatureArtType).Subject(subject).Build()
}
type BaseImageBuilder struct {
layers []Layer
@@ -283,6 +296,19 @@ func (ib *BaseImageBuilder) ArtifactConfig(artifactType string) ManifestBuilder
return ib
}
func (ib *BaseImageBuilder) CustomConfigBlob(configBlob []byte, mediaType string) ManifestBuilder {
ib.config = ispec.Image{}
ib.configDescriptor = ispec.Descriptor{
MediaType: mediaType,
Size: int64(len(configBlob)),
Data: configBlob,
Digest: godigest.FromBytes(configBlob),
}
return ib
}
func (ib *BaseImageBuilder) RandomConfig() ManifestBuilder {
config := GetDefaultConfig()
config.Author = getRandomAuthor()
+26 -85
View File
@@ -5,7 +5,6 @@ import (
godigest "github.com/opencontainers/go-digest"
"zotregistry.io/zot/pkg/common"
mTypes "zotregistry.io/zot/pkg/meta/types"
)
@@ -30,8 +29,8 @@ type MetaDBMock struct {
SetRepoMetaFn func(repo string, repoMeta mTypes.RepoMetadata) error
GetMultipleRepoMetaFn func(ctx context.Context, filter func(repoMeta mTypes.RepoMetadata) bool,
requestedPage mTypes.PageInput) ([]mTypes.RepoMetadata, error)
GetMultipleRepoMetaFn func(ctx context.Context, filter func(repoMeta mTypes.RepoMetadata) bool) (
[]mTypes.RepoMetadata, error)
GetManifestDataFn func(manifestDigest godigest.Digest) (mTypes.ManifestData, error)
@@ -62,34 +61,19 @@ type MetaDBMock struct {
DeleteSignatureFn func(repo string, signedManifestDigest godigest.Digest, sm mTypes.SignatureMetadata) error
SearchReposFn func(ctx context.Context, txt string, filter mTypes.Filter, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo,
SearchReposFn func(ctx context.Context, txt string) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData,
error)
SearchTagsFn func(ctx context.Context, txt string, filter mTypes.Filter, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo,
SearchTagsFn func(ctx context.Context, txt string) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData,
error)
FilterReposFn func(ctx context.Context, filter mTypes.FilterRepoFunc, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo,
error)
FilterReposFn func(ctx context.Context, filter mTypes.FilterRepoFunc) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, error)
FilterTagsFn func(ctx context.Context, filterFunc mTypes.FilterFunc, filter mTypes.Filter,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo,
error)
SearchDigestsFn func(ctx context.Context, searchText string, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error)
SearchLayersFn func(ctx context.Context, searchText string, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error)
SearchForAscendantImagesFn func(ctx context.Context, searchText string, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error)
SearchForDescendantImagesFn func(ctx context.Context, searchText string, requestedPage mTypes.PageInput) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error)
FilterTagsFn func(ctx context.Context, filterFunc mTypes.FilterFunc) (
[]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, error)
GetStarredReposFn func(ctx context.Context) ([]string, error)
@@ -195,10 +179,9 @@ func (sdm MetaDBMock) SetRepoMeta(repo string, repoMeta mTypes.RepoMetadata) err
}
func (sdm MetaDBMock) GetMultipleRepoMeta(ctx context.Context, filter func(repoMeta mTypes.RepoMetadata) bool,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, error) {
if sdm.GetMultipleRepoMetaFn != nil {
return sdm.GetMultipleRepoMetaFn(ctx, filter, requestedPage)
return sdm.GetMultipleRepoMetaFn(ctx, filter)
}
return []mTypes.RepoMetadata{}, nil
@@ -272,86 +255,44 @@ func (sdm MetaDBMock) DeleteSignature(repo string, signedManifestDigest godigest
return nil
}
func (sdm MetaDBMock) SearchRepos(ctx context.Context, searchText string, filter mTypes.Filter,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo, error) {
func (sdm MetaDBMock) SearchRepos(ctx context.Context, searchText string,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, error) {
if sdm.SearchReposFn != nil {
return sdm.SearchReposFn(ctx, searchText, filter, requestedPage)
return sdm.SearchReposFn(ctx, searchText)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{},
map[string]mTypes.IndexData{}, common.PageInfo{}, nil
map[string]mTypes.IndexData{}, nil
}
func (sdm MetaDBMock) SearchTags(ctx context.Context, searchText string, filter mTypes.Filter,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo, error) {
func (sdm MetaDBMock) SearchTags(ctx context.Context, searchText string,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, error) {
if sdm.SearchTagsFn != nil {
return sdm.SearchTagsFn(ctx, searchText, filter, requestedPage)
return sdm.SearchTagsFn(ctx, searchText)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{},
map[string]mTypes.IndexData{}, common.PageInfo{}, nil
map[string]mTypes.IndexData{}, nil
}
func (sdm MetaDBMock) FilterRepos(ctx context.Context, filter mTypes.FilterRepoFunc,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo, error) {
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, error) {
if sdm.FilterReposFn != nil {
return sdm.FilterReposFn(ctx, filter, requestedPage)
return sdm.FilterReposFn(ctx, filter)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{},
map[string]mTypes.IndexData{}, common.PageInfo{}, nil
map[string]mTypes.IndexData{}, nil
}
func (sdm MetaDBMock) FilterTags(ctx context.Context, filterFunc mTypes.FilterFunc, filter mTypes.Filter,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, common.PageInfo, error) {
func (sdm MetaDBMock) FilterTags(ctx context.Context, filterFunc mTypes.FilterFunc,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, map[string]mTypes.IndexData, error) {
if sdm.FilterTagsFn != nil {
return sdm.FilterTagsFn(ctx, filterFunc, filter, requestedPage)
return sdm.FilterTagsFn(ctx, filterFunc)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{},
map[string]mTypes.IndexData{}, common.PageInfo{}, nil
}
func (sdm MetaDBMock) SearchDigests(ctx context.Context, searchText string, requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error) {
if sdm.SearchDigestsFn != nil {
return sdm.SearchDigestsFn(ctx, searchText, requestedPage)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{}, nil
}
func (sdm MetaDBMock) SearchLayers(ctx context.Context, searchText string, requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error) {
if sdm.SearchLayersFn != nil {
return sdm.SearchLayersFn(ctx, searchText, requestedPage)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{}, nil
}
func (sdm MetaDBMock) SearchForAscendantImages(ctx context.Context, searchText string,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error) {
if sdm.SearchForAscendantImagesFn != nil {
return sdm.SearchForAscendantImagesFn(ctx, searchText, requestedPage)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{}, nil
}
func (sdm MetaDBMock) SearchForDescendantImages(ctx context.Context, searchText string,
requestedPage mTypes.PageInput,
) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata, error) {
if sdm.SearchForDescendantImagesFn != nil {
return sdm.SearchForDescendantImagesFn(ctx, searchText, requestedPage)
}
return []mTypes.RepoMetadata{}, map[string]mTypes.ManifestMetadata{}, nil
map[string]mTypes.IndexData{}, nil
}
func (sdm MetaDBMock) SetIndexData(digest godigest.Digest, indexData mTypes.IndexData) error {
+91
View File
@@ -0,0 +1,91 @@
package test
import (
ispec "github.com/opencontainers/image-spec/specs-go/v1"
mTypes "zotregistry.io/zot/pkg/meta/types"
)
type RepoImage struct {
Image
Tag string
}
type RepoMultiArchImage struct {
MultiarchImage
Tag string
}
type Repo struct {
Name string
Images []RepoImage
MultiArchImages []RepoMultiArchImage
IsBookmarked bool
IsStarred bool
}
func GetMetadataForRepos(repos ...Repo) ([]mTypes.RepoMetadata, map[string]mTypes.ManifestMetadata,
map[string]mTypes.IndexData,
) {
var (
reposMetadata = []mTypes.RepoMetadata{}
manifestMetadataMap = map[string]mTypes.ManifestMetadata{}
indexDataMap = map[string]mTypes.IndexData{}
)
for _, repo := range repos {
repoMeta := mTypes.RepoMetadata{
Name: repo.Name,
Tags: map[string]mTypes.Descriptor{},
Signatures: map[string]mTypes.ManifestSignatures{},
IsStarred: repo.IsStarred,
IsBookmarked: repo.IsBookmarked,
}
for _, image := range repo.Images {
if image.Tag != "" {
repoMeta.Tags[image.Tag] = mTypes.Descriptor{
MediaType: ispec.MediaTypeImageManifest,
Digest: image.DigestStr(),
}
}
// here we can do many more checks about the images like check for referrers, signatures but it's not needed yet
// I need just the tags for now and the fake signature.
// This is done just to mark a manifest as signed in the resulted RepoMeta
if image.Manifest.ArtifactType == TestFakeSignatureArtType && image.Manifest.Subject != nil {
signedManifestDig := image.Manifest.Subject.Digest.String()
repoMeta.Signatures[signedManifestDig] = mTypes.ManifestSignatures{
"fakeSignature": []mTypes.SignatureInfo{{SignatureManifestDigest: image.ManifestDescriptor.Digest.String()}},
}
}
manifestMetadataMap[image.ManifestDescriptor.Digest.String()] = mTypes.ManifestMetadata{
ManifestBlob: image.ManifestDescriptor.Data,
ConfigBlob: image.ConfigDescriptor.Data,
}
}
for _, multiArch := range repo.MultiArchImages {
repoMeta.Tags[multiArch.Tag] = mTypes.Descriptor{
MediaType: ispec.MediaTypeImageIndex,
Digest: multiArch.DigestStr(),
}
for _, image := range multiArch.Images {
manifestMetadataMap[image.ManifestDescriptor.Digest.String()] = mTypes.ManifestMetadata{
ManifestBlob: image.ManifestDescriptor.Data,
ConfigBlob: image.ConfigDescriptor.Data,
}
}
indexDataMap[multiArch.indexDescriptor.Digest.String()] = mTypes.IndexData{
IndexBlob: multiArch.indexDescriptor.Data,
}
}
reposMetadata = append(reposMetadata, repoMeta)
}
return reposMetadata, manifestMetadataMap, indexDataMap
}