2021-10-05 12:12:22 +03:00
package storage_test
import (
"bytes"
2023-09-05 19:48:56 +03:00
"context"
2021-10-05 12:12:22 +03:00
"encoding/json"
2023-09-26 21:02:11 +03:00
"errors"
"fmt"
2021-10-05 12:12:22 +03:00
"path"
"regexp"
"strings"
"testing"
2023-09-26 21:02:11 +03:00
"github.com/docker/distribution/registry/storage/driver"
guuid "github.com/gofrs/uuid"
2021-10-05 12:12:22 +03:00
godigest "github.com/opencontainers/go-digest"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
. "github.com/smartystreets/goconvey/convey"
2022-10-20 19:39:20 +03:00
2024-02-01 06:34:07 +02:00
zerr "zotregistry.dev/zot/errors"
"zotregistry.dev/zot/pkg/extensions/monitoring"
"zotregistry.dev/zot/pkg/log"
"zotregistry.dev/zot/pkg/storage"
"zotregistry.dev/zot/pkg/storage/cache"
common "zotregistry.dev/zot/pkg/storage/common"
"zotregistry.dev/zot/pkg/storage/local"
"zotregistry.dev/zot/pkg/storage/s3"
storageTypes "zotregistry.dev/zot/pkg/storage/types"
. "zotregistry.dev/zot/pkg/test/image-utils"
"zotregistry.dev/zot/pkg/test/mocks"
tskip "zotregistry.dev/zot/pkg/test/skip"
2021-10-05 12:12:22 +03:00
)
const (
repoName = "test"
2022-12-11 02:38:01 +02:00
tag = "1.0"
2021-10-05 12:12:22 +03:00
)
2023-09-26 21:02:11 +03:00
var errUnexpectedError = errors . New ( "unexpected err" )
func TestLocalCheckAllBlobsIntegrity ( t * testing . T ) {
Convey ( "test with local storage" , t , func ( ) {
tdir := t . TempDir ( )
log := log . NewLogger ( "debug" , "" )
metrics := monitoring . NewMetricsServer ( false , log )
cacheDriver , _ := storage . Create ( "boltdb" , cache . BoltDBDriverParameters {
RootDir : tdir ,
Name : "cache" ,
UseRelPaths : true ,
} , log )
driver := local . New ( true )
imgStore := local . NewImageStore ( tdir , true , true , log , metrics , nil , cacheDriver )
RunCheckAllBlobsIntegrityTests ( t , imgStore , driver , log )
} )
}
func TestS3CheckAllBlobsIntegrity ( t * testing . T ) {
2023-10-05 14:34:50 +03:00
tskip . SkipS3 ( t )
2023-09-26 21:02:11 +03:00
Convey ( "test with S3 storage" , t , func ( ) {
uuid , err := guuid . NewV4 ( )
if err != nil {
panic ( err )
}
2021-10-05 12:12:22 +03:00
2023-09-26 21:02:11 +03:00
testDir := path . Join ( "/oci-repo-test" , uuid . String ( ) )
tdir := t . TempDir ( )
log := log . NewLogger ( "debug" , "" )
2021-10-05 12:12:22 +03:00
2023-09-26 21:02:11 +03:00
var store driver . StorageDriver
store , imgStore , _ := createObjectsStore ( testDir , tdir )
defer cleanupStorage ( store , testDir )
2021-10-05 12:12:22 +03:00
2023-09-26 21:02:11 +03:00
driver := s3 . New ( store )
RunCheckAllBlobsIntegrityTests ( t , imgStore , driver , log )
} )
}
func RunCheckAllBlobsIntegrityTests ( //nolint: thelper
t * testing . T , imgStore storageTypes . ImageStore , driver storageTypes . Driver , log log . Logger ,
) {
Convey ( "Scrub only one repo" , func ( ) {
2021-10-05 12:12:22 +03:00
// initialize repo
2022-03-07 16:55:12 +08:00
err := imgStore . InitRepo ( repoName )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
2021-12-13 19:23:31 +00:00
ok := imgStore . DirExists ( path . Join ( imgStore . RootDir ( ) , repoName ) )
2021-10-05 12:12:22 +03:00
So ( ok , ShouldBeTrue )
2021-12-13 19:23:31 +00:00
storeCtlr := storage . StoreController { }
storeCtlr . DefaultStore = imgStore
2023-09-26 21:02:11 +03:00
So ( storeCtlr . GetImageStore ( repoName ) , ShouldResemble , imgStore )
2021-10-05 12:12:22 +03:00
2024-01-17 20:20:07 +02:00
image := CreateRandomImage ( )
2021-10-05 12:12:22 +03:00
2024-01-17 20:20:07 +02:00
err = WriteImageToFileSystem ( image , repoName , tag , storeCtlr )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
2022-10-22 23:46:13 +03:00
2021-10-05 12:12:22 +03:00
Convey ( "Blobs integrity not affected" , func ( ) {
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2021-10-05 12:12:22 +03:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2021-10-05 12:12:22 +03:00
So ( actual , ShouldContainSubstring , "test 1.0 ok" )
2024-01-25 21:12:21 +02:00
err = WriteMultiArchImageToFileSystem ( CreateMultiarchWith ( ) . RandomImages ( 0 ) . Build ( ) , repoName , "2.0" , storeCtlr )
So ( err , ShouldBeNil )
buff = bytes . NewBufferString ( "" )
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test 1.0 ok" )
So ( actual , ShouldContainSubstring , "test 2.0 ok" )
2021-10-05 12:12:22 +03:00
} )
2023-11-24 10:40:10 +02:00
Convey ( "Blobs integrity with context done" , func ( ) {
buff := bytes . NewBufferString ( "" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
cancel ( )
res , err := storeCtlr . CheckAllBlobsIntegrity ( ctx )
res . PrintScrubResults ( buff )
So ( err , ShouldNotBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldNotContainSubstring , "test 1.0 ok" )
} )
2021-10-05 12:12:22 +03:00
Convey ( "Manifest integrity affected" , func ( ) {
// get content of manifest file
2024-01-17 20:20:07 +02:00
content , _ , _ , err := imgStore . GetImageManifest ( repoName , image . ManifestDescriptor . Digest . String ( ) )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
// delete content of manifest file
2024-01-17 20:20:07 +02:00
manifestDig := image . ManifestDescriptor . Digest . Encoded ( )
2022-12-11 02:38:01 +02:00
manifestFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , manifestDig )
2023-09-26 21:02:11 +03:00
err = driver . Delete ( manifestFile )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
defer func ( ) {
// put manifest content back to file
_ , err = driver . WriteFile ( manifestFile , content )
So ( err , ShouldBeNil )
} ( )
2021-10-05 12:12:22 +03:00
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2021-10-05 12:12:22 +03:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2024-01-25 21:12:21 +02:00
So ( actual , ShouldNotContainSubstring , "affected" )
2021-10-05 12:12:22 +03:00
2023-09-01 20:54:39 +03:00
index , err := common . GetIndex ( imgStore , repoName , log )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
So ( len ( index . Manifests ) , ShouldEqual , 1 )
2023-09-26 21:02:11 +03:00
_ , err = driver . WriteFile ( manifestFile , [ ] byte ( "invalid content" ) )
So ( err , ShouldBeNil )
buff = bytes . NewBufferString ( "" )
2022-12-11 02:38:01 +02:00
2023-09-26 21:02:11 +03:00
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
// verify error message
2023-12-08 00:05:02 -08:00
So ( actual , ShouldContainSubstring , fmt . Sprintf ( "test 1.0 affected %s invalid manifest content" , manifestDig ) )
2023-09-26 21:02:11 +03:00
index , err = common . GetIndex ( imgStore , repoName , log )
So ( err , ShouldBeNil )
So ( len ( index . Manifests ) , ShouldEqual , 1 )
2024-01-25 21:12:21 +02:00
manifestDescriptor := index . Manifests [ 0 ]
2023-09-26 21:02:11 +03:00
2024-01-25 21:12:21 +02:00
_ , _ , err = storage . CheckManifestAndConfig ( repoName , manifestDescriptor , [ ] byte ( "invalid content" ) , imgStore )
So ( err , ShouldNotBeNil )
2021-10-05 12:12:22 +03:00
} )
Convey ( "Config integrity affected" , func ( ) {
// get content of config file
2024-01-17 20:20:07 +02:00
content , err := imgStore . GetBlobContent ( repoName , image . ConfigDescriptor . Digest )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
// delete content of config file
2024-01-17 20:20:07 +02:00
configDig := image . ConfigDescriptor . Digest . Encoded ( )
2022-12-11 02:38:01 +02:00
configFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , configDig )
2023-09-26 21:02:11 +03:00
err = driver . Delete ( configFile )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
defer func ( ) {
// put config content back to file
_ , err = driver . WriteFile ( configFile , content )
So ( err , ShouldBeNil )
} ( )
2021-10-05 12:12:22 +03:00
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2021-10-05 12:12:22 +03:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2023-12-08 00:05:02 -08:00
So ( actual , ShouldContainSubstring , fmt . Sprintf ( "test 1.0 affected %s blob not found" , configDig ) )
2021-10-05 12:12:22 +03:00
2023-09-26 21:02:11 +03:00
_ , err = driver . WriteFile ( configFile , [ ] byte ( "invalid content" ) )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
buff = bytes . NewBufferString ( "" )
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2023-12-08 00:05:02 -08:00
So ( actual , ShouldContainSubstring , fmt . Sprintf ( "test 1.0 affected %s invalid server config" , configDig ) )
2021-10-05 12:12:22 +03:00
} )
Convey ( "Layers integrity affected" , func ( ) {
// get content of layer
2024-01-17 20:20:07 +02:00
content , err := imgStore . GetBlobContent ( repoName , image . Manifest . Layers [ 0 ] . Digest )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
// delete content of layer file
2024-01-17 20:20:07 +02:00
layerDig := image . Manifest . Layers [ 0 ] . Digest . Encoded ( )
2022-12-11 02:38:01 +02:00
layerFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , layerDig )
2023-09-26 21:02:11 +03:00
_ , err = driver . WriteFile ( layerFile , [ ] byte ( " " ) )
2021-10-05 12:12:22 +03:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
defer func ( ) {
// put layer content back to file
_ , err = driver . WriteFile ( layerFile , content )
So ( err , ShouldBeNil )
} ( )
2021-10-05 12:12:22 +03:00
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2021-10-05 12:12:22 +03:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2023-12-08 00:05:02 -08:00
So ( actual , ShouldContainSubstring , fmt . Sprintf ( "test 1.0 affected %s bad blob digest" , layerDig ) )
2021-10-05 12:12:22 +03:00
} )
Convey ( "Layer not found" , func ( ) {
2023-09-26 21:02:11 +03:00
// get content of layer
2024-01-25 21:12:21 +02:00
digest := image . Manifest . Layers [ 0 ] . Digest
content , err := imgStore . GetBlobContent ( repoName , digest )
2023-09-26 21:02:11 +03:00
So ( err , ShouldBeNil )
2022-12-11 02:38:01 +02:00
// change layer file permissions
2024-01-17 20:20:07 +02:00
layerDig := image . Manifest . Layers [ 0 ] . Digest . Encoded ( )
2023-09-26 21:02:11 +03:00
repoDir := path . Join ( imgStore . RootDir ( ) , repoName )
2022-12-11 02:38:01 +02:00
layerFile := path . Join ( repoDir , "/blobs/sha256" , layerDig )
2023-09-26 21:02:11 +03:00
err = driver . Delete ( layerFile )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
defer func ( ) {
_ , err := driver . WriteFile ( layerFile , content )
So ( err , ShouldBeNil )
} ( )
2023-09-01 20:54:39 +03:00
index , err := common . GetIndex ( imgStore , repoName , log )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
So ( len ( index . Manifests ) , ShouldEqual , 1 )
2024-01-25 21:12:21 +02:00
// get content of layer
imageRes := storage . CheckLayers ( repoName , tag , [ ] ispec . Descriptor { { Digest : digest } } , imgStore )
2022-12-11 02:38:01 +02:00
So ( imageRes . Status , ShouldEqual , "affected" )
2023-12-08 00:05:02 -08:00
So ( imageRes . Error , ShouldEqual , "blob not found" )
2021-10-05 12:12:22 +03:00
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2021-10-05 12:12:22 +03:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2023-12-08 00:05:02 -08:00
So ( actual , ShouldContainSubstring , fmt . Sprintf ( "test 1.0 affected %s blob not found" , layerDig ) )
2021-10-05 12:12:22 +03:00
} )
2022-12-11 02:38:01 +02:00
Convey ( "Scrub index" , func ( ) {
2024-01-17 20:20:07 +02:00
newImage := CreateRandomImage ( )
newManifestDigest := newImage . ManifestDescriptor . Digest
2022-12-11 02:38:01 +02:00
2024-01-17 20:20:07 +02:00
err = WriteImageToFileSystem ( newImage , repoName , "2.0" , storeCtlr )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
idx , err := common . GetIndex ( imgStore , repoName , log )
So ( err , ShouldBeNil )
2024-01-17 20:20:07 +02:00
manifestDescriptor , ok := common . GetManifestDescByReference ( idx , image . ManifestDescriptor . Digest . String ( ) )
2023-09-26 21:02:11 +03:00
So ( ok , ShouldBeTrue )
2022-12-11 02:38:01 +02:00
var index ispec . Index
index . SchemaVersion = 2
2023-09-26 21:02:11 +03:00
index . Subject = & manifestDescriptor
2022-12-11 02:38:01 +02:00
index . Manifests = [ ] ispec . Descriptor {
{
MediaType : ispec . MediaTypeImageManifest ,
Digest : newManifestDigest ,
2024-01-17 20:20:07 +02:00
Size : newImage . ManifestDescriptor . Size ,
2022-12-11 02:38:01 +02:00
} ,
}
indexBlob , err := json . Marshal ( index )
So ( err , ShouldBeNil )
2023-05-12 19:32:01 +03:00
indexDigest , _ , err := imgStore . PutImageManifest ( repoName , "" , ispec . MediaTypeImageIndex , indexBlob )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2022-12-11 02:38:01 +02:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2022-12-11 02:38:01 +02:00
So ( actual , ShouldContainSubstring , "test 1.0 ok" )
So ( actual , ShouldContainSubstring , "test ok" )
2023-11-24 10:40:10 +02:00
// test scrub context done
buff = bytes . NewBufferString ( "" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
cancel ( )
res , err = storeCtlr . CheckAllBlobsIntegrity ( ctx )
res . PrintScrubResults ( buff )
So ( err , ShouldNotBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldNotContainSubstring , "test 1.0 ok" )
So ( actual , ShouldNotContainSubstring , "test ok" )
2022-12-11 02:38:01 +02:00
// test scrub index - errors
2023-09-26 21:02:11 +03:00
manifestFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , newManifestDigest . Encoded ( ) )
2024-01-25 21:12:21 +02:00
_ , err = driver . WriteFile ( manifestFile , [ ] byte ( "invalid content" ) )
So ( err , ShouldBeNil )
buff = bytes . NewBufferString ( "" )
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test affected" )
// delete content of manifest file
2023-09-26 21:02:11 +03:00
err = driver . Delete ( manifestFile )
So ( err , ShouldBeNil )
buff = bytes . NewBufferString ( "" )
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test affected" )
2022-12-11 02:38:01 +02:00
indexFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , indexDigest . Encoded ( ) )
2023-09-26 21:02:11 +03:00
err = driver . Delete ( indexFile )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
buff = bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2022-12-11 02:38:01 +02:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2024-01-25 21:12:21 +02:00
So ( actual , ShouldContainSubstring , "test 1.0 ok" )
So ( actual , ShouldNotContainSubstring , "test affected" )
2022-12-11 02:38:01 +02:00
2023-09-26 21:02:11 +03:00
index . Manifests [ 0 ] . MediaType = "invalid"
indexBlob , err = json . Marshal ( index )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
_ , err = driver . WriteFile ( indexFile , indexBlob )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
buff = bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2022-12-11 02:38:01 +02:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
2024-01-25 21:12:21 +02:00
_ , _ , err = storage . CheckManifestAndConfig ( repoName , index . Manifests [ 0 ] , [ ] byte { } , imgStore )
2023-09-26 21:02:11 +03:00
So ( err , ShouldNotBeNil )
So ( err , ShouldEqual , zerr . ErrBadManifest )
2022-12-11 02:38:01 +02:00
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test affected" )
_ , err = driver . WriteFile ( indexFile , [ ] byte ( "invalid cotent" ) )
So ( err , ShouldBeNil )
defer func ( ) {
err := driver . Delete ( indexFile )
So ( err , ShouldBeNil )
} ( )
buff = bytes . NewBufferString ( "" )
res , err = storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
str = space . ReplaceAllString ( buff . String ( ) , " " )
actual = strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2022-12-11 02:38:01 +02:00
So ( actual , ShouldContainSubstring , "test affected" )
} )
Convey ( "Manifest not found" , func ( ) {
// delete manifest file
2024-01-17 20:20:07 +02:00
manifestDig := image . ManifestDescriptor . Digest . Encoded ( )
2022-12-11 02:38:01 +02:00
manifestFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , manifestDig )
2023-09-26 21:02:11 +03:00
err = driver . Delete ( manifestFile )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
buff := bytes . NewBufferString ( "" )
2023-09-05 19:48:56 +03:00
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
2022-12-11 02:38:01 +02:00
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
2023-09-26 21:02:11 +03:00
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
2024-01-25 21:12:21 +02:00
So ( actual , ShouldNotContainSubstring , fmt . Sprintf ( "test 1.0 affected %s blob not found" , manifestDig ) )
2022-12-11 02:38:01 +02:00
2023-09-01 20:54:39 +03:00
index , err := common . GetIndex ( imgStore , repoName , log )
2022-12-11 02:38:01 +02:00
So ( err , ShouldBeNil )
2023-09-26 21:02:11 +03:00
So ( len ( index . Manifests ) , ShouldEqual , 1 )
2022-12-11 02:38:01 +02:00
} )
2023-09-26 21:02:11 +03:00
Convey ( "use the result of an already scrubed manifest which is the subject of the current manifest" , func ( ) {
index , err := common . GetIndex ( imgStore , repoName , log )
So ( err , ShouldBeNil )
2024-01-17 20:20:07 +02:00
manifestDescriptor , ok := common . GetManifestDescByReference ( index , image . ManifestDescriptor . Digest . String ( ) )
2023-09-26 21:02:11 +03:00
So ( ok , ShouldBeTrue )
2023-09-27 21:34:48 +03:00
err = WriteImageToFileSystem ( CreateDefaultImageWith ( ) . Subject ( & manifestDescriptor ) . Build ( ) ,
2023-09-26 21:02:11 +03:00
repoName , "0.0.1" , storeCtlr )
So ( err , ShouldBeNil )
buff := bytes . NewBufferString ( "" )
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test 1.0 ok" )
So ( actual , ShouldContainSubstring , "test 0.0.1 ok" )
} )
2024-01-25 21:12:21 +02:00
Convey ( "the subject of the current manifest doesn't exist" , func ( ) {
index , err := common . GetIndex ( imgStore , repoName , log )
So ( err , ShouldBeNil )
manifestDescriptor , ok := common . GetManifestDescByReference ( index , image . ManifestDescriptor . Digest . String ( ) )
So ( ok , ShouldBeTrue )
err = WriteImageToFileSystem ( CreateDefaultImageWith ( ) . Subject ( & manifestDescriptor ) . Build ( ) ,
repoName , "0.0.2" , storeCtlr )
So ( err , ShouldBeNil )
// get content of manifest file
content , _ , _ , err := imgStore . GetImageManifest ( repoName , manifestDescriptor . Digest . String ( ) )
So ( err , ShouldBeNil )
// delete content of manifest file
manifestDig := image . ManifestDescriptor . Digest . Encoded ( )
manifestFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , manifestDig )
err = driver . Delete ( manifestFile )
So ( err , ShouldBeNil )
defer func ( ) {
// put manifest content back to file
_ , err = driver . WriteFile ( manifestFile , content )
So ( err , ShouldBeNil )
} ( )
buff := bytes . NewBufferString ( "" )
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test 0.0.2 affected" )
} )
Convey ( "the subject of the current index doesn't exist" , func ( ) {
index , err := common . GetIndex ( imgStore , repoName , log )
So ( err , ShouldBeNil )
manifestDescriptor , ok := common . GetManifestDescByReference ( index , image . ManifestDescriptor . Digest . String ( ) )
So ( ok , ShouldBeTrue )
err = WriteMultiArchImageToFileSystem ( CreateMultiarchWith ( ) . RandomImages ( 1 ) . Subject ( & manifestDescriptor ) . Build ( ) ,
repoName , "0.0.2" , storeCtlr )
So ( err , ShouldBeNil )
// get content of manifest file
content , _ , _ , err := imgStore . GetImageManifest ( repoName , manifestDescriptor . Digest . String ( ) )
So ( err , ShouldBeNil )
// delete content of manifest file
manifestDig := image . ManifestDescriptor . Digest . Encoded ( )
manifestFile := path . Join ( imgStore . RootDir ( ) , repoName , "/blobs/sha256" , manifestDig )
err = driver . Delete ( manifestFile )
So ( err , ShouldBeNil )
defer func ( ) {
// put manifest content back to file
_ , err = driver . WriteFile ( manifestFile , content )
So ( err , ShouldBeNil )
} ( )
buff := bytes . NewBufferString ( "" )
res , err := storeCtlr . CheckAllBlobsIntegrity ( context . Background ( ) )
res . PrintScrubResults ( buff )
So ( err , ShouldBeNil )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , "test 0.0.2 affected" )
} )
2023-09-26 21:02:11 +03:00
} )
Convey ( "test errors" , func ( ) {
mockedImgStore := mocks . MockedImageStore {
GetRepositoriesFn : func ( ) ( [ ] string , error ) {
return [ ] string { repoName } , nil
} ,
ValidateRepoFn : func ( name string ) ( bool , error ) {
return false , nil
} ,
}
storeController := storage . StoreController { }
storeController . DefaultStore = mockedImgStore
_ , err := storeController . CheckAllBlobsIntegrity ( context . Background ( ) )
So ( err , ShouldNotBeNil )
So ( err , ShouldEqual , zerr . ErrRepoBadLayout )
mockedImgStore = mocks . MockedImageStore {
GetRepositoriesFn : func ( ) ( [ ] string , error ) {
return [ ] string { repoName } , nil
} ,
GetIndexContentFn : func ( repo string ) ( [ ] byte , error ) {
return [ ] byte { } , errUnexpectedError
} ,
}
storeController . DefaultStore = mockedImgStore
_ , err = storeController . CheckAllBlobsIntegrity ( context . Background ( ) )
So ( err , ShouldNotBeNil )
So ( err , ShouldEqual , errUnexpectedError )
2024-01-17 20:20:07 +02:00
manifestDigest := godigest . FromString ( "abcd" )
mockedImgStore = mocks . MockedImageStore {
GetRepositoriesFn : func ( ) ( [ ] string , error ) {
return [ ] string { repoName } , nil
} ,
GetIndexContentFn : func ( repo string ) ( [ ] byte , error ) {
var index ispec . Index
index . SchemaVersion = 2
index . Manifests = [ ] ispec . Descriptor {
{
MediaType : "InvalidMediaType" ,
Digest : manifestDigest ,
Size : int64 ( 100 ) ,
Annotations : map [ string ] string { ispec . AnnotationRefName : "1.0" } ,
} ,
}
return json . Marshal ( index )
} ,
}
storeController . DefaultStore = mockedImgStore
res , err := storeController . CheckAllBlobsIntegrity ( context . Background ( ) )
So ( err , ShouldBeNil )
buff := bytes . NewBufferString ( "" )
res . PrintScrubResults ( buff )
space := regexp . MustCompile ( ` \s+ ` )
str := space . ReplaceAllString ( buff . String ( ) , " " )
actual := strings . TrimSpace ( str )
So ( actual , ShouldContainSubstring , "REPOSITORY TAG STATUS AFFECTED BLOB ERROR" )
So ( actual , ShouldContainSubstring , fmt . Sprintf ( "%s 1.0 affected %s invalid manifest content" ,
repoName , manifestDigest . Encoded ( ) ) )
2021-10-05 12:12:22 +03:00
} )
}