mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 12:28:01 +08:00
feat(repodb): update referrers api to use repodb (#1230)
Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
This commit is contained in:
+129
-1
@@ -105,6 +105,37 @@ func (img Image) Digest() (godigest.Digest, error) {
|
||||
return godigest.FromBytes(blob), nil
|
||||
}
|
||||
|
||||
type Artifact struct {
|
||||
Manifest ispec.Artifact
|
||||
Blobs []ArtifactBlobs
|
||||
Reference string
|
||||
}
|
||||
|
||||
func (a Artifact) Digest() (godigest.Digest, error) {
|
||||
blob, err := json.Marshal(a.Manifest)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return godigest.FromBytes(blob), nil
|
||||
}
|
||||
|
||||
func (a Artifact) ArtifactData() (repodb.ArtifactData, error) {
|
||||
blob, err := json.Marshal(a.Manifest)
|
||||
if err != nil {
|
||||
return repodb.ArtifactData{}, err
|
||||
}
|
||||
|
||||
return repodb.ArtifactData{
|
||||
ManifestBlob: blob,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type ArtifactBlobs struct {
|
||||
Blob []byte
|
||||
MediaType string
|
||||
}
|
||||
|
||||
type MultiarchImage struct {
|
||||
Index ispec.Index
|
||||
Images []Image
|
||||
@@ -623,6 +654,22 @@ func GetRandomImageComponents(layerSize int) (ispec.Image, [][]byte, ispec.Manif
|
||||
return config, layers, manifest, nil
|
||||
}
|
||||
|
||||
func GetRandomImage(reference string) (Image, error) {
|
||||
const layerSize = 20
|
||||
|
||||
config, layers, manifest, err := GetRandomImageComponents(layerSize)
|
||||
if err != nil {
|
||||
return Image{}, err
|
||||
}
|
||||
|
||||
return Image{
|
||||
Manifest: manifest,
|
||||
Layers: layers,
|
||||
Config: config,
|
||||
Reference: reference,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetImageComponentsWithConfig(conf ispec.Image) (ispec.Image, [][]byte, ispec.Manifest, error) {
|
||||
configBlob, err := json.Marshal(conf)
|
||||
if err = Error(err); err != nil {
|
||||
@@ -728,6 +775,49 @@ func GetImageWithComponents(config ispec.Image, layers [][]byte) (Image, error)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetRandomArtifact(subject *ispec.Descriptor) (Artifact, error) {
|
||||
var randBlob [10]byte
|
||||
|
||||
_, err := rand.Read(randBlob[:])
|
||||
if err != nil {
|
||||
return Artifact{}, err
|
||||
}
|
||||
|
||||
artifactBlobs := []ArtifactBlobs{
|
||||
{
|
||||
Blob: randBlob[:],
|
||||
MediaType: "application/octet-stream",
|
||||
},
|
||||
}
|
||||
|
||||
blobsDescriptors := make([]ispec.Descriptor, 0, len(artifactBlobs))
|
||||
|
||||
for _, artifactBlob := range artifactBlobs {
|
||||
blobsDescriptors = append(blobsDescriptors, ispec.Descriptor{
|
||||
Digest: godigest.FromBytes(artifactBlob.Blob),
|
||||
MediaType: artifactBlob.MediaType,
|
||||
Size: int64(len(artifactBlob.Blob)),
|
||||
})
|
||||
}
|
||||
|
||||
artifactManifest := ispec.Artifact{
|
||||
MediaType: ispec.MediaTypeArtifactManifest,
|
||||
Blobs: blobsDescriptors,
|
||||
Subject: subject,
|
||||
}
|
||||
|
||||
artifactManifestBlob, err := json.Marshal(artifactManifest)
|
||||
if err != nil {
|
||||
return Artifact{}, err
|
||||
}
|
||||
|
||||
return Artifact{
|
||||
Manifest: artifactManifest,
|
||||
Blobs: artifactBlobs,
|
||||
Reference: godigest.FromBytes(artifactManifestBlob).String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetCosignSignatureTagForManifest(manifest ispec.Manifest) (string, error) {
|
||||
manifestBlob, err := json.Marshal(manifest)
|
||||
if err != nil {
|
||||
@@ -743,6 +833,32 @@ func GetCosignSignatureTagForDigest(manifestDigest godigest.Digest) string {
|
||||
return manifestDigest.Algorithm().String() + "-" + manifestDigest.Encoded() + ".sig"
|
||||
}
|
||||
|
||||
func GetImageWithSubject(subjectDigest godigest.Digest, mediaType string) (Image, error) {
|
||||
num := 100
|
||||
|
||||
conf, layers, manifest, err := GetRandomImageComponents(num)
|
||||
if err != nil {
|
||||
return Image{}, err
|
||||
}
|
||||
|
||||
manifest.Subject = &ispec.Descriptor{
|
||||
Digest: subjectDigest,
|
||||
MediaType: mediaType,
|
||||
}
|
||||
|
||||
manifestBlob, err := json.Marshal(manifest)
|
||||
if err != nil {
|
||||
return Image{}, err
|
||||
}
|
||||
|
||||
return Image{
|
||||
Manifest: manifest,
|
||||
Config: conf,
|
||||
Layers: layers,
|
||||
Reference: godigest.FromBytes(manifestBlob).String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func UploadImage(img Image, baseURL, repo string) error {
|
||||
for _, blob := range img.Layers {
|
||||
resp, err := resty.R().Post(baseURL + "/v2/" + repo + "/blobs/uploads/")
|
||||
@@ -830,7 +946,19 @@ func UploadImage(img Image, baseURL, repo string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func UploadArtifact(baseURL, repo string, artifactManifest *ispec.Artifact) error {
|
||||
func DeleteImage(repo, reference, baseURL string) (int, error) {
|
||||
resp, err := resty.R().Delete(
|
||||
fmt.Sprintf(baseURL+"/v2/%s/manifests/%s", repo, reference),
|
||||
)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return resp.StatusCode(), err
|
||||
}
|
||||
|
||||
// UploadArtifactManifest is used in tests where we don't need to upload the blobs of the artifact.
|
||||
func UploadArtifactManifest(artifactManifest *ispec.Artifact, baseURL, repo string) error {
|
||||
// put manifest
|
||||
artifactManifestBlob, err := json.Marshal(artifactManifest)
|
||||
if err != nil {
|
||||
|
||||
+64
-2
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
@@ -21,10 +22,12 @@ import (
|
||||
|
||||
"zotregistry.io/zot/pkg/api"
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
"zotregistry.io/zot/pkg/test/mocks"
|
||||
)
|
||||
|
||||
var ErrTestError = errors.New("test error")
|
||||
var ErrTestError = errors.New("ErrTestError")
|
||||
|
||||
func TestCopyFiles(t *testing.T) {
|
||||
Convey("sourceDir does not exist", t, func() {
|
||||
@@ -238,7 +241,7 @@ func TestUploadArtifact(t *testing.T) {
|
||||
|
||||
artifact := ispec.Artifact{}
|
||||
|
||||
err := test.UploadArtifact(baseURL, "test", &artifact)
|
||||
err := test.UploadArtifactManifest(&artifact, baseURL, "test")
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
@@ -1274,3 +1277,62 @@ func TestGenerateNotationCerts(t *testing.T) {
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestWriteImageToFileSystem(t *testing.T) {
|
||||
Convey("WriteImageToFileSystem errors", t, func() {
|
||||
err := test.WriteImageToFileSystem(test.Image{}, "repo", storage.StoreController{
|
||||
DefaultStore: mocks.MockedImageStore{
|
||||
InitRepoFn: func(name string) error {
|
||||
return ErrTestError
|
||||
},
|
||||
},
|
||||
})
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
err = test.WriteImageToFileSystem(
|
||||
test.Image{Layers: [][]byte{[]byte("testLayer")}},
|
||||
"repo",
|
||||
storage.StoreController{
|
||||
DefaultStore: mocks.MockedImageStore{
|
||||
FullBlobUploadFn: func(repo string, body io.Reader, digest godigest.Digest,
|
||||
) (string, int64, error) {
|
||||
return "", 0, ErrTestError
|
||||
},
|
||||
},
|
||||
})
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
count := 0
|
||||
err = test.WriteImageToFileSystem(
|
||||
test.Image{Layers: [][]byte{[]byte("testLayer")}},
|
||||
"repo",
|
||||
storage.StoreController{
|
||||
DefaultStore: mocks.MockedImageStore{
|
||||
FullBlobUploadFn: func(repo string, body io.Reader, digest godigest.Digest,
|
||||
) (string, int64, error) {
|
||||
if count == 0 {
|
||||
count++
|
||||
|
||||
return "", 0, nil
|
||||
}
|
||||
|
||||
return "", 0, ErrTestError
|
||||
},
|
||||
},
|
||||
})
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
err = test.WriteImageToFileSystem(
|
||||
test.Image{Layers: [][]byte{[]byte("testLayer")}},
|
||||
"repo",
|
||||
storage.StoreController{
|
||||
DefaultStore: mocks.MockedImageStore{
|
||||
PutImageManifestFn: func(repo, reference, mediaType string, body []byte,
|
||||
) (godigest.Digest, error) {
|
||||
return "", ErrTestError
|
||||
},
|
||||
},
|
||||
})
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,6 +40,19 @@ type RepoDBMock struct {
|
||||
|
||||
GetIndexDataFn func(indexDigest godigest.Digest) (repodb.IndexData, error)
|
||||
|
||||
SetArtifactDataFn func(digest godigest.Digest, artifactData repodb.ArtifactData) error
|
||||
|
||||
GetArtifactDataFn func(artifactDigest godigest.Digest) (repodb.ArtifactData, error)
|
||||
|
||||
SetReferrerFn func(repo string, referredDigest godigest.Digest, referrer repodb.Descriptor) error
|
||||
|
||||
DeleteReferrerFn func(repo string, referredDigest godigest.Digest, referrerDigest godigest.Digest) error
|
||||
|
||||
GetReferrersFn func(repo string, referredDigest godigest.Digest) ([]repodb.Descriptor, error)
|
||||
|
||||
GetFilteredReferrersInfoFn func(repo string, referredDigest godigest.Digest, artifactTypes []string) (
|
||||
[]repodb.ReferrerInfo, error)
|
||||
|
||||
IncrementImageDownloadsFn func(repo string, reference string) error
|
||||
|
||||
AddManifestSignatureFn func(repo string, signedManifestDigest godigest.Digest, sm repodb.SignatureMetadata) error
|
||||
@@ -103,14 +116,6 @@ func (sdm RepoDBMock) GetRepoStars(repo string) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) SetRepoLogo(repo string, logoPath string) error {
|
||||
if sdm.SetRepoLogoFn != nil {
|
||||
return sdm.SetRepoLogoFn(repo, logoPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) SetRepoReference(repo string, reference string, manifestDigest godigest.Digest,
|
||||
mediaType string,
|
||||
) error {
|
||||
@@ -300,3 +305,55 @@ func (sdm RepoDBMock) PatchDB() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) SetArtifactData(digest godigest.Digest, artifactData repodb.ArtifactData) error {
|
||||
if sdm.SetArtifactDataFn != nil {
|
||||
return sdm.SetArtifactDataFn(digest, artifactData)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) GetArtifactData(artifactDigest godigest.Digest) (repodb.ArtifactData, error) {
|
||||
if sdm.GetArtifactDataFn != nil {
|
||||
return sdm.GetArtifactDataFn(artifactDigest)
|
||||
}
|
||||
|
||||
return repodb.ArtifactData{}, nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) SetReferrer(repo string, referredDigest godigest.Digest, referrer repodb.Descriptor) error {
|
||||
if sdm.SetReferrerFn != nil {
|
||||
return sdm.SetReferrerFn(repo, referredDigest, referrer)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) DeleteReferrer(repo string, referredDigest godigest.Digest,
|
||||
referrerDigest godigest.Digest,
|
||||
) error {
|
||||
if sdm.DeleteReferrerFn != nil {
|
||||
return sdm.DeleteReferrerFn(repo, referredDigest, referrerDigest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) GetReferrers(repo string, referredDigest godigest.Digest) ([]repodb.Descriptor, error) {
|
||||
if sdm.GetReferrersFn != nil {
|
||||
return sdm.GetReferrersFn(repo, referredDigest)
|
||||
}
|
||||
|
||||
return []repodb.Descriptor{}, nil
|
||||
}
|
||||
|
||||
func (sdm RepoDBMock) GetFilteredReferrersInfo(repo string, referredDigest godigest.Digest,
|
||||
artifactTypes []string,
|
||||
) ([]repodb.ReferrerInfo, error) {
|
||||
if sdm.GetFilteredReferrersInfoFn != nil {
|
||||
return sdm.GetFilteredReferrersInfoFn(repo, referredDigest, artifactTypes)
|
||||
}
|
||||
|
||||
return []repodb.ReferrerInfo{}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user