mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 04:17:55 +08:00
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:
@@ -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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user