mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 04:17:55 +08:00
image level lint: enforce manifest mandatory annotations
closes #536 Signed-off-by: Lisca Ana-Roberta <ana.kagome@yahoo.com>
This commit is contained in:
committed by
Andrei Aaron
parent
3d72dad507
commit
87fc941b3c
+27
-3
@@ -11,6 +11,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -23,6 +24,7 @@ import (
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
artifactspec "github.com/oras-project/artifacts-spec/specs-go/v1"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/sigstore/cosign/pkg/oci/remote"
|
||||
zerr "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
zlog "zotregistry.io/zot/pkg/log"
|
||||
@@ -50,6 +52,7 @@ type ObjectStorage struct {
|
||||
metrics monitoring.MetricServer
|
||||
cache *storage.Cache
|
||||
dedupe bool
|
||||
linter storage.Lint
|
||||
}
|
||||
|
||||
func (is *ObjectStorage) RootDir() string {
|
||||
@@ -67,7 +70,7 @@ func (is *ObjectStorage) DirExists(d string) bool {
|
||||
// NewObjectStorage returns a new image store backed by cloud storages.
|
||||
// see https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers
|
||||
func NewImageStore(rootDir string, cacheDir string, gc bool, gcDelay time.Duration, dedupe, commit bool,
|
||||
log zlog.Logger, metrics monitoring.MetricServer,
|
||||
log zlog.Logger, metrics monitoring.MetricServer, linter storage.Lint,
|
||||
store driver.StorageDriver,
|
||||
) storage.ImageStore {
|
||||
imgStore := &ObjectStorage{
|
||||
@@ -79,6 +82,7 @@ func NewImageStore(rootDir string, cacheDir string, gc bool, gcDelay time.Durati
|
||||
multiPartUploads: sync.Map{},
|
||||
metrics: metrics,
|
||||
dedupe: dedupe,
|
||||
linter: linter,
|
||||
}
|
||||
|
||||
cachePath := path.Join(cacheDir, CacheDBName+storage.DBExtensionName)
|
||||
@@ -395,8 +399,8 @@ func (is *ObjectStorage) GetImageManifest(repo, reference string) ([]byte, strin
|
||||
|
||||
// PutImageManifest adds an image manifest to the repository.
|
||||
func (is *ObjectStorage) PutImageManifest(repo, reference, mediaType string,
|
||||
body []byte,
|
||||
) (string, error) {
|
||||
body []byte) (string, error,
|
||||
) {
|
||||
if err := is.InitRepo(repo); err != nil {
|
||||
is.log.Debug().Err(err).Msg("init repo")
|
||||
|
||||
@@ -549,6 +553,26 @@ func (is *ObjectStorage) PutImageManifest(repo, reference, mediaType string,
|
||||
return "", err
|
||||
}
|
||||
|
||||
// apply linter only on images, not signatures
|
||||
if is.linter != nil {
|
||||
if mediaType == ispec.MediaTypeImageManifest &&
|
||||
// check that image manifest is not cosign signature
|
||||
!strings.HasPrefix(reference, "sha256-") &&
|
||||
!strings.HasSuffix(reference, remote.SignatureTagSuffix) {
|
||||
// lint new index with new manifest before writing to disk
|
||||
pass, err := is.linter.Lint(repo, mDigest, is)
|
||||
if err != nil {
|
||||
is.log.Error().Err(err).Msg("linter error")
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !pass {
|
||||
return "", zerr.ErrImageLintAnnotations
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = is.store.PutContent(context.Background(), indexPath, buf); err != nil {
|
||||
is.log.Error().Err(err).Str("file", manifestPath).Msg("unable to write")
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ func skipIt(t *testing.T) {
|
||||
func createMockStorage(rootDir string, cacheDir string, dedupe bool, store driver.StorageDriver) storage.ImageStore {
|
||||
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
il := s3.NewImageStore(rootDir, cacheDir, false, storage.DefaultGCDelay, dedupe, false, log, metrics, store)
|
||||
il := s3.NewImageStore(rootDir, cacheDir, false, storage.DefaultGCDelay,
|
||||
dedupe, false, log, metrics, nil, store,
|
||||
)
|
||||
|
||||
return il
|
||||
}
|
||||
@@ -95,7 +97,8 @@ func createObjectsStore(rootDir string, cacheDir string, dedupe bool) (
|
||||
|
||||
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
il := s3.NewImageStore(rootDir, cacheDir, false, storage.DefaultGCDelay, dedupe, false, log, metrics, store)
|
||||
il := s3.NewImageStore(rootDir, cacheDir, false, storage.DefaultGCDelay,
|
||||
dedupe, false, log, metrics, nil, store)
|
||||
|
||||
return store, il, err
|
||||
}
|
||||
@@ -894,7 +897,8 @@ func TestS3Dedupe(t *testing.T) {
|
||||
manifestBuf, err := json.Marshal(manifest)
|
||||
So(err, ShouldBeNil)
|
||||
digest = godigest.FromBytes(manifestBuf)
|
||||
_, err = imgStore.PutImageManifest("dedupe1", digest.String(), ispec.MediaTypeImageManifest, manifestBuf)
|
||||
_, err = imgStore.PutImageManifest("dedupe1", digest.String(),
|
||||
ispec.MediaTypeImageManifest, manifestBuf)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, _, _, err = imgStore.GetImageManifest("dedupe1", digest.String())
|
||||
@@ -956,7 +960,8 @@ func TestS3Dedupe(t *testing.T) {
|
||||
manifestBuf, err = json.Marshal(manifest)
|
||||
So(err, ShouldBeNil)
|
||||
digest = godigest.FromBytes(manifestBuf)
|
||||
_, err = imgStore.PutImageManifest("dedupe2", "1.0", ispec.MediaTypeImageManifest, manifestBuf)
|
||||
_, err = imgStore.PutImageManifest("dedupe2", "1.0", ispec.MediaTypeImageManifest,
|
||||
manifestBuf)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, _, _, err = imgStore.GetImageManifest("dedupe2", digest.String())
|
||||
@@ -1078,7 +1083,8 @@ func TestS3Dedupe(t *testing.T) {
|
||||
manifestBuf, err = json.Marshal(manifest)
|
||||
So(err, ShouldBeNil)
|
||||
digest = godigest.FromBytes(manifestBuf)
|
||||
_, err = imgStore.PutImageManifest("dedupe3", "1.0", ispec.MediaTypeImageManifest, manifestBuf)
|
||||
_, err = imgStore.PutImageManifest("dedupe3", "1.0", ispec.MediaTypeImageManifest,
|
||||
manifestBuf)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, _, _, err = imgStore.GetImageManifest("dedupe3", digest.String())
|
||||
|
||||
Reference in New Issue
Block a user