feat(repodb): update referrers api to use repodb (#1230)

Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
This commit is contained in:
LaurentiuNiculae
2023-03-10 20:37:29 +02:00
committed by GitHub
parent c731acf6de
commit 5d1f91a79f
37 changed files with 2011 additions and 201 deletions
+129 -1
View File
@@ -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
View File
@@ -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)
})
}
+65 -8
View File
@@ -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
}