2022-09-30 12:35:16 -05:00
|
|
|
package storage_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
2023-08-23 12:59:52 -05:00
|
|
|
"errors"
|
2022-09-30 12:35:16 -05:00
|
|
|
"os"
|
2023-09-01 12:54:39 -05:00
|
|
|
"path"
|
2022-09-30 12:35:16 -05:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
godigest "github.com/opencontainers/go-digest"
|
|
|
|
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
2022-11-15 01:21:49 -05:00
|
|
|
artifactspec "github.com/oras-project/artifacts-spec/specs-go/v1"
|
2022-09-30 12:35:16 -05:00
|
|
|
"github.com/rs/zerolog"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
2022-10-20 11:39:20 -05:00
|
|
|
|
2023-08-23 12:59:52 -05:00
|
|
|
zerr "zotregistry.io/zot/errors"
|
2022-09-30 12:35:16 -05:00
|
|
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
|
|
|
"zotregistry.io/zot/pkg/log"
|
|
|
|
"zotregistry.io/zot/pkg/storage"
|
2022-11-02 17:53:08 -05:00
|
|
|
"zotregistry.io/zot/pkg/storage/cache"
|
2023-05-26 13:08:19 -05:00
|
|
|
common "zotregistry.io/zot/pkg/storage/common"
|
|
|
|
storageConstants "zotregistry.io/zot/pkg/storage/constants"
|
2022-09-30 12:35:16 -05:00
|
|
|
"zotregistry.io/zot/pkg/storage/local"
|
|
|
|
"zotregistry.io/zot/pkg/test"
|
2023-09-15 11:53:15 -05:00
|
|
|
. "zotregistry.io/zot/pkg/test/image-utils"
|
2022-11-15 01:21:49 -05:00
|
|
|
"zotregistry.io/zot/pkg/test/mocks"
|
2022-09-30 12:35:16 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestValidateManifest(t *testing.T) {
|
|
|
|
Convey("Make manifest", t, func(c C) {
|
|
|
|
dir := t.TempDir()
|
|
|
|
|
|
|
|
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
|
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
2022-11-02 17:53:08 -05:00
|
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
|
|
RootDir: dir,
|
|
|
|
Name: "cache",
|
|
|
|
UseRelPaths: true,
|
|
|
|
}, log)
|
2023-09-01 12:54:39 -05:00
|
|
|
imgStore := local.NewImageStore(dir, true, true, storageConstants.DefaultGCDelay,
|
|
|
|
storageConstants.DefaultUntaggedImgeRetentionDelay, true, true, log, metrics, nil, cacheDriver)
|
2022-09-30 12:35:16 -05:00
|
|
|
|
|
|
|
content := []byte("this is a blob")
|
|
|
|
digest := godigest.FromBytes(content)
|
|
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
|
2022-10-22 15:46:13 -05:00
|
|
|
_, blen, err := imgStore.FullBlobUpload("test", bytes.NewReader(content), digest)
|
2022-09-30 12:35:16 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(blen, ShouldEqual, len(content))
|
|
|
|
|
|
|
|
cblob, cdigest := test.GetRandomImageConfig()
|
2022-10-22 15:46:13 -05:00
|
|
|
_, clen, err := imgStore.FullBlobUpload("test", bytes.NewReader(cblob), cdigest)
|
2022-09-30 12:35:16 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(clen, ShouldEqual, len(cblob))
|
|
|
|
|
|
|
|
Convey("bad manifest schema version", func() {
|
|
|
|
manifest := ispec.Manifest{
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: ispec.MediaTypeImageConfig,
|
|
|
|
Digest: cdigest,
|
|
|
|
Size: int64(len(cblob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: ispec.MediaTypeImageLayer,
|
|
|
|
Digest: digest,
|
|
|
|
Size: int64(len(content)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
manifest.SchemaVersion = 999
|
|
|
|
|
|
|
|
body, err := json.Marshal(manifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
2023-05-12 11:32:01 -05:00
|
|
|
_, _, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, body)
|
2022-09-30 12:35:16 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
2023-08-23 12:59:52 -05:00
|
|
|
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]")
|
2022-09-30 12:35:16 -05:00
|
|
|
})
|
2023-05-01 14:49:41 -05:00
|
|
|
|
2023-09-01 12:54:39 -05:00
|
|
|
Convey("bad config blob", func() {
|
|
|
|
manifest := ispec.Manifest{
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: ispec.MediaTypeImageConfig,
|
|
|
|
Digest: cdigest,
|
|
|
|
Size: int64(len(cblob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: ispec.MediaTypeImageLayer,
|
|
|
|
Digest: digest,
|
|
|
|
Size: int64(len(content)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
manifest.SchemaVersion = 2
|
|
|
|
|
|
|
|
configBlobPath := imgStore.BlobPath("test", cdigest)
|
|
|
|
|
|
|
|
err := os.WriteFile(configBlobPath, []byte("bad config blob"), 0o000)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
body, err := json.Marshal(manifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
// this was actually an umoci error on config blob
|
|
|
|
_, _, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, body)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
})
|
|
|
|
|
2023-05-01 14:49:41 -05:00
|
|
|
Convey("manifest with non-distributable layers", func() {
|
|
|
|
content := []byte("this blob doesn't exist")
|
|
|
|
digest := godigest.FromBytes(content)
|
|
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
|
|
|
|
manifest := ispec.Manifest{
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: ispec.MediaTypeImageConfig,
|
|
|
|
Digest: cdigest,
|
|
|
|
Size: int64(len(cblob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{
|
|
|
|
{
|
2023-05-10 12:15:33 -05:00
|
|
|
MediaType: ispec.MediaTypeImageLayerNonDistributable, //nolint:staticcheck
|
2023-05-01 14:49:41 -05:00
|
|
|
Digest: digest,
|
|
|
|
Size: int64(len(content)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
manifest.SchemaVersion = 2
|
|
|
|
|
|
|
|
body, err := json.Marshal(manifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
2023-05-12 11:32:01 -05:00
|
|
|
_, _, err = imgStore.PutImageManifest("test", "1.0", ispec.MediaTypeImageManifest, body)
|
2023-05-01 14:49:41 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
})
|
2022-09-30 12:35:16 -05:00
|
|
|
})
|
|
|
|
}
|
2022-11-15 01:21:49 -05:00
|
|
|
|
|
|
|
func TestGetReferrersErrors(t *testing.T) {
|
|
|
|
Convey("make storage", t, func(c C) {
|
|
|
|
dir := t.TempDir()
|
|
|
|
|
|
|
|
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
|
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
|
|
RootDir: dir,
|
|
|
|
Name: "cache",
|
|
|
|
UseRelPaths: true,
|
|
|
|
}, log)
|
|
|
|
|
2023-09-01 12:54:39 -05:00
|
|
|
imgStore := local.NewImageStore(dir, true, true, storageConstants.DefaultGCDelay,
|
|
|
|
storageConstants.DefaultUntaggedImgeRetentionDelay, false, true, log, metrics, nil, cacheDriver)
|
2022-11-15 01:21:49 -05:00
|
|
|
|
|
|
|
artifactType := "application/vnd.example.icecream.v1"
|
|
|
|
validDigest := godigest.FromBytes([]byte("blob"))
|
|
|
|
|
|
|
|
Convey("Trigger invalid digest error", func(c C) {
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err := common.GetReferrers(imgStore, "zot-test", "invalidDigest",
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{artifactType}, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", "invalidDigest",
|
2023-09-01 12:54:39 -05:00
|
|
|
artifactType, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Trigger repo not found error", func(c C) {
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err := common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{artifactType}, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
artifactType, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
2023-08-18 03:46:11 -05:00
|
|
|
storageCtlr := storage.StoreController{DefaultStore: imgStore}
|
2023-09-15 11:53:15 -05:00
|
|
|
err := test.WriteImageToFileSystem(CreateDefaultImage(), "zot-test", "0.0.1", storageCtlr)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
digest := godigest.FromBytes([]byte("{}"))
|
|
|
|
|
|
|
|
index := ispec.Index{
|
|
|
|
Manifests: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: artifactspec.MediaTypeArtifactManifest,
|
|
|
|
Digest: digest,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
indexBuf, err := json.Marshal(index)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
Convey("Trigger GetBlobContent() not found", func(c C) {
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return indexBuf, nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
2023-08-23 12:59:52 -05:00
|
|
|
return []byte{}, zerr.ErrBlobNotFound
|
2022-11-15 01:21:49 -05:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{artifactType}, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
artifactType, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Trigger GetBlobContent() generic error", func(c C) {
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return indexBuf, nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
2023-08-23 12:59:52 -05:00
|
|
|
return []byte{}, zerr.ErrBadBlob
|
2022-11-15 01:21:49 -05:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{artifactType}, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
2023-02-13 13:43:52 -05:00
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
artifactType, log)
|
2023-02-13 13:43:52 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
2022-11-15 01:21:49 -05:00
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Trigger continue on different artifactType", func(c C) {
|
|
|
|
orasManifest := artifactspec.Manifest{
|
|
|
|
Subject: &artifactspec.Descriptor{
|
|
|
|
Digest: digest,
|
|
|
|
ArtifactType: "unknown",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
orasBuf, err := json.Marshal(orasManifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return indexBuf, nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return orasBuf, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
artifactType, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", digest,
|
2023-09-01 12:54:39 -05:00
|
|
|
artifactType, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
2023-02-13 13:43:52 -05:00
|
|
|
Convey("Unmarshal oras artifact error", func(c C) {
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return indexBuf, nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return []byte("wrong content"), nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-09-01 12:54:39 -05:00
|
|
|
_, err = common.GetOrasReferrers(imgStore, "zot-test", validDigest, artifactType, log)
|
2023-02-13 13:43:52 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
2022-11-15 01:21:49 -05:00
|
|
|
Convey("Trigger unmarshal error on manifest image mediaType", func(c C) {
|
|
|
|
index = ispec.Index{
|
|
|
|
Manifests: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: ispec.MediaTypeImageManifest,
|
|
|
|
Digest: digest,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
indexBuf, err = json.Marshal(index)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return indexBuf, nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return []byte{}, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{artifactType}, log)
|
2022-11-15 01:21:49 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Trigger nil subject", func(c C) {
|
|
|
|
index = ispec.Index{
|
|
|
|
Manifests: []ispec.Descriptor{
|
|
|
|
{
|
2023-05-10 12:15:33 -05:00
|
|
|
MediaType: ispec.MediaTypeImageManifest,
|
2022-11-15 01:21:49 -05:00
|
|
|
Digest: digest,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
indexBuf, err = json.Marshal(index)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
ociManifest := ispec.Manifest{
|
|
|
|
Subject: nil,
|
|
|
|
}
|
|
|
|
|
|
|
|
ociManifestBuf, err := json.Marshal(ociManifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return indexBuf, nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return ociManifestBuf, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err = common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{artifactType}, log)
|
2022-11-28 13:43:53 -05:00
|
|
|
So(err, ShouldBeNil)
|
2022-11-15 01:21:49 -05:00
|
|
|
})
|
2023-07-05 11:42:16 -05:00
|
|
|
|
|
|
|
Convey("Index bad blob", func() {
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return []byte(`{
|
|
|
|
"manifests": [{
|
|
|
|
"digest": "digest",
|
|
|
|
"mediaType": "application/vnd.oci.image.index.v1+json"
|
|
|
|
}]
|
|
|
|
}`), nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return []byte("bad blob"), nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{}, log)
|
2023-07-05 11:42:16 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Index bad artifac type", func() {
|
|
|
|
imgStore = &mocks.MockedImageStore{
|
|
|
|
GetIndexContentFn: func(repo string) ([]byte, error) {
|
|
|
|
return []byte(`{
|
|
|
|
"manifests": [{
|
|
|
|
"digest": "digest",
|
|
|
|
"mediaType": "application/vnd.oci.image.index.v1+json"
|
|
|
|
}]
|
|
|
|
}`), nil
|
|
|
|
},
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return []byte(`{
|
|
|
|
"subject": {"digest": "` + validDigest.String() + `"}
|
|
|
|
}`), nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
ref, err := common.GetReferrers(imgStore, "zot-test", validDigest,
|
2023-09-01 12:54:39 -05:00
|
|
|
[]string{"art.type"}, log)
|
2023-07-05 11:42:16 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(len(ref.Manifests), ShouldEqual, 0)
|
|
|
|
})
|
2022-11-15 01:21:49 -05:00
|
|
|
})
|
|
|
|
}
|
2022-11-24 14:00:22 -05:00
|
|
|
|
|
|
|
func TestGetImageIndexErrors(t *testing.T) {
|
2023-09-01 12:54:39 -05:00
|
|
|
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
2022-11-24 14:00:22 -05:00
|
|
|
|
|
|
|
Convey("Trigger invalid digest error", t, func(c C) {
|
|
|
|
imgStore := &mocks.MockedImageStore{}
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err := common.GetImageIndex(imgStore, "zot-test", "invalidDigest", log)
|
2022-11-24 14:00:22 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Trigger GetBlobContent error", t, func(c C) {
|
|
|
|
imgStore := &mocks.MockedImageStore{
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
2023-08-23 12:59:52 -05:00
|
|
|
return []byte{}, zerr.ErrBlobNotFound
|
2022-11-24 14:00:22 -05:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
validDigest := godigest.FromBytes([]byte("blob"))
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err := common.GetImageIndex(imgStore, "zot-test", validDigest, log)
|
2022-11-24 14:00:22 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Trigger unmarshal error", t, func(c C) {
|
|
|
|
imgStore := &mocks.MockedImageStore{
|
|
|
|
GetBlobContentFn: func(repo string, digest godigest.Digest) ([]byte, error) {
|
|
|
|
return []byte{}, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
validDigest := godigest.FromBytes([]byte("blob"))
|
|
|
|
|
2023-05-26 13:08:19 -05:00
|
|
|
_, err := common.GetImageIndex(imgStore, "zot-test", validDigest, log)
|
2022-11-24 14:00:22 -05:00
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
}
|
2023-05-10 12:15:33 -05:00
|
|
|
|
|
|
|
func TestIsSignature(t *testing.T) {
|
|
|
|
Convey("Unknown media type", t, func(c C) {
|
2023-05-26 13:08:19 -05:00
|
|
|
isSingature := common.IsSignature(ispec.Descriptor{
|
2023-05-10 12:15:33 -05:00
|
|
|
MediaType: "unknown media type",
|
|
|
|
})
|
|
|
|
So(isSingature, ShouldBeFalse)
|
|
|
|
})
|
|
|
|
}
|
2023-09-01 12:54:39 -05:00
|
|
|
|
|
|
|
func TestGarbageCollectManifestErrors(t *testing.T) {
|
|
|
|
Convey("Make imagestore and upload manifest", t, func(c C) {
|
|
|
|
dir := t.TempDir()
|
|
|
|
|
|
|
|
repoName := "test"
|
|
|
|
|
|
|
|
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
|
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
|
|
RootDir: dir,
|
|
|
|
Name: "cache",
|
|
|
|
UseRelPaths: true,
|
|
|
|
}, log)
|
|
|
|
imgStore := local.NewImageStore(dir, true, true, storageConstants.DefaultGCDelay,
|
|
|
|
storageConstants.DefaultUntaggedImgeRetentionDelay, true, true, log, metrics, nil, cacheDriver)
|
|
|
|
|
|
|
|
Convey("trigger repo not found in GetReferencedBlobs()", func() {
|
|
|
|
err := common.AddRepoBlobsToReferences(imgStore, repoName, map[string]bool{}, log)
|
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
content := []byte("this is a blob")
|
|
|
|
digest := godigest.FromBytes(content)
|
|
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
|
|
|
|
_, blen, err := imgStore.FullBlobUpload(repoName, bytes.NewReader(content), digest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(blen, ShouldEqual, len(content))
|
|
|
|
|
|
|
|
cblob, cdigest := test.GetRandomImageConfig()
|
|
|
|
_, clen, err := imgStore.FullBlobUpload(repoName, bytes.NewReader(cblob), cdigest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(clen, ShouldEqual, len(cblob))
|
|
|
|
|
|
|
|
manifest := ispec.Manifest{
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: ispec.MediaTypeImageConfig,
|
|
|
|
Digest: cdigest,
|
|
|
|
Size: int64(len(cblob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: ispec.MediaTypeImageLayer,
|
|
|
|
Digest: digest,
|
|
|
|
Size: int64(len(content)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
manifest.SchemaVersion = 2
|
|
|
|
|
|
|
|
body, err := json.Marshal(manifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
manifestDigest := godigest.FromBytes(body)
|
|
|
|
|
|
|
|
_, _, err = imgStore.PutImageManifest(repoName, "1.0", ispec.MediaTypeImageManifest, body)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
Convey("trigger GetIndex error in GetReferencedBlobs", func() {
|
|
|
|
err := os.Chmod(path.Join(imgStore.RootDir(), repoName), 0o000)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
err := os.Chmod(path.Join(imgStore.RootDir(), repoName), 0o755)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
}()
|
|
|
|
|
|
|
|
err = common.AddRepoBlobsToReferences(imgStore, repoName, map[string]bool{}, log)
|
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("trigger GetImageManifest error in GetReferencedBlobsInImageManifest", func() {
|
|
|
|
err := os.Chmod(path.Join(imgStore.RootDir(), repoName, "blobs", "sha256", manifestDigest.Encoded()), 0o000)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
err := os.Chmod(path.Join(imgStore.RootDir(), repoName, "blobs", "sha256", manifestDigest.Encoded()), 0o755)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
}()
|
|
|
|
|
|
|
|
err = common.AddRepoBlobsToReferences(imgStore, repoName, map[string]bool{}, log)
|
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGarbageCollectIndexErrors(t *testing.T) {
|
|
|
|
Convey("Make imagestore and upload manifest", t, func(c C) {
|
|
|
|
dir := t.TempDir()
|
|
|
|
|
|
|
|
repoName := "test"
|
|
|
|
|
|
|
|
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
|
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
|
|
RootDir: dir,
|
|
|
|
Name: "cache",
|
|
|
|
UseRelPaths: true,
|
|
|
|
}, log)
|
|
|
|
imgStore := local.NewImageStore(dir, true, true, storageConstants.DefaultGCDelay,
|
|
|
|
storageConstants.DefaultUntaggedImgeRetentionDelay, true, true, log, metrics, nil, cacheDriver)
|
|
|
|
|
|
|
|
content := []byte("this is a blob")
|
|
|
|
bdgst := godigest.FromBytes(content)
|
|
|
|
So(bdgst, ShouldNotBeNil)
|
|
|
|
|
|
|
|
_, bsize, err := imgStore.FullBlobUpload(repoName, bytes.NewReader(content), bdgst)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(bsize, ShouldEqual, len(content))
|
|
|
|
|
|
|
|
var index ispec.Index
|
|
|
|
index.SchemaVersion = 2
|
|
|
|
index.MediaType = ispec.MediaTypeImageIndex
|
|
|
|
|
|
|
|
var digest godigest.Digest
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
// upload image config blob
|
|
|
|
upload, err := imgStore.NewBlobUpload(repoName)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(upload, ShouldNotBeEmpty)
|
|
|
|
|
|
|
|
cblob, cdigest := test.GetRandomImageConfig()
|
|
|
|
buf := bytes.NewBuffer(cblob)
|
|
|
|
buflen := buf.Len()
|
|
|
|
blob, err := imgStore.PutBlobChunkStreamed(repoName, upload, buf)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(blob, ShouldEqual, buflen)
|
|
|
|
|
|
|
|
err = imgStore.FinishBlobUpload(repoName, upload, buf, cdigest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(blob, ShouldEqual, buflen)
|
|
|
|
|
|
|
|
// create a manifest
|
|
|
|
manifest := ispec.Manifest{
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: ispec.MediaTypeImageConfig,
|
|
|
|
Digest: cdigest,
|
|
|
|
Size: int64(len(cblob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: ispec.MediaTypeImageLayer,
|
|
|
|
Digest: bdgst,
|
|
|
|
Size: bsize,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
manifest.SchemaVersion = 2
|
|
|
|
content, err = json.Marshal(manifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
digest = godigest.FromBytes(content)
|
|
|
|
So(digest, ShouldNotBeNil)
|
|
|
|
_, _, err = imgStore.PutImageManifest(repoName, digest.String(), ispec.MediaTypeImageManifest, content)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
index.Manifests = append(index.Manifests, ispec.Descriptor{
|
|
|
|
Digest: digest,
|
|
|
|
MediaType: ispec.MediaTypeImageManifest,
|
|
|
|
Size: int64(len(content)),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// upload index image
|
|
|
|
indexContent, err := json.Marshal(index)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
indexDigest := godigest.FromBytes(indexContent)
|
|
|
|
So(indexDigest, ShouldNotBeNil)
|
|
|
|
|
|
|
|
_, _, err = imgStore.PutImageManifest(repoName, "1.0", ispec.MediaTypeImageIndex, indexContent)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
err = common.AddRepoBlobsToReferences(imgStore, repoName, map[string]bool{}, log)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
Convey("trigger GetImageIndex error in GetReferencedBlobsInImageIndex", func() {
|
|
|
|
err := os.Chmod(path.Join(imgStore.RootDir(), repoName, "blobs", "sha256", indexDigest.Encoded()), 0o000)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
err := os.Chmod(path.Join(imgStore.RootDir(), repoName, "blobs", "sha256", indexDigest.Encoded()), 0o755)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
}()
|
|
|
|
|
|
|
|
err = common.AddRepoBlobsToReferences(imgStore, repoName, map[string]bool{}, log)
|
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|