mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
fix: add support for uploaded index when signing using notation (#1882)
ci(notation): update to latest notation version fix(sync): add layers info when syncing signatures Signed-off-by: Andreea-Lupu <andreealupu1470@yahoo.com>
This commit is contained in:
parent
458d40fb48
commit
fc2380b57b
24 changed files with 576 additions and 45 deletions
2
Makefile
2
Makefile
|
@ -12,7 +12,7 @@ STACKER := $(shell which stacker)
|
|||
GOLINTER := $(TOOLSDIR)/bin/golangci-lint
|
||||
GOLINTER_VERSION := v1.52.2
|
||||
NOTATION := $(TOOLSDIR)/bin/notation
|
||||
NOTATION_VERSION := 1.0.0-rc.4
|
||||
NOTATION_VERSION := 1.0.0
|
||||
COSIGN := $(TOOLSDIR)/bin/cosign
|
||||
COSIGN_VERSION := 2.2.0
|
||||
HELM := $(TOOLSDIR)/bin/helm
|
||||
|
|
|
@ -5233,7 +5233,7 @@ func TestImageSignatures(t *testing.T) {
|
|||
So(err, ShouldBeNil)
|
||||
|
||||
image := fmt.Sprintf("localhost:%s/%s:%s", port, repoName, "1.0")
|
||||
err = signature.SignWithNotation("good", image, tdir)
|
||||
err = signature.SignWithNotation("good", image, tdir, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.VerifyWithNotation(image, tdir)
|
||||
|
@ -7806,7 +7806,7 @@ func TestGCSignaturesAndUntaggedManifestsWithMetaDB(t *testing.T) {
|
|||
So(err, ShouldBeNil)
|
||||
|
||||
// sign the image
|
||||
err = signature.SignWithNotation("good", image, tdir)
|
||||
err = signature.SignWithNotation("good", image, tdir, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// get cosign signature manifest
|
||||
|
|
|
@ -139,7 +139,7 @@ func TestSignature(t *testing.T) {
|
|||
err = UploadImage(CreateDefaultImage(), url, repoName, "0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignImageUsingNotary("repo7:0.0.1", port)
|
||||
err = signature.SignImageUsingNotary("repo7:0.0.1", port, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
searchConfig := getTestSearchConfig(url, client.NewSearchService())
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -119,3 +120,11 @@ func ContainsStringIgnoreCase(strSlice []string, str string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// this function will check if tag is a referrers tag
|
||||
// (https://github.com/opencontainers/distribution-spec/blob/main/spec.md#referrers-tag-schema).
|
||||
func IsReferrersTag(tag string) bool {
|
||||
referrersTagRule := regexp.MustCompile(`sha256\-[A-Za-z0-9]*$`)
|
||||
|
||||
return referrersTagRule.MatchString(tag)
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[
|
|||
// sign the image
|
||||
imageURL := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))
|
||||
|
||||
err = signature.SignWithNotation(certName, imageURL, rootDir)
|
||||
err = signature.SignWithNotation(certName, imageURL, rootDir, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
found, err = test.ReadLogFileAndSearchString(logFile.Name(), "update signatures validity", 10*time.Second)
|
||||
|
@ -499,7 +499,7 @@ func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[
|
|||
// sign the image
|
||||
imageURL := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))
|
||||
|
||||
err = signature.SignWithNotation(certName, imageURL, rootDir)
|
||||
err = signature.SignWithNotation(certName, imageURL, rootDir, false)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
found, err = test.ReadLogFileAndSearchString(logFile.Name(), "update signatures validity", 10*time.Second)
|
||||
|
|
|
@ -437,7 +437,7 @@ func TestVerifySignatures(t *testing.T) {
|
|||
// sign the image
|
||||
image := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))
|
||||
|
||||
err = signature.SignWithNotation("notation-sign-test", image, notationDir)
|
||||
err = signature.SignWithNotation("notation-sign-test", image, notationDir, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = test.CopyFiles(path.Join(notationDir, "notation", "truststore"), path.Join(notationDir, "truststore"))
|
||||
|
@ -1271,7 +1271,7 @@ func RunVerificationTests(t *testing.T, dbDriverParams map[string]interface{}) {
|
|||
// sign the image
|
||||
imageURL := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))
|
||||
|
||||
err = signature.SignWithNotation(certName, imageURL, notationDir)
|
||||
err = signature.SignWithNotation(certName, imageURL, notationDir, false)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
indexContent, err := ctlr.StoreController.DefaultStore.GetIndexContent(repo)
|
||||
|
|
|
@ -4422,7 +4422,7 @@ func TestMetaDBWhenSigningImages(t *testing.T) {
|
|||
})
|
||||
|
||||
Convey("Sign with notation", func() {
|
||||
err = signature.SignImageUsingNotary("repo1:1.0.1", port)
|
||||
err = signature.SignImageUsingNotary("repo1:1.0.1", port, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
resp, err := resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(queryImage1))
|
||||
|
@ -4439,7 +4439,7 @@ func TestMetaDBWhenSigningImages(t *testing.T) {
|
|||
})
|
||||
|
||||
Convey("Sign with notation index", func() {
|
||||
err = signature.SignImageUsingNotary("repo1:index", port)
|
||||
err = signature.SignImageUsingNotary("repo1:index", port, false)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
resp, err := resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(queryIndex))
|
||||
|
@ -5438,7 +5438,7 @@ func TestMetaDBWhenDeletingImages(t *testing.T) {
|
|||
|
||||
Convey("Delete a notary signature", func() {
|
||||
repo := "repo1"
|
||||
err := signature.SignImageUsingNotary("repo1:1.0.1", port)
|
||||
err := signature.SignImageUsingNotary("repo1:1.0.1", port, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
query := `
|
||||
|
|
|
@ -5,5 +5,6 @@ const (
|
|||
Oras = "OrasReference"
|
||||
Cosign = "CosignSignature"
|
||||
OCI = "OCIReference"
|
||||
Tag = "TagReference"
|
||||
SyncBlobUploadDir = ".sync"
|
||||
)
|
||||
|
|
|
@ -161,10 +161,8 @@ func (ref CosignReference) SyncReferences(ctx context.Context, localRepo, remote
|
|||
}
|
||||
|
||||
if isSig {
|
||||
err = ref.metaDB.AddManifestSignature(localRepo, signedManifestDig, mTypes.SignatureMetadata{
|
||||
SignatureType: sigType,
|
||||
SignatureDigest: referenceDigest.String(),
|
||||
})
|
||||
err = addSigToMeta(ref.metaDB, localRepo, sigType, cosignTag, signedManifestDig, referenceDigest,
|
||||
manifestBuf, imageStore, ref.log)
|
||||
} else {
|
||||
err = meta.SetImageMetaFromInput(localRepo, cosignTag, ispec.MediaTypeImageManifest,
|
||||
referenceDigest, manifestBuf, ref.storeController.GetImageStore(localRepo),
|
||||
|
|
|
@ -145,10 +145,8 @@ func (ref OciReferences) SyncReferences(ctx context.Context, localRepo, remoteRe
|
|||
}
|
||||
|
||||
if isSig {
|
||||
err = ref.metaDB.AddManifestSignature(localRepo, signedManifestDig, mTypes.SignatureMetadata{
|
||||
SignatureType: sigType,
|
||||
SignatureDigest: referenceDigest.String(),
|
||||
})
|
||||
err = addSigToMeta(ref.metaDB, localRepo, sigType, referrer.Digest.String(), signedManifestDig, referenceDigest,
|
||||
referenceBuf, imageStore, ref.log)
|
||||
} else {
|
||||
err = meta.SetImageMetaFromInput(localRepo, referenceDigest.String(), referrer.MediaType,
|
||||
referenceDigest, referenceBuf, ref.storeController.GetImageStore(localRepo),
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"zotregistry.io/zot/pkg/common"
|
||||
client "zotregistry.io/zot/pkg/extensions/sync/httpclient"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/meta"
|
||||
mTypes "zotregistry.io/zot/pkg/meta/types"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
storageTypes "zotregistry.io/zot/pkg/storage/types"
|
||||
|
@ -42,6 +43,7 @@ func NewReferences(httpClient *client.Client, storeController storage.StoreContr
|
|||
refs := References{log: log}
|
||||
|
||||
refs.referenceList = append(refs.referenceList, NewCosignReference(httpClient, storeController, metaDB, log))
|
||||
refs.referenceList = append(refs.referenceList, NewTagReferences(httpClient, storeController, metaDB, log))
|
||||
refs.referenceList = append(refs.referenceList, NewOciReferences(httpClient, storeController, metaDB, log))
|
||||
refs.referenceList = append(refs.referenceList, NewORASReferences(httpClient, storeController, metaDB, log))
|
||||
|
||||
|
@ -215,3 +217,21 @@ func getNotationManifestsFromOCIRefs(ociRefs ispec.Index) []ispec.Descriptor {
|
|||
|
||||
return notaryManifests
|
||||
}
|
||||
|
||||
func addSigToMeta(
|
||||
metaDB mTypes.MetaDB, repo, sigType, tag string, signedManifestDig, referenceDigest godigest.Digest,
|
||||
referenceBuf []byte, imageStore storageTypes.ImageStore, log log.Logger,
|
||||
) error {
|
||||
layersInfo, errGetLayers := meta.GetSignatureLayersInfo(repo, tag, referenceDigest.String(),
|
||||
sigType, referenceBuf, imageStore, log)
|
||||
|
||||
if errGetLayers != nil {
|
||||
return errGetLayers
|
||||
}
|
||||
|
||||
return metaDB.AddManifestSignature(repo, signedManifestDig, mTypes.SignatureMetadata{
|
||||
SignatureType: sigType,
|
||||
SignatureDigest: referenceDigest.String(),
|
||||
LayersInfo: layersInfo,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -86,6 +86,54 @@ func TestOci(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestReferrersTag(t *testing.T) {
|
||||
Convey("trigger errors", t, func() {
|
||||
cfg := client.Config{
|
||||
URL: "url",
|
||||
TLSVerify: false,
|
||||
}
|
||||
|
||||
client, err := client.New(cfg, log.NewLogger("debug", ""))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
referrersTag := NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
|
||||
GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
||||
return []byte{}, "", "", errRef
|
||||
},
|
||||
}}, nil, log.NewLogger("debug", ""))
|
||||
|
||||
ok := referrersTag.IsSigned(context.Background(), "repo", "")
|
||||
So(ok, ShouldBeFalse)
|
||||
|
||||
// trigger GetImageManifest err
|
||||
ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "digest")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(ok, ShouldBeFalse)
|
||||
|
||||
referrersTag = NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
|
||||
GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
||||
return []byte{}, "", "", zerr.ErrManifestNotFound
|
||||
},
|
||||
}}, nil, log.NewLogger("debug", ""))
|
||||
|
||||
// trigger GetImageManifest err
|
||||
ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "digest")
|
||||
So(err, ShouldBeNil)
|
||||
So(ok, ShouldBeFalse)
|
||||
|
||||
referrersTag = NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
|
||||
GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
|
||||
return []byte{}, "digest", "", nil
|
||||
},
|
||||
}}, nil, log.NewLogger("debug", ""))
|
||||
|
||||
// different digest
|
||||
ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "newdigest")
|
||||
So(err, ShouldBeNil)
|
||||
So(ok, ShouldBeFalse)
|
||||
})
|
||||
}
|
||||
|
||||
func TestORAS(t *testing.T) {
|
||||
Convey("trigger errors", t, func() {
|
||||
cfg := client.Config{
|
||||
|
@ -392,3 +440,14 @@ func TestCompareArtifactRefs(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddSigToMeta(t *testing.T) {
|
||||
Convey("Test addSigToMeta", t, func() {
|
||||
imageStore := mocks.MockedImageStore{}
|
||||
metaDB := mocks.MetaDBMock{}
|
||||
|
||||
err := addSigToMeta(metaDB, "repo", "cosign", "tag", godigest.FromString("signedmanifest"),
|
||||
godigest.FromString("reference"), []byte("bad"), imageStore, log.Logger{})
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
|
185
pkg/extensions/sync/references/referrers_tag.go
Normal file
185
pkg/extensions/sync/references/referrers_tag.go
Normal file
|
@ -0,0 +1,185 @@
|
|||
//go:build sync
|
||||
// +build sync
|
||||
|
||||
package references
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
zerr "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/common"
|
||||
"zotregistry.io/zot/pkg/extensions/sync/constants"
|
||||
client "zotregistry.io/zot/pkg/extensions/sync/httpclient"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/meta"
|
||||
mTypes "zotregistry.io/zot/pkg/meta/types"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
type TagReferences struct {
|
||||
client *client.Client
|
||||
storeController storage.StoreController
|
||||
metaDB mTypes.MetaDB
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func NewTagReferences(httpClient *client.Client, storeController storage.StoreController,
|
||||
metaDB mTypes.MetaDB, log log.Logger,
|
||||
) TagReferences {
|
||||
return TagReferences{
|
||||
client: httpClient,
|
||||
storeController: storeController,
|
||||
metaDB: metaDB,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (ref TagReferences) Name() string {
|
||||
return constants.Tag
|
||||
}
|
||||
|
||||
func (ref TagReferences) IsSigned(ctx context.Context, remoteRepo, subjectDigestStr string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ref TagReferences) canSkipReferences(localRepo, subjectDigestStr, digest string) (bool, error) {
|
||||
imageStore := ref.storeController.GetImageStore(localRepo)
|
||||
|
||||
_, localDigest, _, err := imageStore.GetImageManifest(localRepo, getReferrersTagFromSubjectDigest(subjectDigestStr))
|
||||
if err != nil {
|
||||
if errors.Is(err, zerr.ErrManifestNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
ref.log.Error().Str("errorType", common.TypeOf(err)).
|
||||
Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Err(err).Msg("couldn't get local index with referrers tag for image")
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
if localDigest.String() != digest {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
ref.log.Info().Str("repository", localRepo).Str("reference", subjectDigestStr).
|
||||
Msg("skipping index with referrers tag for image, already synced")
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (ref TagReferences) SyncReferences(ctx context.Context, localRepo, remoteRepo, subjectDigestStr string) (
|
||||
[]godigest.Digest, error,
|
||||
) {
|
||||
refsDigests := make([]godigest.Digest, 0, 10)
|
||||
|
||||
index, indexContent, err := ref.getIndex(ctx, remoteRepo, subjectDigestStr)
|
||||
if err != nil {
|
||||
return refsDigests, err
|
||||
}
|
||||
|
||||
skipTagRefs, err := ref.canSkipReferences(localRepo, subjectDigestStr, string(godigest.FromBytes(indexContent)))
|
||||
if err != nil {
|
||||
ref.log.Error().Err(err).Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Msg("couldn't check if the upstream index with referrers tag for image can be skipped")
|
||||
}
|
||||
|
||||
if skipTagRefs {
|
||||
return refsDigests, nil
|
||||
}
|
||||
|
||||
imageStore := ref.storeController.GetImageStore(localRepo)
|
||||
|
||||
ref.log.Info().Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Msg("syncing oci references for image")
|
||||
|
||||
for _, referrer := range index.Manifests {
|
||||
referenceBuf, referenceDigest, err := syncManifest(ctx, ref.client, imageStore, localRepo, remoteRepo,
|
||||
referrer, subjectDigestStr, ref.log)
|
||||
if err != nil {
|
||||
return refsDigests, err
|
||||
}
|
||||
|
||||
refsDigests = append(refsDigests, referenceDigest)
|
||||
|
||||
if ref.metaDB != nil {
|
||||
ref.log.Debug().Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Msg("metaDB: trying to add oci references for image")
|
||||
|
||||
isSig, sigType, signedManifestDig, err := storage.CheckIsImageSignature(localRepo, referenceBuf,
|
||||
referrer.Digest.String())
|
||||
if err != nil {
|
||||
return refsDigests, fmt.Errorf("failed to check if oci reference '%s@%s' is a signature: %w", localRepo,
|
||||
referrer.Digest.String(), err)
|
||||
}
|
||||
|
||||
if isSig {
|
||||
err = addSigToMeta(ref.metaDB, localRepo, sigType, referrer.Digest.String(), signedManifestDig, referenceDigest,
|
||||
referenceBuf, imageStore, ref.log)
|
||||
} else {
|
||||
err = meta.SetImageMetaFromInput(localRepo, referenceDigest.String(), referrer.MediaType,
|
||||
referenceDigest, referenceBuf, ref.storeController.GetImageStore(localRepo),
|
||||
ref.metaDB, ref.log)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return refsDigests, fmt.Errorf("failed to set metadata for oci reference in '%s@%s': %w",
|
||||
localRepo, subjectDigestStr, err)
|
||||
}
|
||||
|
||||
ref.log.Info().Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Msg("metaDB: successfully added oci references to MetaDB for image")
|
||||
}
|
||||
}
|
||||
|
||||
ref.log.Info().Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Msg("syncing index with referrers tag for image")
|
||||
|
||||
referrersTag := getReferrersTagFromSubjectDigest(subjectDigestStr)
|
||||
|
||||
_, _, err = imageStore.PutImageManifest(localRepo, referrersTag, index.MediaType, indexContent)
|
||||
if err != nil {
|
||||
ref.log.Error().Str("errorType", common.TypeOf(err)).
|
||||
Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Err(err).Msg("couldn't upload index with referrers tag for image")
|
||||
|
||||
return refsDigests, err
|
||||
}
|
||||
|
||||
ref.log.Info().Str("repository", localRepo).Str("subject", subjectDigestStr).
|
||||
Msg("successfully synced index with referrers tag for image")
|
||||
|
||||
return refsDigests, nil
|
||||
}
|
||||
|
||||
func (ref TagReferences) getIndex(
|
||||
ctx context.Context, repo, subjectDigestStr string,
|
||||
) (ispec.Index, []byte, error) {
|
||||
var index ispec.Index
|
||||
|
||||
content, _, statusCode, err := ref.client.MakeGetRequest(ctx, &index, ispec.MediaTypeImageIndex,
|
||||
"v2", repo, "manifests", getReferrersTagFromSubjectDigest(subjectDigestStr))
|
||||
if err != nil {
|
||||
if statusCode == http.StatusNotFound {
|
||||
ref.log.Debug().Str("repository", repo).Str("subject", subjectDigestStr).
|
||||
Msg("couldn't find any index with referrers tag for image, skipping")
|
||||
|
||||
return index, []byte{}, zerr.ErrSyncReferrerNotFound
|
||||
}
|
||||
|
||||
return index, []byte{}, err
|
||||
}
|
||||
|
||||
return index, content, nil
|
||||
}
|
||||
|
||||
func getReferrersTagFromSubjectDigest(digestStr string) string {
|
||||
return strings.Replace(digestStr, ":", "-", 1)
|
||||
}
|
|
@ -298,7 +298,7 @@ func (service *BaseService) SyncRepo(ctx context.Context, repo string) error {
|
|||
default:
|
||||
}
|
||||
|
||||
if references.IsCosignTag(tag) {
|
||||
if references.IsCosignTag(tag) || common.IsReferrersTag(tag) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -374,7 +374,8 @@ func (service *BaseService) syncTag(ctx context.Context, localRepo, remoteRepo,
|
|||
return "", zerr.ErrMediaTypeNotSupported
|
||||
}
|
||||
|
||||
if service.config.OnlySigned != nil && *service.config.OnlySigned && !references.IsCosignTag(tag) {
|
||||
if service.config.OnlySigned != nil && *service.config.OnlySigned &&
|
||||
!references.IsCosignTag(tag) && !common.IsReferrersTag(tag) {
|
||||
signed := service.references.IsSigned(ctx, remoteRepo, manifestDigest.String())
|
||||
if !signed {
|
||||
// skip unsigned images
|
||||
|
|
|
@ -898,6 +898,146 @@ func TestOnDemand(t *testing.T) {
|
|||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
||||
})
|
||||
|
||||
Convey("Sync referrers tag errors", func() {
|
||||
// start upstream server
|
||||
rootDir := t.TempDir()
|
||||
port := test.GetFreePort()
|
||||
srcBaseURL := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
conf.Storage.GC = false
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = rootDir
|
||||
|
||||
cm := test.NewControllerManager(ctlr)
|
||||
cm.StartAndWait(conf.HTTP.Port)
|
||||
defer cm.StopServer()
|
||||
|
||||
image := CreateRandomImage()
|
||||
manifestBlob := image.ManifestDescriptor.Data
|
||||
manifestDigest := image.ManifestDescriptor.Digest
|
||||
|
||||
err := UploadImage(image, srcBaseURL, "remote-repo", "test")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
subjectDesc := ispec.Descriptor{
|
||||
MediaType: ispec.MediaTypeImageManifest,
|
||||
Digest: manifestDigest,
|
||||
Size: int64(len(manifestBlob)),
|
||||
}
|
||||
|
||||
ociRefImage := CreateDefaultImageWith().Subject(&subjectDesc).Build()
|
||||
|
||||
err = UploadImage(ociRefImage, srcBaseURL, "remote-repo", ociRefImage.ManifestDescriptor.Digest.String())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
tag := strings.Replace(manifestDigest.String(), ":", "-", 1)
|
||||
|
||||
// add index with referrers tag
|
||||
tagRefIndex := ispec.Index{
|
||||
MediaType: ispec.MediaTypeImageIndex,
|
||||
Manifests: []ispec.Descriptor{
|
||||
{
|
||||
MediaType: ispec.MediaTypeImageManifest,
|
||||
Digest: ociRefImage.ManifestDescriptor.Digest,
|
||||
Size: int64(len(ociRefImage.ManifestDescriptor.Data)),
|
||||
},
|
||||
},
|
||||
Annotations: map[string]string{ispec.AnnotationRefName: tag},
|
||||
}
|
||||
|
||||
tagRefIndex.SchemaVersion = 2
|
||||
|
||||
tagRefIndexBlob, err := json.Marshal(tagRefIndex)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
resp, err := resty.R().
|
||||
SetHeader("Content-type", ispec.MediaTypeImageIndex).
|
||||
SetBody(tagRefIndexBlob).
|
||||
Put(srcBaseURL + "/v2/remote-repo/manifests/" + tag)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusCreated)
|
||||
|
||||
//------- Start downstream server
|
||||
|
||||
var tlsVerify bool
|
||||
|
||||
regex := ".*"
|
||||
semver := true
|
||||
|
||||
destPort := test.GetFreePort()
|
||||
destConfig := config.New()
|
||||
|
||||
destBaseURL := test.GetBaseURL(destPort)
|
||||
|
||||
hostname, err := os.Hostname()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
syncRegistryConfig := syncconf.RegistryConfig{
|
||||
Content: []syncconf.Content{
|
||||
{
|
||||
Prefix: "remote-repo",
|
||||
Tags: &syncconf.Tags{
|
||||
Regex: ®ex,
|
||||
Semver: &semver,
|
||||
},
|
||||
},
|
||||
},
|
||||
// include self url, should be ignored
|
||||
URLs: []string{
|
||||
fmt.Sprintf("http://%s", hostname), destBaseURL,
|
||||
srcBaseURL, fmt.Sprintf("http://localhost:%s", destPort),
|
||||
},
|
||||
TLSVerify: &tlsVerify,
|
||||
CertDir: "",
|
||||
OnDemand: true,
|
||||
}
|
||||
|
||||
defaultVal := true
|
||||
syncConfig := &syncconf.Config{
|
||||
Enable: &defaultVal,
|
||||
Registries: []syncconf.RegistryConfig{syncRegistryConfig},
|
||||
}
|
||||
|
||||
destConfig.HTTP.Port = destPort
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
destConfig.Storage.RootDirectory = destDir
|
||||
destConfig.Storage.Dedupe = false
|
||||
destConfig.Storage.GC = false
|
||||
|
||||
destConfig.Extensions = &extconf.ExtensionConfig{}
|
||||
|
||||
destConfig.Extensions.Sync = syncConfig
|
||||
|
||||
dctlr := api.NewController(destConfig)
|
||||
|
||||
// metadb fails for syncReferrersTag"
|
||||
dctlr.MetaDB = mocks.MetaDBMock{
|
||||
SetManifestDataFn: func(manifestDigest godigest.Digest, mm mTypes.ManifestData) error {
|
||||
if manifestDigest.String() == ociRefImage.ManifestDescriptor.Digest.String() {
|
||||
return sync.ErrTestError
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
dcm := test.NewControllerManager(dctlr)
|
||||
dcm.StartAndWait(destPort)
|
||||
defer dcm.StopServer()
|
||||
|
||||
resp, err = resty.R().Get(destBaseURL + "/v2/remote-repo/manifests/test")
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
||||
|
||||
resp, err = resty.R().Get(destBaseURL + "/v2/remote-repo/manifests/" + tag)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -3818,7 +3958,10 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
|
|||
So(found, ShouldBeTrue)
|
||||
|
||||
// should not be synced nor sync on demand
|
||||
resp, err = resty.R().Get(destBaseURL + artifactURLPath)
|
||||
resp, err = resty.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetQueryParam("artifactType", "application/vnd.cncf.icecream").
|
||||
Get(destBaseURL + artifactURLPath)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
||||
|
||||
|
@ -3871,7 +4014,10 @@ func TestPeriodicallySignaturesErr(t *testing.T) {
|
|||
So(found, ShouldBeTrue)
|
||||
|
||||
// should not be synced nor sync on demand
|
||||
resp, err = resty.R().Get(destBaseURL + artifactURLPath)
|
||||
resp, err = resty.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
SetQueryParam("artifactType", "application/vnd.cncf.icecream").
|
||||
Get(destBaseURL + artifactURLPath)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, http.StatusOK)
|
||||
|
||||
|
@ -4475,7 +4621,7 @@ func TestSyncedSignaturesMetaDB(t *testing.T) {
|
|||
err := UploadImage(signedImage, srcBaseURL, repoName, tag)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignImageUsingNotary(repoName+":"+tag, srcPort)
|
||||
err = signature.SignImageUsingNotary(repoName+":"+tag, srcPort, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignImageUsingCosign(repoName+":"+tag, srcPort)
|
||||
|
@ -5715,7 +5861,7 @@ func TestSyncSignaturesDiff(t *testing.T) {
|
|||
So(func() { signImage(tdir, srcPort, repoName, digest) }, ShouldNotPanic)
|
||||
|
||||
// wait for signatures
|
||||
time.Sleep(10 * time.Second)
|
||||
time.Sleep(12 * time.Second)
|
||||
|
||||
// notation verify the image
|
||||
image = fmt.Sprintf("localhost:%s/%s:%s", destPort, repoName, testImageTag)
|
||||
|
@ -6301,8 +6447,8 @@ func signImage(tdir, port, repoName string, digest godigest.Digest) {
|
|||
// sign the image
|
||||
image := fmt.Sprintf("localhost:%s/%s@%s", port, repoName, digest.String())
|
||||
|
||||
err = signature.SignWithNotation("good", image, tdir)
|
||||
if err != nil {
|
||||
err = signature.SignWithNotation("good", image, tdir, false)
|
||||
if err != nil && !strings.Contains(err.Error(), "failed to delete dangling referrers index") {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package meta
|
|||
import (
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
|
||||
zcommon "zotregistry.io/zot/pkg/common"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/meta/common"
|
||||
mTypes "zotregistry.io/zot/pkg/meta/types"
|
||||
|
@ -15,6 +16,10 @@ import (
|
|||
func OnUpdateManifest(repo, reference, mediaType string, digest godigest.Digest, body []byte,
|
||||
storeController storage.StoreController, metaDB mTypes.MetaDB, log log.Logger,
|
||||
) error {
|
||||
if zcommon.IsReferrersTag(reference) {
|
||||
return nil
|
||||
}
|
||||
|
||||
imgStore := storeController.GetImageStore(repo)
|
||||
|
||||
// check if image is a signature
|
||||
|
@ -87,6 +92,10 @@ func OnUpdateManifest(repo, reference, mediaType string, digest godigest.Digest,
|
|||
func OnDeleteManifest(repo, reference, mediaType string, digest godigest.Digest, manifestBlob []byte,
|
||||
storeController storage.StoreController, metaDB mTypes.MetaDB, log log.Logger,
|
||||
) error {
|
||||
if zcommon.IsReferrersTag(reference) {
|
||||
return nil
|
||||
}
|
||||
|
||||
imgStore := storeController.GetImageStore(repo)
|
||||
|
||||
isSignature, signatureType, signedManifestDigest, err := storage.CheckIsImageSignature(repo, manifestBlob,
|
||||
|
@ -154,7 +163,7 @@ func OnGetManifest(name, reference string, body []byte,
|
|||
return err
|
||||
}
|
||||
|
||||
if !isSignature {
|
||||
if !isSignature && !zcommon.IsReferrersTag(reference) {
|
||||
err := metaDB.IncrementImageDownloads(name, reference)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("repository", name).Str("reference", reference).
|
||||
|
|
|
@ -108,6 +108,12 @@ func TestUpdateErrors(t *testing.T) {
|
|||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("IsReferrersTag true", func() {
|
||||
err := meta.OnUpdateManifest("repo", "sha256-123", "digest", "media", []byte("bad"),
|
||||
storeController, metaDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("GetSignatureLayersInfo errors", func() {
|
||||
// get notation signature layers info
|
||||
badNotationManifestContent := ispec.Manifest{
|
||||
|
@ -180,6 +186,12 @@ func TestUpdateErrors(t *testing.T) {
|
|||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("IsReferrersTag true", func() {
|
||||
err := meta.OnDeleteManifest("repo", "sha256-123", "digest", "media", []byte("bad"),
|
||||
storeController, metaDB, log)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("DeleteReferrers errors", func() {
|
||||
metaDB.DeleteReferrerFn = func(repo string, referredDigest, referrerDigest godigest.Digest) error {
|
||||
return ErrTestError
|
||||
|
|
|
@ -80,6 +80,10 @@ func ParseRepo(repo string, metaDB mTypes.MetaDB, storeController storage.StoreC
|
|||
for _, descriptor := range indexContent.Manifests {
|
||||
tag := descriptor.Annotations[ispec.AnnotationRefName]
|
||||
|
||||
if zcommon.IsReferrersTag(tag) {
|
||||
continue
|
||||
}
|
||||
|
||||
descriptorBlob, err := getCachedBlob(repo, descriptor, metaDB, imageStore, log)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("load-repo: error checking manifestMeta in MetaDB")
|
||||
|
@ -299,6 +303,11 @@ func getNotationSignatureLayersInfo(
|
|||
return layers, err
|
||||
}
|
||||
|
||||
// skip if is a notation index
|
||||
if manifestContent.MediaType == ispec.MediaTypeImageIndex {
|
||||
return []mTypes.LayerInfo{}, nil
|
||||
}
|
||||
|
||||
if len(manifestContent.Layers) != 1 {
|
||||
log.Error().Err(zerr.ErrBadManifest).Str("repository", repo).Str("reference", manifestDigest).
|
||||
Msg("load-repo: notation signature manifest requires exactly one layer but it does not")
|
||||
|
|
|
@ -347,6 +347,33 @@ func TestParseStorageErrors(t *testing.T) {
|
|||
err = meta.ParseRepo("repo", metaDB, storeController, log)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("IsReferrersTag -> true", func() {
|
||||
indexContent := ispec.Index{
|
||||
Manifests: []ispec.Descriptor{
|
||||
{
|
||||
Digest: godigest.FromString("indx1"),
|
||||
MediaType: ispec.MediaTypeImageIndex,
|
||||
Annotations: map[string]string{
|
||||
ispec.AnnotationRefName: "sha256-123",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
indexBlob, err := json.Marshal(indexContent)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
imageStore.GetIndexContentFn = func(repo string) ([]byte, error) {
|
||||
return indexBlob, nil
|
||||
}
|
||||
|
||||
metaDB.SetIndexDataFn = func(digest godigest.Digest, indexData mTypes.IndexData) error {
|
||||
return ErrTestError
|
||||
}
|
||||
|
||||
err = meta.ParseRepo("repo", metaDB, storeController, log)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -605,6 +632,19 @@ func TestGetSignatureLayersInfo(t *testing.T) {
|
|||
So(layers, ShouldBeEmpty)
|
||||
})
|
||||
|
||||
Convey("notation index", t, func() {
|
||||
notationIndex := ispec.Index{
|
||||
MediaType: ispec.MediaTypeImageIndex,
|
||||
}
|
||||
|
||||
notationIndexBlob, err := json.Marshal(notationIndex)
|
||||
So(err, ShouldBeNil)
|
||||
layers, err := meta.GetSignatureLayersInfo("repo", "tag", "123", zcommon.NotationSignature, notationIndexBlob,
|
||||
nil, log.NewLogger("debug", ""))
|
||||
So(err, ShouldBeNil)
|
||||
So(layers, ShouldBeEmpty)
|
||||
})
|
||||
|
||||
Convey("error while unmarshaling manifest content", t, func() {
|
||||
_, err := meta.GetSignatureLayersInfo("repo", "tag", "123", zcommon.CosignSignature, []byte("bad manifest"),
|
||||
nil, log.NewLogger("debug", ""))
|
||||
|
|
|
@ -325,7 +325,7 @@ func TestBaseOciLayoutUtils(t *testing.T) {
|
|||
isSigned := olu.CheckManifestSignature(repo, manifestList[0].Digest)
|
||||
So(isSigned, ShouldBeFalse)
|
||||
|
||||
err = signature.SignImageUsingNotary(fmt.Sprintf("%s:%s", repo, tag), port)
|
||||
err = signature.SignImageUsingNotary(fmt.Sprintf("%s:%s", repo, tag), port, true)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
isSigned = olu.CheckManifestSignature(repo, manifestList[0].Digest)
|
||||
|
|
|
@ -139,7 +139,7 @@ func GenerateNotationCerts(tdir string, certName string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func SignWithNotation(keyName string, reference string, tdir string) error {
|
||||
func SignWithNotation(keyName, reference, tdir string, referrersCapability bool) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
// getSigner
|
||||
|
@ -193,6 +193,10 @@ func SignWithNotation(keyName string, reference string, tdir string) error {
|
|||
PlainHTTP: plainHTTP,
|
||||
}
|
||||
|
||||
if !referrersCapability {
|
||||
_ = remoteRepo.SetReferrersCapability(false)
|
||||
}
|
||||
|
||||
repositoryOpts := notreg.RepositoryOptions{}
|
||||
|
||||
sigRepo := notreg.NewRepositoryWithOptions(remoteRepo, repositoryOpts)
|
||||
|
@ -432,7 +436,7 @@ func LoadNotationConfig(tdir string) (*notconfig.Config, error) {
|
|||
return configInfo, nil
|
||||
}
|
||||
|
||||
func SignImageUsingNotary(repoTag, port string) error {
|
||||
func SignImageUsingNotary(repoTag, port string, referrersCapability bool) error {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -463,7 +467,7 @@ func SignImageUsingNotary(repoTag, port string) error {
|
|||
// sign the image
|
||||
image := fmt.Sprintf("localhost:%s/%s", port, repoTag)
|
||||
|
||||
err = SignWithNotation("notation-sign-test", image, tdir)
|
||||
err = SignWithNotation("notation-sign-test", image, tdir, referrersCapability)
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ func TestLoadNotationConfig(t *testing.T) {
|
|||
|
||||
func TestSignWithNotation(t *testing.T) {
|
||||
Convey("notation directory doesn't exist", t, func() {
|
||||
err := signature.SignWithNotation("key", "reference", t.TempDir())
|
||||
err := signature.SignWithNotation("key", "reference", t.TempDir(), true)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
|
@ -128,7 +128,7 @@ func TestSignWithNotation(t *testing.T) {
|
|||
err = os.WriteFile(filePath, []byte("{}"), 0o666) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignWithNotation("key", "reference", tempDir)
|
||||
err = signature.SignWithNotation("key", "reference", tempDir, true)
|
||||
So(err, ShouldEqual, signature.ErrKeyNotFound)
|
||||
})
|
||||
|
||||
|
@ -150,7 +150,7 @@ func TestSignWithNotation(t *testing.T) {
|
|||
err = os.Chmod(path.Join(tdir, "notation", "localkeys"), 0o000)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignWithNotation("key", "reference", tdir)
|
||||
err = signature.SignWithNotation("key", "reference", tdir, true)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
err = os.Chmod(path.Join(tdir, "notation", "localkeys"), 0o755)
|
||||
|
@ -172,7 +172,7 @@ func TestSignWithNotation(t *testing.T) {
|
|||
err = signature.GenerateNotationCerts(tdir, "key")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignWithNotation("key", "invalidReference", tdir)
|
||||
err = signature.SignWithNotation("key", "invalidReference", tdir, true)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
|
@ -191,7 +191,7 @@ func TestSignWithNotation(t *testing.T) {
|
|||
err = signature.GenerateNotationCerts(tdir, "key")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = signature.SignWithNotation("key", "localhost:8080/invalidreference:1.0", tdir)
|
||||
err = signature.SignWithNotation("key", "localhost:8080/invalidreference:1.0", tdir, true)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -163,10 +163,50 @@ function teardown_file() {
|
|||
}
|
||||
EOF
|
||||
|
||||
run notation sign --key "notation-sign-test" --plain-http localhost:8080/annotations:latest
|
||||
run notation sign --key "notation-sign-test" --insecure-registry localhost:8080/annotations:latest
|
||||
[ "$status" -eq 0 ]
|
||||
run notation verify --plain-http localhost:8080/annotations:latest
|
||||
run notation verify --insecure-registry localhost:8080/annotations:latest
|
||||
[ "$status" -eq 0 ]
|
||||
run notation list --plain-http localhost:8080/annotations:latest
|
||||
run notation list --insecure-registry localhost:8080/annotations:latest
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "sign/verify with notation( NOTATION_EXPERIMENTAL=1 and --allow-referrers-api )" {
|
||||
run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:8080/v2/_zot/ext/search
|
||||
[ "$status" -eq 0 ]
|
||||
[ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run notation cert generate-test "notation-sign-test-experimental"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
local trust_policy_file=${HOME}/.config/notation/trustpolicy.json
|
||||
|
||||
cat >${trust_policy_file} <<EOF
|
||||
{
|
||||
"version": "1.0",
|
||||
"trustPolicies": [
|
||||
{
|
||||
"name": "notation-sign-test-experimental",
|
||||
"registryScopes": [ "*" ],
|
||||
"signatureVerification": {
|
||||
"level" : "strict"
|
||||
},
|
||||
"trustStores": [ "ca:notation-sign-test-experimental" ],
|
||||
"trustedIdentities": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
export NOTATION_EXPERIMENTAL=1
|
||||
run notation sign --allow-referrers-api --key "notation-sign-test-experimental" --insecure-registry localhost:8080/annotations:latest
|
||||
[ "$status" -eq 0 ]
|
||||
run notation verify --allow-referrers-api --insecure-registry localhost:8080/annotations:latest
|
||||
[ "$status" -eq 0 ]
|
||||
run notation list --allow-referrers-api --insecure-registry localhost:8080/annotations:latest
|
||||
[ "$status" -eq 0 ]
|
||||
unset NOTATION_EXPERIMENTAL
|
||||
}
|
||||
|
|
|
@ -291,11 +291,11 @@ function teardown_file() {
|
|||
}
|
||||
EOF
|
||||
|
||||
run notation sign --key "notation-sign-sync-test" --plain-http localhost:9000/golang:1.20
|
||||
run notation sign --key "notation-sign-sync-test" --insecure-registry localhost:9000/golang:1.20
|
||||
[ "$status" -eq 0 ]
|
||||
run notation verify --plain-http localhost:9000/golang:1.20
|
||||
run notation verify --insecure-registry localhost:9000/golang:1.20
|
||||
[ "$status" -eq 0 ]
|
||||
run notation list --plain-http localhost:9000/golang:1.20
|
||||
run notation list --insecure-registry localhost:9000/golang:1.20
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,7 @@ EOF
|
|||
# wait for signatures to be copied
|
||||
run sleep 15s
|
||||
|
||||
run notation verify --plain-http localhost:8081/golang:1.20
|
||||
run notation verify --insecure-registry localhost:8081/golang:1.20
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-sync-test.pub localhost:8081/golang:1.20
|
||||
|
@ -311,7 +311,7 @@ EOF
|
|||
}
|
||||
|
||||
@test "sync signatures ondemand" {
|
||||
run notation verify --plain-http localhost:8082/golang:1.20
|
||||
run notation verify --insecure-registry localhost:8082/golang:1.20
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-sync-test.pub localhost:8082/golang:1.20
|
||||
|
|
Loading…
Reference in a new issue