mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
feat(graphql): add an api to return referrers (#1009)
UI can now make use of OCI artifacts and references using `Referrers` gQL query. It returns a list of descriptors that refer on their `subject` field to another digest. Signed-off-by: Alex Stan <alexandrustan96@yahoo.ro>
This commit is contained in:
parent
8746a49268
commit
f75bce3085
10 changed files with 1148 additions and 0 deletions
|
@ -76,6 +76,14 @@ type ExpandedRepoInfoResp struct {
|
||||||
Errors []ErrorGQL `json:"errors"`
|
Errors []ErrorGQL `json:"errors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReferrersResp struct {
|
||||||
|
ReferrersResult ReferrersResult `json:"data"`
|
||||||
|
Errors []ErrorGQL `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReferrersResult struct {
|
||||||
|
Referrers []common.Referrer `json:"referrers"`
|
||||||
|
}
|
||||||
type GlobalSearchResultResp struct {
|
type GlobalSearchResultResp struct {
|
||||||
GlobalSearchResult GlobalSearchResult `json:"data"`
|
GlobalSearchResult GlobalSearchResult `json:"data"`
|
||||||
Errors []ErrorGQL `json:"errors"`
|
Errors []ErrorGQL `json:"errors"`
|
||||||
|
@ -658,6 +666,138 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetReferrersGQL(t *testing.T) {
|
||||||
|
Convey("get referrers", t, func() {
|
||||||
|
port := GetFreePort()
|
||||||
|
baseURL := GetBaseURL(port)
|
||||||
|
conf := config.New()
|
||||||
|
conf.HTTP.Port = port
|
||||||
|
conf.Storage.RootDirectory = t.TempDir()
|
||||||
|
|
||||||
|
defaultVal := true
|
||||||
|
conf.Extensions = &extconf.ExtensionConfig{
|
||||||
|
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||||
|
Lint: &extconf.LintConfig{
|
||||||
|
BaseConfig: extconf.BaseConfig{
|
||||||
|
Enable: &defaultVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
gqlEndpoint := fmt.Sprintf("%s%s?query=", baseURL, graphqlQueryPrefix)
|
||||||
|
|
||||||
|
conf.Extensions.Search.CVE = nil
|
||||||
|
|
||||||
|
ctlr := api.NewController(conf)
|
||||||
|
|
||||||
|
go startServer(ctlr)
|
||||||
|
defer stopServer(ctlr)
|
||||||
|
|
||||||
|
WaitTillServerReady(baseURL)
|
||||||
|
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
config, layers, manifest, err := GetImageComponents(1000)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
repo := "artifact-ref"
|
||||||
|
|
||||||
|
err = UploadImage(
|
||||||
|
Image{
|
||||||
|
Manifest: manifest,
|
||||||
|
Config: config,
|
||||||
|
Layers: layers,
|
||||||
|
Tag: "1.0",
|
||||||
|
},
|
||||||
|
baseURL,
|
||||||
|
repo)
|
||||||
|
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
manifestBlob, err := json.Marshal(manifest)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
manifestDigest := godigest.FromBytes(manifestBlob)
|
||||||
|
manifestSize := int64(len(manifestBlob))
|
||||||
|
|
||||||
|
subjectDescriptor := &ispec.Descriptor{
|
||||||
|
MediaType: "application/vnd.oci.image.manifest.v1+json",
|
||||||
|
Size: manifestSize,
|
||||||
|
Digest: manifestDigest,
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactContentBlob := []byte("test artifact")
|
||||||
|
artifactContentBlobSize := int64(len(artifactContentBlob))
|
||||||
|
artifactContentType := "application/octet-stream"
|
||||||
|
artifactContentBlobDigest := godigest.FromBytes(artifactContentBlob)
|
||||||
|
artifactType := "com.artifact.test"
|
||||||
|
|
||||||
|
err = UploadBlob(baseURL, repo, artifactContentBlob, artifactContentType)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
artifact := &ispec.Artifact{
|
||||||
|
Blobs: []ispec.Descriptor{
|
||||||
|
{
|
||||||
|
MediaType: artifactContentType,
|
||||||
|
Digest: artifactContentBlobDigest,
|
||||||
|
Size: artifactContentBlobSize,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subject: subjectDescriptor,
|
||||||
|
ArtifactType: artifactType,
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"com.artifact.format": "test",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactManifestBlob, err := json.Marshal(artifact)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
artifactManifestDigest := godigest.FromBytes(artifactManifestBlob)
|
||||||
|
|
||||||
|
err = UploadArtifact(baseURL, repo, artifact)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
gqlQuery := `
|
||||||
|
{Referrers(
|
||||||
|
repo: "%s",
|
||||||
|
digest: "%s",
|
||||||
|
type: ""
|
||||||
|
){
|
||||||
|
ArtifactType,
|
||||||
|
Digest,
|
||||||
|
MediaType,
|
||||||
|
Size,
|
||||||
|
Annotations{
|
||||||
|
Key
|
||||||
|
Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
strQuery := fmt.Sprintf(gqlQuery, repo, manifestDigest.String())
|
||||||
|
|
||||||
|
targetURL := fmt.Sprintf("%s%s", gqlEndpoint, url.QueryEscape(strQuery))
|
||||||
|
|
||||||
|
resp, err := resty.R().Get(targetURL)
|
||||||
|
So(resp, ShouldNotBeNil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(resp.StatusCode(), ShouldEqual, 200)
|
||||||
|
So(resp.Body(), ShouldNotBeNil)
|
||||||
|
|
||||||
|
refferrsResp := &ReferrersResp{}
|
||||||
|
|
||||||
|
err = json.Unmarshal(resp.Body(), refferrsResp)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(refferrsResp.Errors, ShouldBeNil)
|
||||||
|
So(refferrsResp.ReferrersResult.Referrers[0].ArtifactType, ShouldEqual, artifactType)
|
||||||
|
So(refferrsResp.ReferrersResult.Referrers[0].MediaType, ShouldEqual, ispec.MediaTypeArtifactManifest)
|
||||||
|
|
||||||
|
So(refferrsResp.ReferrersResult.Referrers[0].Annotations[0].Key, ShouldEqual, "com.artifact.format")
|
||||||
|
So(refferrsResp.ReferrersResult.Referrers[0].Annotations[0].Value, ShouldEqual, "test")
|
||||||
|
|
||||||
|
So(refferrsResp.ReferrersResult.Referrers[0].Digest, ShouldEqual, artifactManifestDigest)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestExpandedRepoInfo(t *testing.T) {
|
func TestExpandedRepoInfo(t *testing.T) {
|
||||||
Convey("Filter out manifests with no tag", t, func() {
|
Convey("Filter out manifests with no tag", t, func() {
|
||||||
tagToBeRemoved := "3.0"
|
tagToBeRemoved := "3.0"
|
||||||
|
|
|
@ -71,3 +71,16 @@ type HistoryDescription struct {
|
||||||
Comment string `json:"comment"`
|
Comment string `json:"comment"`
|
||||||
EmptyLayer bool `json:"emptyLayer"`
|
EmptyLayer bool `json:"emptyLayer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Referrer struct {
|
||||||
|
MediaType string `json:"mediatype"`
|
||||||
|
ArtifactType string `json:"artifacttype"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Digest string `json:"digest"`
|
||||||
|
Annotations []Annotation `json:"annotations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Annotation struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,11 @@ type DirectiveRoot struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ComplexityRoot struct {
|
type ComplexityRoot struct {
|
||||||
|
Annotation struct {
|
||||||
|
Key func(childComplexity int) int
|
||||||
|
Value func(childComplexity int) int
|
||||||
|
}
|
||||||
|
|
||||||
CVE struct {
|
CVE struct {
|
||||||
Description func(childComplexity int) int
|
Description func(childComplexity int) int
|
||||||
ID func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
|
@ -132,9 +137,18 @@ type ComplexityRoot struct {
|
||||||
ImageListForCve func(childComplexity int, id string) int
|
ImageListForCve func(childComplexity int, id string) int
|
||||||
ImageListForDigest func(childComplexity int, id string) int
|
ImageListForDigest func(childComplexity int, id string) int
|
||||||
ImageListWithCVEFixed func(childComplexity int, id string, image string) int
|
ImageListWithCVEFixed func(childComplexity int, id string, image string) int
|
||||||
|
Referrers func(childComplexity int, repo string, digest string, typeArg string) int
|
||||||
RepoListWithNewestImage func(childComplexity int) int
|
RepoListWithNewestImage func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Referrer struct {
|
||||||
|
Annotations func(childComplexity int) int
|
||||||
|
ArtifactType func(childComplexity int) int
|
||||||
|
Digest func(childComplexity int) int
|
||||||
|
MediaType func(childComplexity int) int
|
||||||
|
Size func(childComplexity int) int
|
||||||
|
}
|
||||||
|
|
||||||
RepoInfo struct {
|
RepoInfo struct {
|
||||||
Images func(childComplexity int) int
|
Images func(childComplexity int) int
|
||||||
Summary func(childComplexity int) int
|
Summary func(childComplexity int) int
|
||||||
|
@ -166,6 +180,7 @@ type QueryResolver interface {
|
||||||
DerivedImageList(ctx context.Context, image string) ([]*ImageSummary, error)
|
DerivedImageList(ctx context.Context, image string) ([]*ImageSummary, error)
|
||||||
BaseImageList(ctx context.Context, image string) ([]*ImageSummary, error)
|
BaseImageList(ctx context.Context, image string) ([]*ImageSummary, error)
|
||||||
Image(ctx context.Context, image string) (*ImageSummary, error)
|
Image(ctx context.Context, image string) (*ImageSummary, error)
|
||||||
|
Referrers(ctx context.Context, repo string, digest string, typeArg string) ([]*Referrer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type executableSchema struct {
|
type executableSchema struct {
|
||||||
|
@ -183,6 +198,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
_ = ec
|
_ = ec
|
||||||
switch typeName + "." + field {
|
switch typeName + "." + field {
|
||||||
|
|
||||||
|
case "Annotation.Key":
|
||||||
|
if e.complexity.Annotation.Key == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Annotation.Key(childComplexity), true
|
||||||
|
|
||||||
|
case "Annotation.Value":
|
||||||
|
if e.complexity.Annotation.Value == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Annotation.Value(childComplexity), true
|
||||||
|
|
||||||
case "CVE.Description":
|
case "CVE.Description":
|
||||||
if e.complexity.CVE.Description == nil {
|
if e.complexity.CVE.Description == nil {
|
||||||
break
|
break
|
||||||
|
@ -639,6 +668,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Query.ImageListWithCVEFixed(childComplexity, args["id"].(string), args["image"].(string)), true
|
return e.complexity.Query.ImageListWithCVEFixed(childComplexity, args["id"].(string), args["image"].(string)), true
|
||||||
|
|
||||||
|
case "Query.Referrers":
|
||||||
|
if e.complexity.Query.Referrers == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Query_Referrers_args(context.TODO(), rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Query.Referrers(childComplexity, args["repo"].(string), args["digest"].(string), args["type"].(string)), true
|
||||||
|
|
||||||
case "Query.RepoListWithNewestImage":
|
case "Query.RepoListWithNewestImage":
|
||||||
if e.complexity.Query.RepoListWithNewestImage == nil {
|
if e.complexity.Query.RepoListWithNewestImage == nil {
|
||||||
break
|
break
|
||||||
|
@ -646,6 +687,41 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Query.RepoListWithNewestImage(childComplexity), true
|
return e.complexity.Query.RepoListWithNewestImage(childComplexity), true
|
||||||
|
|
||||||
|
case "Referrer.Annotations":
|
||||||
|
if e.complexity.Referrer.Annotations == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Referrer.Annotations(childComplexity), true
|
||||||
|
|
||||||
|
case "Referrer.ArtifactType":
|
||||||
|
if e.complexity.Referrer.ArtifactType == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Referrer.ArtifactType(childComplexity), true
|
||||||
|
|
||||||
|
case "Referrer.Digest":
|
||||||
|
if e.complexity.Referrer.Digest == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Referrer.Digest(childComplexity), true
|
||||||
|
|
||||||
|
case "Referrer.MediaType":
|
||||||
|
if e.complexity.Referrer.MediaType == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Referrer.MediaType(childComplexity), true
|
||||||
|
|
||||||
|
case "Referrer.Size":
|
||||||
|
if e.complexity.Referrer.Size == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Referrer.Size(childComplexity), true
|
||||||
|
|
||||||
case "RepoInfo.Images":
|
case "RepoInfo.Images":
|
||||||
if e.complexity.RepoInfo.Images == nil {
|
if e.complexity.RepoInfo.Images == nil {
|
||||||
break
|
break
|
||||||
|
@ -918,6 +994,19 @@ type LayerHistory {
|
||||||
HistoryDescription: HistoryDescription
|
HistoryDescription: HistoryDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Annotation {
|
||||||
|
Key: String
|
||||||
|
Value: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Referrer {
|
||||||
|
MediaType: String
|
||||||
|
ArtifactType: String
|
||||||
|
Size: Int
|
||||||
|
Digest: String
|
||||||
|
Annotations: [Annotation]!
|
||||||
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Contains details about the supported OS and architecture of the image
|
Contains details about the supported OS and architecture of the image
|
||||||
"""
|
"""
|
||||||
|
@ -981,6 +1070,12 @@ type Query {
|
||||||
Search for a specific image using its name
|
Search for a specific image using its name
|
||||||
"""
|
"""
|
||||||
Image(image: String!): ImageSummary
|
Image(image: String!): ImageSummary
|
||||||
|
|
||||||
|
"""
|
||||||
|
Returns a list of descriptors of an image or artifact manifest that are found in a <repo> and have a subject field of <digest>
|
||||||
|
Can be filtered based on a specific artifact type <type>
|
||||||
|
"""
|
||||||
|
Referrers(repo: String!, digest: String!, type: String!): [Referrer]!
|
||||||
}
|
}
|
||||||
`, BuiltIn: false},
|
`, BuiltIn: false},
|
||||||
}
|
}
|
||||||
|
@ -1149,6 +1244,39 @@ func (ec *executionContext) field_Query_Image_args(ctx context.Context, rawArgs
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Query_Referrers_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]interface{}{}
|
||||||
|
var arg0 string
|
||||||
|
if tmp, ok := rawArgs["repo"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("repo"))
|
||||||
|
arg0, err = ec.unmarshalNString2string(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["repo"] = arg0
|
||||||
|
var arg1 string
|
||||||
|
if tmp, ok := rawArgs["digest"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("digest"))
|
||||||
|
arg1, err = ec.unmarshalNString2string(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["digest"] = arg1
|
||||||
|
var arg2 string
|
||||||
|
if tmp, ok := rawArgs["type"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("type"))
|
||||||
|
arg2, err = ec.unmarshalNString2string(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["type"] = arg2
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
|
@ -1202,6 +1330,88 @@ func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArg
|
||||||
|
|
||||||
// region **************************** field.gotpl *****************************
|
// region **************************** field.gotpl *****************************
|
||||||
|
|
||||||
|
func (ec *executionContext) _Annotation_Key(ctx context.Context, field graphql.CollectedField, obj *Annotation) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Annotation_Key(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Key, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Annotation_Key(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Annotation",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Annotation_Value(ctx context.Context, field graphql.CollectedField, obj *Annotation) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Annotation_Value(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Value, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Annotation_Value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Annotation",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _CVE_Id(ctx context.Context, field graphql.CollectedField, obj *Cve) (ret graphql.Marshaler) {
|
func (ec *executionContext) _CVE_Id(ctx context.Context, field graphql.CollectedField, obj *Cve) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_CVE_Id(ctx, field)
|
fc, err := ec.fieldContext_CVE_Id(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4233,6 +4443,73 @@ func (ec *executionContext) fieldContext_Query_Image(ctx context.Context, field
|
||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Query_Referrers(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Query_Referrers(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return ec.resolvers.Query().Referrers(rctx, fc.Args["repo"].(string), fc.Args["digest"].(string), fc.Args["type"].(string))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*Referrer)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNReferrer2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐReferrer(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Query_Referrers(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Query",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
switch field.Name {
|
||||||
|
case "MediaType":
|
||||||
|
return ec.fieldContext_Referrer_MediaType(ctx, field)
|
||||||
|
case "ArtifactType":
|
||||||
|
return ec.fieldContext_Referrer_ArtifactType(ctx, field)
|
||||||
|
case "Size":
|
||||||
|
return ec.fieldContext_Referrer_Size(ctx, field)
|
||||||
|
case "Digest":
|
||||||
|
return ec.fieldContext_Referrer_Digest(ctx, field)
|
||||||
|
case "Annotations":
|
||||||
|
return ec.fieldContext_Referrer_Annotations(ctx, field)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no field named %q was found under type Referrer", field.Name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = ec.Recover(ctx, r)
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
if fc.Args, err = ec.field_Query_Referrers_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Query___type(ctx, field)
|
fc, err := ec.fieldContext_Query___type(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4362,6 +4639,220 @@ func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, fie
|
||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Referrer_MediaType(ctx context.Context, field graphql.CollectedField, obj *Referrer) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Referrer_MediaType(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.MediaType, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Referrer_MediaType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Referrer",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Referrer_ArtifactType(ctx context.Context, field graphql.CollectedField, obj *Referrer) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Referrer_ArtifactType(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.ArtifactType, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Referrer_ArtifactType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Referrer",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Referrer_Size(ctx context.Context, field graphql.CollectedField, obj *Referrer) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Referrer_Size(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Size, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*int)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Referrer_Size(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Referrer",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Int does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Referrer_Digest(ctx context.Context, field graphql.CollectedField, obj *Referrer) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Referrer_Digest(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Digest, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Referrer_Digest(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Referrer",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Referrer_Annotations(ctx context.Context, field graphql.CollectedField, obj *Referrer) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Referrer_Annotations(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Annotations, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*Annotation)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNAnnotation2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐAnnotation(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Referrer_Annotations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Referrer",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
switch field.Name {
|
||||||
|
case "Key":
|
||||||
|
return ec.fieldContext_Annotation_Key(ctx, field)
|
||||||
|
case "Value":
|
||||||
|
return ec.fieldContext_Annotation_Value(ctx, field)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no field named %q was found under type Annotation", field.Name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _RepoInfo_Images(ctx context.Context, field graphql.CollectedField, obj *RepoInfo) (ret graphql.Marshaler) {
|
func (ec *executionContext) _RepoInfo_Images(ctx context.Context, field graphql.CollectedField, obj *RepoInfo) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_RepoInfo_Images(ctx, field)
|
fc, err := ec.fieldContext_RepoInfo_Images(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -6751,6 +7242,35 @@ func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Conte
|
||||||
|
|
||||||
// region **************************** object.gotpl ****************************
|
// region **************************** object.gotpl ****************************
|
||||||
|
|
||||||
|
var annotationImplementors = []string{"Annotation"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Annotation(ctx context.Context, sel ast.SelectionSet, obj *Annotation) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.OperationContext, sel, annotationImplementors)
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
var invalids uint32
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("Annotation")
|
||||||
|
case "Key":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Annotation_Key(ctx, field, obj)
|
||||||
|
|
||||||
|
case "Value":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Annotation_Value(ctx, field, obj)
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch()
|
||||||
|
if invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
var cVEImplementors = []string{"CVE"}
|
var cVEImplementors = []string{"CVE"}
|
||||||
|
|
||||||
func (ec *executionContext) _CVE(ctx context.Context, sel ast.SelectionSet, obj *Cve) graphql.Marshaler {
|
func (ec *executionContext) _CVE(ctx context.Context, sel ast.SelectionSet, obj *Cve) graphql.Marshaler {
|
||||||
|
@ -7401,6 +7921,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||||
return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc)
|
return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.Concurrently(i, func() graphql.Marshaler {
|
||||||
|
return rrm(innerCtx)
|
||||||
|
})
|
||||||
|
case "Referrers":
|
||||||
|
field := field
|
||||||
|
|
||||||
|
innerFunc := func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._Query_Referrers(ctx, field)
|
||||||
|
if res == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
rrm := func(ctx context.Context) graphql.Marshaler {
|
||||||
|
return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc)
|
||||||
|
}
|
||||||
|
|
||||||
out.Concurrently(i, func() graphql.Marshaler {
|
out.Concurrently(i, func() graphql.Marshaler {
|
||||||
return rrm(innerCtx)
|
return rrm(innerCtx)
|
||||||
})
|
})
|
||||||
|
@ -7427,6 +7970,50 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var referrerImplementors = []string{"Referrer"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Referrer(ctx context.Context, sel ast.SelectionSet, obj *Referrer) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.OperationContext, sel, referrerImplementors)
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
var invalids uint32
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("Referrer")
|
||||||
|
case "MediaType":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Referrer_MediaType(ctx, field, obj)
|
||||||
|
|
||||||
|
case "ArtifactType":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Referrer_ArtifactType(ctx, field, obj)
|
||||||
|
|
||||||
|
case "Size":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Referrer_Size(ctx, field, obj)
|
||||||
|
|
||||||
|
case "Digest":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Referrer_Digest(ctx, field, obj)
|
||||||
|
|
||||||
|
case "Annotations":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Referrer_Annotations(ctx, field, obj)
|
||||||
|
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
invalids++
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch()
|
||||||
|
if invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
var repoInfoImplementors = []string{"RepoInfo"}
|
var repoInfoImplementors = []string{"RepoInfo"}
|
||||||
|
|
||||||
func (ec *executionContext) _RepoInfo(ctx context.Context, sel ast.SelectionSet, obj *RepoInfo) graphql.Marshaler {
|
func (ec *executionContext) _RepoInfo(ctx context.Context, sel ast.SelectionSet, obj *RepoInfo) graphql.Marshaler {
|
||||||
|
@ -7835,6 +8422,44 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
|
||||||
|
|
||||||
// region ***************************** type.gotpl *****************************
|
// region ***************************** type.gotpl *****************************
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNAnnotation2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐAnnotation(ctx context.Context, sel ast.SelectionSet, v []*Annotation) graphql.Marshaler {
|
||||||
|
ret := make(graphql.Array, len(v))
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
isLen1 := len(v) == 1
|
||||||
|
if !isLen1 {
|
||||||
|
wg.Add(len(v))
|
||||||
|
}
|
||||||
|
for i := range v {
|
||||||
|
i := i
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Index: &i,
|
||||||
|
Result: &v[i],
|
||||||
|
}
|
||||||
|
ctx := graphql.WithFieldContext(ctx, fc)
|
||||||
|
f := func(i int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if !isLen1 {
|
||||||
|
defer wg.Done()
|
||||||
|
}
|
||||||
|
ret[i] = ec.marshalOAnnotation2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐAnnotation(ctx, sel, v[i])
|
||||||
|
}
|
||||||
|
if isLen1 {
|
||||||
|
f(i)
|
||||||
|
} else {
|
||||||
|
go f(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) {
|
func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) {
|
||||||
res, err := graphql.UnmarshalBoolean(v)
|
res, err := graphql.UnmarshalBoolean(v)
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
@ -7888,6 +8513,44 @@ func (ec *executionContext) marshalNImageSummary2ᚖzotregistryᚗioᚋzotᚋpkg
|
||||||
return ec._ImageSummary(ctx, sel, v)
|
return ec._ImageSummary(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNReferrer2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐReferrer(ctx context.Context, sel ast.SelectionSet, v []*Referrer) graphql.Marshaler {
|
||||||
|
ret := make(graphql.Array, len(v))
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
isLen1 := len(v) == 1
|
||||||
|
if !isLen1 {
|
||||||
|
wg.Add(len(v))
|
||||||
|
}
|
||||||
|
for i := range v {
|
||||||
|
i := i
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Index: &i,
|
||||||
|
Result: &v[i],
|
||||||
|
}
|
||||||
|
ctx := graphql.WithFieldContext(ctx, fc)
|
||||||
|
f := func(i int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if !isLen1 {
|
||||||
|
defer wg.Done()
|
||||||
|
}
|
||||||
|
ret[i] = ec.marshalOReferrer2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐReferrer(ctx, sel, v[i])
|
||||||
|
}
|
||||||
|
if isLen1 {
|
||||||
|
f(i)
|
||||||
|
} else {
|
||||||
|
go f(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNRepoInfo2zotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐRepoInfo(ctx context.Context, sel ast.SelectionSet, v RepoInfo) graphql.Marshaler {
|
func (ec *executionContext) marshalNRepoInfo2zotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐRepoInfo(ctx context.Context, sel ast.SelectionSet, v RepoInfo) graphql.Marshaler {
|
||||||
return ec._RepoInfo(ctx, sel, &v)
|
return ec._RepoInfo(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
@ -8224,6 +8887,13 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOAnnotation2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐAnnotation(ctx context.Context, sel ast.SelectionSet, v *Annotation) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._Annotation(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) {
|
func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) {
|
||||||
res, err := graphql.UnmarshalBoolean(v)
|
res, err := graphql.UnmarshalBoolean(v)
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
@ -8615,6 +9285,13 @@ func (ec *executionContext) marshalOPackageInfo2ᚖzotregistryᚗioᚋzotᚋpkg
|
||||||
return ec._PackageInfo(ctx, sel, v)
|
return ec._PackageInfo(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOReferrer2ᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐReferrer(ctx context.Context, sel ast.SelectionSet, v *Referrer) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._Referrer(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalORepoSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐRepoSummary(ctx context.Context, sel ast.SelectionSet, v []*RepoSummary) graphql.Marshaler {
|
func (ec *executionContext) marshalORepoSummary2ᚕᚖzotregistryᚗioᚋzotᚋpkgᚋextensionsᚋsearchᚋgql_generatedᚐRepoSummary(ctx context.Context, sel ast.SelectionSet, v []*RepoSummary) graphql.Marshaler {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
|
|
|
@ -6,6 +6,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Annotation struct {
|
||||||
|
Key *string `json:"Key"`
|
||||||
|
Value *string `json:"Value"`
|
||||||
|
}
|
||||||
|
|
||||||
// Contains various details about the CVE and a list of PackageInfo about the affected packages
|
// Contains various details about the CVE and a list of PackageInfo about the affected packages
|
||||||
type Cve struct {
|
type Cve struct {
|
||||||
ID *string `json:"Id"`
|
ID *string `json:"Id"`
|
||||||
|
@ -95,6 +100,14 @@ type PackageInfo struct {
|
||||||
FixedVersion *string `json:"FixedVersion"`
|
FixedVersion *string `json:"FixedVersion"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Referrer struct {
|
||||||
|
MediaType *string `json:"MediaType"`
|
||||||
|
ArtifactType *string `json:"ArtifactType"`
|
||||||
|
Size *int `json:"Size"`
|
||||||
|
Digest *string `json:"Digest"`
|
||||||
|
Annotations []*Annotation `json:"Annotations"`
|
||||||
|
}
|
||||||
|
|
||||||
// Contains details about the repo: a list of image summaries and a summary of the repo
|
// Contains details about the repo: a list of image summaries and a summary of the repo
|
||||||
type RepoInfo struct {
|
type RepoInfo struct {
|
||||||
Images []*ImageSummary `json:"Images"`
|
Images []*ImageSummary `json:"Images"`
|
||||||
|
|
|
@ -576,6 +576,47 @@ func (r *queryResolver) getImageList(store storage.ImageStore, imageName string)
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getReferrers(store storage.ImageStore, repoName string, digest string, artifactType string, log log.Logger) (
|
||||||
|
[]*gql_generated.Referrer, error,
|
||||||
|
) {
|
||||||
|
results := make([]*gql_generated.Referrer, 0)
|
||||||
|
|
||||||
|
index, err := store.GetReferrers(repoName, godigest.Digest(digest), artifactType)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("error extracting referrers list")
|
||||||
|
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, manifest := range index.Manifests {
|
||||||
|
size := int(manifest.Size)
|
||||||
|
digest := manifest.Digest.String()
|
||||||
|
annotations := make([]*gql_generated.Annotation, 0)
|
||||||
|
artifactType := manifest.ArtifactType
|
||||||
|
mediaType := manifest.MediaType
|
||||||
|
|
||||||
|
for k, v := range manifest.Annotations {
|
||||||
|
key := k
|
||||||
|
value := v
|
||||||
|
|
||||||
|
annotations = append(annotations, &gql_generated.Annotation{
|
||||||
|
Key: &key,
|
||||||
|
Value: &value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, &gql_generated.Referrer{
|
||||||
|
MediaType: &mediaType,
|
||||||
|
ArtifactType: &artifactType,
|
||||||
|
Digest: &digest,
|
||||||
|
Size: &size,
|
||||||
|
Annotations: annotations,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
func BuildImageInfo(repo string, tag string, manifestDigest godigest.Digest,
|
func BuildImageInfo(repo string, tag string, manifestDigest godigest.Digest,
|
||||||
manifest ispec.Manifest, imageConfig ispec.Image, isSigned bool,
|
manifest ispec.Manifest, imageConfig ispec.Image, isSigned bool,
|
||||||
) *gql_generated.ImageSummary {
|
) *gql_generated.ImageSummary {
|
||||||
|
|
|
@ -315,6 +315,52 @@ func TestMatching(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetReferrers(t *testing.T) {
|
||||||
|
Convey("getReferrers", t, func() {
|
||||||
|
Convey("GetReferrers returns error", func() {
|
||||||
|
testLogger := log.NewLogger("debug", "")
|
||||||
|
mockedStore := mocks.MockedImageStore{
|
||||||
|
GetReferrersFn: func(repo string, digest godigest.Digest, artifactType string) (ispec.Index, error) {
|
||||||
|
return ispec.Index{}, ErrTestError
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := getReferrers(mockedStore, "test", "", "", testLogger)
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("GetReferrers return index of descriptors", func() {
|
||||||
|
testLogger := log.NewLogger("debug", "")
|
||||||
|
referrerDescriptor := ispec.Descriptor{
|
||||||
|
MediaType: ispec.MediaTypeArtifactManifest,
|
||||||
|
ArtifactType: "com.artifact.test",
|
||||||
|
Size: 403,
|
||||||
|
Digest: godigest.FromString("test"),
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"key": "value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mockedStore := mocks.MockedImageStore{
|
||||||
|
GetReferrersFn: func(repo string, digest godigest.Digest, artifactType string) (ispec.Index, error) {
|
||||||
|
return ispec.Index{
|
||||||
|
Manifests: []ispec.Descriptor{
|
||||||
|
referrerDescriptor,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
referrers, err := getReferrers(mockedStore, "test", "", "", testLogger)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(*referrers[0].ArtifactType, ShouldEqual, referrerDescriptor.ArtifactType)
|
||||||
|
So(*referrers[0].MediaType, ShouldEqual, referrerDescriptor.MediaType)
|
||||||
|
So(*referrers[0].Size, ShouldEqual, referrerDescriptor.Size)
|
||||||
|
So(*referrers[0].Digest, ShouldEqual, referrerDescriptor.Digest)
|
||||||
|
So(*referrers[0].Annotations[0].Value, ShouldEqual, referrerDescriptor.Annotations["key"])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestExtractImageDetails(t *testing.T) {
|
func TestExtractImageDetails(t *testing.T) {
|
||||||
Convey("repoListWithNewestImage", t, func() {
|
Convey("repoListWithNewestImage", t, func() {
|
||||||
// log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
// log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||||
|
|
|
@ -134,6 +134,19 @@ type LayerHistory {
|
||||||
HistoryDescription: HistoryDescription
|
HistoryDescription: HistoryDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Annotation {
|
||||||
|
Key: String
|
||||||
|
Value: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Referrer {
|
||||||
|
MediaType: String
|
||||||
|
ArtifactType: String
|
||||||
|
Size: Int
|
||||||
|
Digest: String
|
||||||
|
Annotations: [Annotation]!
|
||||||
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Contains details about the supported OS and architecture of the image
|
Contains details about the supported OS and architecture of the image
|
||||||
"""
|
"""
|
||||||
|
@ -197,4 +210,10 @@ type Query {
|
||||||
Search for a specific image using its name
|
Search for a specific image using its name
|
||||||
"""
|
"""
|
||||||
Image(image: String!): ImageSummary
|
Image(image: String!): ImageSummary
|
||||||
|
|
||||||
|
"""
|
||||||
|
Returns a list of descriptors of an image or artifact manifest that are found in a <repo> and have a subject field of <digest>
|
||||||
|
Can be filtered based on a specific artifact type <type>
|
||||||
|
"""
|
||||||
|
Referrers(repo: String!, digest: String!, type: String!): [Referrer]!
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,6 +564,20 @@ func (r *queryResolver) Image(ctx context.Context, image string) (*gql_generated
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Referrers is the resolver for the Referrers field.
|
||||||
|
func (r *queryResolver) Referrers(ctx context.Context, repo string, digest string, typeArg string) ([]*gql_generated.Referrer, error) {
|
||||||
|
store := r.storeController.GetImageStore(repo)
|
||||||
|
|
||||||
|
referrers, err := getReferrers(store, repo, digest, typeArg, r.log)
|
||||||
|
if err != nil {
|
||||||
|
r.log.Error().Err(err).Msg("unable to get referrers from default store")
|
||||||
|
|
||||||
|
return []*gql_generated.Referrer{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return referrers, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Query returns gql_generated.QueryResolver implementation.
|
// Query returns gql_generated.QueryResolver implementation.
|
||||||
func (r *Resolver) Query() gql_generated.QueryResolver { return &queryResolver{r} }
|
func (r *Resolver) Query() gql_generated.QueryResolver { return &queryResolver{r} }
|
||||||
|
|
||||||
|
|
|
@ -446,6 +446,55 @@ func UploadImage(img Image, baseURL, repo string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UploadArtifact(baseURL, repo string, artifactManifest *imagespec.Artifact) error {
|
||||||
|
// put manifest
|
||||||
|
artifactManifestBlob, err := json.Marshal(artifactManifest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactManifestDigest := godigest.FromBytes(artifactManifestBlob)
|
||||||
|
|
||||||
|
_, err = resty.R().
|
||||||
|
SetHeader("Content-type", imagespec.MediaTypeArtifactManifest).
|
||||||
|
SetBody(artifactManifestBlob).
|
||||||
|
Put(baseURL + "/v2/" + repo + "/manifests/" + artifactManifestDigest.String())
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func UploadBlob(baseURL, repo string, blob []byte, artifactBlobMediaType string) error {
|
||||||
|
resp, err := resty.R().Post(baseURL + "/v2/" + repo + "/blobs/uploads/")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode() != http.StatusAccepted {
|
||||||
|
return ErrPostBlob
|
||||||
|
}
|
||||||
|
|
||||||
|
loc := resp.Header().Get("Location")
|
||||||
|
|
||||||
|
blobDigest := godigest.FromBytes(blob).String()
|
||||||
|
|
||||||
|
resp, err = resty.R().
|
||||||
|
SetHeader("Content-Length", fmt.Sprintf("%d", len(blob))).
|
||||||
|
SetHeader("Content-Type", artifactBlobMediaType).
|
||||||
|
SetQueryParam("digest", blobDigest).
|
||||||
|
SetBody(blob).
|
||||||
|
Put(baseURL + loc)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode() != http.StatusCreated {
|
||||||
|
return ErrPutBlob
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func ReadLogFileAndSearchString(logPath string, stringToMatch string, timeout time.Duration) (bool, error) {
|
func ReadLogFileAndSearchString(logPath string, stringToMatch string, timeout time.Duration) (bool, error) {
|
||||||
ctx, cancelFunc := context.WithTimeout(context.Background(), timeout)
|
ctx, cancelFunc := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
|
@ -156,6 +156,142 @@ func TestWaitTillTrivyDBDownloadStarted(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUploadArtifact(t *testing.T) {
|
||||||
|
Convey("Put request results in an error", t, func() {
|
||||||
|
port := test.GetFreePort()
|
||||||
|
baseURL := test.GetBaseURL(port)
|
||||||
|
|
||||||
|
artifact := ispec.Artifact{}
|
||||||
|
|
||||||
|
err := test.UploadArtifact(baseURL, "test", &artifact)
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUploadBlob(t *testing.T) {
|
||||||
|
Convey("Post request results in an error", t, func() {
|
||||||
|
port := test.GetFreePort()
|
||||||
|
baseURL := test.GetBaseURL(port)
|
||||||
|
|
||||||
|
err := test.UploadBlob(baseURL, "test", []byte("test"), "zot.com.test")
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Post request status differs from accepted", t, func() {
|
||||||
|
port := test.GetFreePort()
|
||||||
|
baseURL := test.GetBaseURL(port)
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
conf := config.New()
|
||||||
|
conf.HTTP.Port = port
|
||||||
|
conf.Storage.RootDirectory = tempDir
|
||||||
|
|
||||||
|
err := os.Chmod(tempDir, 0o400)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctlr := api.NewController(conf)
|
||||||
|
go startServer(ctlr)
|
||||||
|
defer stopServer(ctlr)
|
||||||
|
|
||||||
|
test.WaitTillServerReady(baseURL)
|
||||||
|
|
||||||
|
err = test.UploadBlob(baseURL, "test", []byte("test"), "zot.com.test")
|
||||||
|
So(err, ShouldEqual, test.ErrPostBlob)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Put request results in an error", t, func() {
|
||||||
|
port := test.GetFreePort()
|
||||||
|
baseURL := test.GetBaseURL(port)
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
conf := config.New()
|
||||||
|
conf.HTTP.Port = port
|
||||||
|
conf.Storage.RootDirectory = tempDir
|
||||||
|
|
||||||
|
ctlr := api.NewController(conf)
|
||||||
|
go startServer(ctlr)
|
||||||
|
defer stopServer(ctlr)
|
||||||
|
|
||||||
|
test.WaitTillServerReady(baseURL)
|
||||||
|
|
||||||
|
blob := new([]byte)
|
||||||
|
|
||||||
|
err := test.UploadBlob(baseURL, "test", *blob, "zot.com.test")
|
||||||
|
So(err, ShouldNotBeNil)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Put request status differs from accepted", t, func() {
|
||||||
|
port := test.GetFreePort()
|
||||||
|
baseURL := test.GetBaseURL(port)
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
conf := config.New()
|
||||||
|
conf.HTTP.Port = port
|
||||||
|
conf.Storage.RootDirectory = tempDir
|
||||||
|
|
||||||
|
ctlr := api.NewController(conf)
|
||||||
|
go startServer(ctlr)
|
||||||
|
defer stopServer(ctlr)
|
||||||
|
|
||||||
|
test.WaitTillServerReady(baseURL)
|
||||||
|
|
||||||
|
blob := []byte("test")
|
||||||
|
blobDigest := godigest.FromBytes(blob)
|
||||||
|
layerPath := path.Join(tempDir, "test", "blobs", "sha256")
|
||||||
|
blobPath := path.Join(layerPath, blobDigest.String())
|
||||||
|
if _, err := os.Stat(layerPath); os.IsNotExist(err) {
|
||||||
|
err = os.MkdirAll(layerPath, 0o700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(blobPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Chmod(layerPath, 0o000)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err = os.Chmod(layerPath, 0o700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.RemoveAll(file.Name())
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
err := test.UploadBlob(baseURL, "test", blob, "zot.com.test")
|
||||||
|
So(err, ShouldEqual, test.ErrPutBlob)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Put request successful", t, func() {
|
||||||
|
port := test.GetFreePort()
|
||||||
|
baseURL := test.GetBaseURL(port)
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
conf := config.New()
|
||||||
|
conf.HTTP.Port = port
|
||||||
|
conf.Storage.RootDirectory = tempDir
|
||||||
|
|
||||||
|
ctlr := api.NewController(conf)
|
||||||
|
go startServer(ctlr)
|
||||||
|
defer stopServer(ctlr)
|
||||||
|
|
||||||
|
test.WaitTillServerReady(baseURL)
|
||||||
|
|
||||||
|
blob := []byte("test")
|
||||||
|
|
||||||
|
err := test.UploadBlob(baseURL, "test", blob, "zot.com.test")
|
||||||
|
So(err, ShouldEqual, nil)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestUploadImage(t *testing.T) {
|
func TestUploadImage(t *testing.T) {
|
||||||
Convey("Post request results in an error", t, func() {
|
Convey("Post request results in an error", t, func() {
|
||||||
port := test.GetFreePort()
|
port := test.GetFreePort()
|
||||||
|
|
Loading…
Reference in a new issue