2023-01-09 15:37:44 -05:00
|
|
|
package convert_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
2023-01-23 12:45:11 -05:00
|
|
|
"strconv"
|
2023-01-09 15:37:44 -05:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/99designs/gqlgen/graphql"
|
|
|
|
godigest "github.com/opencontainers/go-digest"
|
2023-01-23 12:45:11 -05:00
|
|
|
"github.com/opencontainers/image-spec/specs-go"
|
2023-01-09 15:37:44 -05:00
|
|
|
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
|
|
2023-01-23 12:45:11 -05:00
|
|
|
"zotregistry.io/zot/pkg/api"
|
|
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
|
|
extconf "zotregistry.io/zot/pkg/extensions/config"
|
|
|
|
"zotregistry.io/zot/pkg/extensions/search/common"
|
2023-01-09 15:37:44 -05:00
|
|
|
"zotregistry.io/zot/pkg/extensions/search/convert"
|
|
|
|
cveinfo "zotregistry.io/zot/pkg/extensions/search/cve"
|
2023-02-27 14:23:18 -05:00
|
|
|
"zotregistry.io/zot/pkg/log"
|
2023-03-28 12:20:09 -05:00
|
|
|
"zotregistry.io/zot/pkg/meta/bolt"
|
2023-01-09 15:37:44 -05:00
|
|
|
"zotregistry.io/zot/pkg/meta/repodb"
|
2023-03-28 12:20:09 -05:00
|
|
|
boltdb_wrapper "zotregistry.io/zot/pkg/meta/repodb/boltdb-wrapper"
|
2023-01-23 12:45:11 -05:00
|
|
|
. "zotregistry.io/zot/pkg/test"
|
2023-01-09 15:37:44 -05:00
|
|
|
"zotregistry.io/zot/pkg/test/mocks"
|
|
|
|
)
|
|
|
|
|
|
|
|
var ErrTestError = errors.New("TestError")
|
|
|
|
|
|
|
|
func TestConvertErrors(t *testing.T) {
|
2023-02-27 14:23:18 -05:00
|
|
|
Convey("Convert Errors", t, func() {
|
2023-03-28 12:20:09 -05:00
|
|
|
params := bolt.DBParameters{
|
2023-01-09 15:37:44 -05:00
|
|
|
RootDir: t.TempDir(),
|
2023-03-28 12:20:09 -05:00
|
|
|
}
|
|
|
|
boltDB, err := bolt.GetBoltDriver(params)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
repoDB, err := boltdb_wrapper.NewBoltDBWrapper(boltDB, log.NewLogger("debug", ""))
|
2023-01-09 15:37:44 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
configBlob, err := json.Marshal(ispec.Image{})
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
manifestBlob, err := json.Marshal(ispec.Manifest{
|
|
|
|
Layers: []ispec.Descriptor{
|
|
|
|
{
|
|
|
|
MediaType: ispec.MediaTypeImageLayerGzip,
|
|
|
|
Size: 0,
|
|
|
|
Digest: godigest.NewDigestFromEncoded(godigest.SHA256, "digest"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
repoMeta11 := repodb.ManifestMetadata{
|
|
|
|
ManifestBlob: manifestBlob,
|
|
|
|
ConfigBlob: configBlob,
|
|
|
|
}
|
|
|
|
|
|
|
|
digest11 := godigest.FromString("abc1")
|
|
|
|
err = repoDB.SetManifestMeta("repo1", digest11, repoMeta11)
|
|
|
|
So(err, ShouldBeNil)
|
2023-03-09 13:41:48 -05:00
|
|
|
err = repoDB.SetRepoReference("repo1", "0.1.0", digest11, ispec.MediaTypeImageManifest)
|
2023-01-09 15:37:44 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
2023-02-27 14:23:18 -05:00
|
|
|
repoMetas, manifestMetaMap, _, _, err := repoDB.SearchRepos(context.Background(), "", repodb.Filter{},
|
2023-01-18 17:20:55 -05:00
|
|
|
repodb.PageInput{})
|
2023-01-09 15:37:44 -05:00
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
ctx := graphql.WithResponseContext(context.Background(),
|
|
|
|
graphql.DefaultErrorPresenter, graphql.DefaultRecover)
|
|
|
|
|
|
|
|
_ = convert.RepoMeta2RepoSummary(
|
|
|
|
ctx,
|
|
|
|
repoMetas[0],
|
|
|
|
manifestMetaMap,
|
2023-02-27 14:23:18 -05:00
|
|
|
map[string]repodb.IndexData{},
|
2023-01-09 15:37:44 -05:00
|
|
|
convert.SkipQGLField{},
|
|
|
|
mocks.CveInfoMock{
|
2023-02-27 14:23:18 -05:00
|
|
|
GetCVESummaryForImageFn: func(repo string, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
2023-01-09 15:37:44 -05:00
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
So(graphql.GetErrors(ctx).Error(), ShouldContainSubstring, "unable to run vulnerability scan on tag")
|
|
|
|
})
|
2023-02-27 14:23:18 -05:00
|
|
|
|
|
|
|
Convey("ImageIndex2ImageSummary errors", t, func() {
|
|
|
|
ctx := graphql.WithResponseContext(context.Background(),
|
|
|
|
graphql.DefaultErrorPresenter, graphql.DefaultRecover)
|
|
|
|
|
|
|
|
_, _, err := convert.ImageIndex2ImageSummary(
|
|
|
|
ctx,
|
|
|
|
"repo",
|
|
|
|
"tag",
|
|
|
|
godigest.FromString("indexDigest"),
|
|
|
|
true,
|
|
|
|
repodb.RepoMetadata{},
|
|
|
|
repodb.IndexData{
|
|
|
|
IndexBlob: []byte("bad json"),
|
|
|
|
},
|
|
|
|
map[string]repodb.ManifestMetadata{},
|
|
|
|
mocks.CveInfoMock{},
|
|
|
|
)
|
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("ImageIndex2ImageSummary cve scanning", t, func() {
|
|
|
|
ctx := graphql.WithResponseContext(context.Background(),
|
|
|
|
graphql.DefaultErrorPresenter, graphql.DefaultRecover)
|
|
|
|
|
|
|
|
_, _, err := convert.ImageIndex2ImageSummary(
|
|
|
|
ctx,
|
|
|
|
"repo",
|
|
|
|
"tag",
|
|
|
|
godigest.FromString("indexDigest"),
|
|
|
|
false,
|
|
|
|
repodb.RepoMetadata{},
|
|
|
|
repodb.IndexData{
|
|
|
|
IndexBlob: []byte("{}"),
|
|
|
|
},
|
|
|
|
map[string]repodb.ManifestMetadata{},
|
|
|
|
mocks.CveInfoMock{
|
|
|
|
GetCVESummaryForImageFn: func(repo, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("ImageManifest2ImageSummary", t, func() {
|
|
|
|
ctx := graphql.WithResponseContext(context.Background(),
|
|
|
|
graphql.DefaultErrorPresenter, graphql.DefaultRecover)
|
2023-03-21 12:16:00 -05:00
|
|
|
configBlob, err := json.Marshal(ispec.Image{
|
|
|
|
Platform: ispec.Platform{
|
|
|
|
OS: "os",
|
|
|
|
Architecture: "arch",
|
|
|
|
Variant: "var",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
So(err, ShouldBeNil)
|
2023-02-27 14:23:18 -05:00
|
|
|
|
2023-03-21 12:16:00 -05:00
|
|
|
_, _, err = convert.ImageManifest2ImageSummary(
|
2023-02-27 14:23:18 -05:00
|
|
|
ctx,
|
|
|
|
"repo",
|
|
|
|
"tag",
|
|
|
|
godigest.FromString("manifestDigest"),
|
|
|
|
false,
|
|
|
|
repodb.RepoMetadata{},
|
|
|
|
repodb.ManifestMetadata{
|
|
|
|
ManifestBlob: []byte("{}"),
|
2023-03-21 12:16:00 -05:00
|
|
|
ConfigBlob: configBlob,
|
2023-02-27 14:23:18 -05:00
|
|
|
},
|
|
|
|
mocks.CveInfoMock{
|
|
|
|
GetCVESummaryForImageFn: func(repo, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("ImageManifest2ManifestSummary", t, func() {
|
|
|
|
ctx := graphql.WithResponseContext(context.Background(),
|
|
|
|
graphql.DefaultErrorPresenter, graphql.DefaultRecover)
|
|
|
|
|
|
|
|
// with bad config json, error while unmarshaling
|
|
|
|
_, _, err := convert.ImageManifest2ManifestSummary(
|
|
|
|
ctx,
|
|
|
|
"repo",
|
|
|
|
"tag",
|
|
|
|
ispec.Descriptor{
|
|
|
|
Digest: "dig",
|
|
|
|
MediaType: ispec.MediaTypeImageManifest,
|
|
|
|
},
|
|
|
|
false,
|
2023-03-21 12:16:00 -05:00
|
|
|
repodb.RepoMetadata{
|
|
|
|
Tags: map[string]repodb.Descriptor{},
|
|
|
|
Statistics: map[string]repodb.DescriptorStatistics{},
|
|
|
|
Signatures: map[string]repodb.ManifestSignatures{},
|
|
|
|
Referrers: map[string][]repodb.ReferrerInfo{},
|
|
|
|
},
|
2023-02-27 14:23:18 -05:00
|
|
|
repodb.ManifestMetadata{
|
|
|
|
ManifestBlob: []byte("{}"),
|
|
|
|
ConfigBlob: []byte("bad json"),
|
|
|
|
},
|
2023-03-20 11:14:17 -05:00
|
|
|
nil,
|
2023-02-27 14:23:18 -05:00
|
|
|
mocks.CveInfoMock{
|
|
|
|
GetCVESummaryForImageFn: func(repo, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
So(err, ShouldNotBeNil)
|
|
|
|
|
|
|
|
// CVE scan using platform
|
|
|
|
configBlob, err := json.Marshal(ispec.Image{
|
|
|
|
Platform: ispec.Platform{
|
|
|
|
OS: "os",
|
|
|
|
Architecture: "arch",
|
2023-03-21 12:16:00 -05:00
|
|
|
Variant: "var",
|
2023-02-27 14:23:18 -05:00
|
|
|
},
|
|
|
|
})
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
_, _, err = convert.ImageManifest2ManifestSummary(
|
|
|
|
ctx,
|
|
|
|
"repo",
|
|
|
|
"tag",
|
|
|
|
ispec.Descriptor{
|
|
|
|
Digest: "dig",
|
|
|
|
MediaType: ispec.MediaTypeImageManifest,
|
|
|
|
},
|
|
|
|
false,
|
2023-03-21 12:16:00 -05:00
|
|
|
repodb.RepoMetadata{
|
|
|
|
Tags: map[string]repodb.Descriptor{},
|
|
|
|
Statistics: map[string]repodb.DescriptorStatistics{},
|
|
|
|
Signatures: map[string]repodb.ManifestSignatures{"dig": {"cosine": []repodb.SignatureInfo{{}}}},
|
|
|
|
Referrers: map[string][]repodb.ReferrerInfo{},
|
|
|
|
},
|
2023-02-27 14:23:18 -05:00
|
|
|
repodb.ManifestMetadata{
|
|
|
|
ManifestBlob: []byte("{}"),
|
|
|
|
ConfigBlob: configBlob,
|
|
|
|
},
|
2023-03-20 11:14:17 -05:00
|
|
|
nil,
|
2023-02-27 14:23:18 -05:00
|
|
|
mocks.CveInfoMock{
|
|
|
|
GetCVESummaryForImageFn: func(repo, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("RepoMeta2ExpandedRepoInfo", t, func() {
|
|
|
|
ctx := graphql.WithResponseContext(context.Background(),
|
|
|
|
graphql.DefaultErrorPresenter, graphql.DefaultRecover)
|
|
|
|
|
|
|
|
// with bad config json, error while unmarshaling
|
|
|
|
_, imageSummaries := convert.RepoMeta2ExpandedRepoInfo(
|
|
|
|
ctx,
|
|
|
|
repodb.RepoMetadata{
|
|
|
|
Tags: map[string]repodb.Descriptor{
|
|
|
|
"tag1": {Digest: "dig", MediaType: ispec.MediaTypeImageManifest},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
map[string]repodb.ManifestMetadata{
|
|
|
|
"dig": {
|
|
|
|
ManifestBlob: []byte("{}"),
|
|
|
|
ConfigBlob: []byte("bad json"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
map[string]repodb.IndexData{},
|
|
|
|
convert.SkipQGLField{
|
|
|
|
Vulnerabilities: false,
|
|
|
|
},
|
|
|
|
mocks.CveInfoMock{
|
|
|
|
GetCVESummaryForImageFn: func(repo, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
}, log.NewLogger("debug", ""),
|
|
|
|
)
|
|
|
|
So(len(imageSummaries), ShouldEqual, 0)
|
2023-03-21 12:16:00 -05:00
|
|
|
|
|
|
|
// cveInfo present no error
|
|
|
|
_, imageSummaries = convert.RepoMeta2ExpandedRepoInfo(
|
|
|
|
ctx,
|
|
|
|
repodb.RepoMetadata{
|
|
|
|
Tags: map[string]repodb.Descriptor{
|
|
|
|
"tag1": {Digest: "dig", MediaType: ispec.MediaTypeImageManifest},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
map[string]repodb.ManifestMetadata{
|
|
|
|
"dig": {
|
|
|
|
ManifestBlob: []byte("{}"),
|
|
|
|
ConfigBlob: []byte("{}"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
map[string]repodb.IndexData{},
|
|
|
|
convert.SkipQGLField{
|
|
|
|
Vulnerabilities: false,
|
|
|
|
},
|
|
|
|
mocks.CveInfoMock{
|
|
|
|
GetCVESummaryForImageFn: func(repo, reference string,
|
|
|
|
) (cveinfo.ImageCVESummary, error) {
|
|
|
|
return cveinfo.ImageCVESummary{}, ErrTestError
|
|
|
|
},
|
|
|
|
}, log.NewLogger("debug", ""),
|
|
|
|
)
|
|
|
|
So(len(imageSummaries), ShouldEqual, 1)
|
2023-02-27 14:23:18 -05:00
|
|
|
})
|
2023-01-09 15:37:44 -05:00
|
|
|
}
|
2023-01-23 12:45:11 -05:00
|
|
|
|
|
|
|
func TestBuildImageInfo(t *testing.T) {
|
|
|
|
rootDir := t.TempDir()
|
|
|
|
|
|
|
|
port := GetFreePort()
|
|
|
|
baseURL := GetBaseURL(port)
|
|
|
|
|
|
|
|
conf := config.New()
|
|
|
|
conf.HTTP.Port = port
|
|
|
|
conf.Storage.RootDirectory = rootDir
|
|
|
|
defaultVal := true
|
|
|
|
conf.Extensions = &extconf.ExtensionConfig{
|
|
|
|
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
|
|
|
}
|
|
|
|
|
|
|
|
conf.Extensions.Search.CVE = nil
|
|
|
|
|
|
|
|
ctlr := api.NewController(conf)
|
|
|
|
ctlrManager := NewControllerManager(ctlr)
|
|
|
|
|
|
|
|
ctlrManager.StartAndWait(port)
|
|
|
|
defer ctlrManager.StopServer()
|
|
|
|
|
|
|
|
olu := &common.BaseOciLayoutUtils{
|
|
|
|
StoreController: ctlr.StoreController,
|
|
|
|
Log: ctlr.Log,
|
|
|
|
}
|
|
|
|
|
|
|
|
Convey("Check image summary when the image has no history", t, func() {
|
|
|
|
imageName := "nohistory"
|
|
|
|
|
|
|
|
config := ispec.Image{
|
|
|
|
Platform: ispec.Platform{
|
|
|
|
OS: "linux",
|
|
|
|
Architecture: "amd64",
|
|
|
|
},
|
|
|
|
RootFS: ispec.RootFS{
|
|
|
|
Type: "layers",
|
|
|
|
DiffIDs: []godigest.Digest{},
|
|
|
|
},
|
|
|
|
Author: "ZotUser",
|
|
|
|
}
|
|
|
|
|
|
|
|
configBlob, err := json.Marshal(config)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
configDigest := godigest.FromBytes(configBlob)
|
|
|
|
layerDigest := godigest.FromString(imageName)
|
|
|
|
layerblob := []byte(imageName)
|
|
|
|
schemaVersion := 2
|
|
|
|
ispecManifest := ispec.Manifest{
|
|
|
|
Versioned: specs.Versioned{
|
|
|
|
SchemaVersion: schemaVersion,
|
|
|
|
},
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: "application/vnd.oci.image.config.v1+json",
|
|
|
|
Digest: configDigest,
|
|
|
|
Size: int64(len(configBlob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{ // just 1 layer in manifest
|
|
|
|
{
|
|
|
|
MediaType: "application/vnd.oci.image.layer.v1.tar",
|
|
|
|
Digest: layerDigest,
|
|
|
|
Size: int64(len(layerblob)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
manifestLayersSize := ispecManifest.Layers[0].Size
|
|
|
|
manifestBlob, err := json.Marshal(ispecManifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := godigest.FromBytes(manifestBlob)
|
|
|
|
err = UploadImage(
|
|
|
|
Image{
|
|
|
|
Manifest: ispecManifest,
|
|
|
|
Config: config,
|
|
|
|
Layers: [][]byte{
|
|
|
|
layerblob,
|
|
|
|
},
|
2023-02-27 14:23:18 -05:00
|
|
|
Reference: "0.0.1",
|
2023-01-23 12:45:11 -05:00
|
|
|
},
|
|
|
|
baseURL,
|
|
|
|
imageName,
|
|
|
|
)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
imageConfig, err := olu.GetImageConfigInfo(imageName, manifestDigest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
isSigned := false
|
|
|
|
|
|
|
|
imageSummary := convert.BuildImageInfo(imageName, imageName, manifestDigest, ispecManifest,
|
|
|
|
imageConfig, isSigned)
|
|
|
|
|
2023-02-27 14:23:18 -05:00
|
|
|
So(len(imageSummary.Manifests[0].Layers), ShouldEqual, len(ispecManifest.Layers))
|
2023-01-23 12:45:11 -05:00
|
|
|
imageSummaryLayerSize, err := strconv.Atoi(*imageSummary.Size)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(imageSummaryLayerSize, ShouldEqual, manifestLayersSize)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Check image summary when layer count matche history entries", t, func() {
|
|
|
|
imageName := "valid"
|
|
|
|
|
|
|
|
config := ispec.Image{
|
|
|
|
Platform: ispec.Platform{
|
|
|
|
OS: "linux",
|
|
|
|
Architecture: "amd64",
|
|
|
|
},
|
|
|
|
RootFS: ispec.RootFS{
|
|
|
|
Type: "layers",
|
|
|
|
DiffIDs: []godigest.Digest{},
|
|
|
|
},
|
|
|
|
Author: "ZotUser",
|
|
|
|
History: []ispec.History{ // should contain 3 elements, 2 of which corresponding to layers
|
|
|
|
{
|
|
|
|
EmptyLayer: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EmptyLayer: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EmptyLayer: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
configBlob, err := json.Marshal(config)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
configDigest := godigest.FromBytes(configBlob)
|
|
|
|
layerDigest := godigest.FromString("layer1")
|
|
|
|
layerblob := []byte("layer1")
|
|
|
|
layerDigest2 := godigest.FromString("layer2")
|
|
|
|
layerblob2 := []byte("layer2")
|
|
|
|
schemaVersion := 2
|
|
|
|
ispecManifest := ispec.Manifest{
|
|
|
|
Versioned: specs.Versioned{
|
|
|
|
SchemaVersion: schemaVersion,
|
|
|
|
},
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: "application/vnd.oci.image.config.v1+json",
|
|
|
|
Digest: configDigest,
|
|
|
|
Size: int64(len(configBlob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{ // just 1 layer in manifest
|
|
|
|
{
|
|
|
|
MediaType: "application/vnd.oci.image.layer.v1.tar",
|
|
|
|
Digest: layerDigest,
|
|
|
|
Size: int64(len(layerblob)),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MediaType: "application/vnd.oci.image.layer.v1.tar",
|
|
|
|
Digest: layerDigest2,
|
|
|
|
Size: int64(len(layerblob2)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
manifestLayersSize := ispecManifest.Layers[0].Size + ispecManifest.Layers[1].Size
|
|
|
|
manifestBlob, err := json.Marshal(ispecManifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := godigest.FromBytes(manifestBlob)
|
|
|
|
err = UploadImage(
|
|
|
|
Image{
|
|
|
|
Manifest: ispecManifest,
|
|
|
|
Config: config,
|
|
|
|
Layers: [][]byte{
|
|
|
|
layerblob,
|
|
|
|
layerblob2,
|
|
|
|
},
|
2023-02-27 14:23:18 -05:00
|
|
|
Reference: "0.0.1",
|
2023-01-23 12:45:11 -05:00
|
|
|
},
|
|
|
|
baseURL,
|
|
|
|
imageName,
|
|
|
|
)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
imageConfig, err := olu.GetImageConfigInfo(imageName, manifestDigest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
isSigned := false
|
|
|
|
|
|
|
|
imageSummary := convert.BuildImageInfo(imageName, imageName, manifestDigest, ispecManifest,
|
|
|
|
imageConfig, isSigned)
|
|
|
|
|
2023-02-27 14:23:18 -05:00
|
|
|
So(len(imageSummary.Manifests[0].Layers), ShouldEqual, len(ispecManifest.Layers))
|
2023-01-23 12:45:11 -05:00
|
|
|
imageSummaryLayerSize, err := strconv.Atoi(*imageSummary.Size)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(imageSummaryLayerSize, ShouldEqual, manifestLayersSize)
|
|
|
|
})
|
|
|
|
|
|
|
|
Convey("Check image summary when layer count does not match history", t, func() {
|
|
|
|
imageName := "invalid"
|
|
|
|
|
|
|
|
config := ispec.Image{
|
|
|
|
Platform: ispec.Platform{
|
|
|
|
OS: "linux",
|
|
|
|
Architecture: "amd64",
|
|
|
|
},
|
|
|
|
RootFS: ispec.RootFS{
|
|
|
|
Type: "layers",
|
|
|
|
DiffIDs: []godigest.Digest{},
|
|
|
|
},
|
|
|
|
Author: "ZotUser",
|
|
|
|
History: []ispec.History{ // should contain 3 elements, 2 of which corresponding to layers
|
|
|
|
{
|
|
|
|
EmptyLayer: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EmptyLayer: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EmptyLayer: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
configBlob, err := json.Marshal(config)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
configDigest := godigest.FromBytes(configBlob)
|
|
|
|
layerDigest := godigest.FromString(imageName)
|
|
|
|
layerblob := []byte(imageName)
|
|
|
|
schemaVersion := 2
|
|
|
|
ispecManifest := ispec.Manifest{
|
|
|
|
Versioned: specs.Versioned{
|
|
|
|
SchemaVersion: schemaVersion,
|
|
|
|
},
|
|
|
|
Config: ispec.Descriptor{
|
|
|
|
MediaType: "application/vnd.oci.image.config.v1+json",
|
|
|
|
Digest: configDigest,
|
|
|
|
Size: int64(len(configBlob)),
|
|
|
|
},
|
|
|
|
Layers: []ispec.Descriptor{ // just 1 layer in manifest
|
|
|
|
{
|
|
|
|
MediaType: "application/vnd.oci.image.layer.v1.tar",
|
|
|
|
Digest: layerDigest,
|
|
|
|
Size: int64(len(layerblob)),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
manifestLayersSize := ispecManifest.Layers[0].Size
|
|
|
|
manifestBlob, err := json.Marshal(ispecManifest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := godigest.FromBytes(manifestBlob)
|
|
|
|
err = UploadImage(
|
|
|
|
Image{
|
|
|
|
Manifest: ispecManifest,
|
|
|
|
Config: config,
|
|
|
|
Layers: [][]byte{
|
|
|
|
layerblob,
|
|
|
|
},
|
2023-02-27 14:23:18 -05:00
|
|
|
Reference: "0.0.1",
|
2023-01-23 12:45:11 -05:00
|
|
|
},
|
|
|
|
baseURL,
|
|
|
|
imageName,
|
|
|
|
)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
imageConfig, err := olu.GetImageConfigInfo(imageName, manifestDigest)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
|
|
|
|
isSigned := false
|
|
|
|
|
|
|
|
imageSummary := convert.BuildImageInfo(imageName, imageName, manifestDigest, ispecManifest,
|
|
|
|
imageConfig, isSigned)
|
|
|
|
|
2023-02-27 14:23:18 -05:00
|
|
|
So(len(imageSummary.Manifests[0].Layers), ShouldEqual, len(ispecManifest.Layers))
|
2023-01-23 12:45:11 -05:00
|
|
|
imageSummaryLayerSize, err := strconv.Atoi(*imageSummary.Size)
|
|
|
|
So(err, ShouldBeNil)
|
|
|
|
So(imageSummaryLayerSize, ShouldEqual, manifestLayersSize)
|
|
|
|
})
|
|
|
|
}
|