mirror of
https://github.com/project-zot/zot.git
synced 2025-03-11 02:17:43 -05:00
fix(gc): fix cleaning deduped blobs because they have the modTime of the original blobs, fixed by updating the modTime when hard linking the blobs. fix(gc): failing to parse rootDir at zot startup when using s3 storage because there are no files under rootDir and we can not create empty dirs on s3, fixed by creating an empty file under rootDir. Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
300 lines
8.1 KiB
Go
300 lines
8.1 KiB
Go
//go:build scrub
|
|
// +build scrub
|
|
|
|
package scrub_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"testing"
|
|
"time"
|
|
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
|
"zotregistry.io/zot/pkg/api"
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
extconf "zotregistry.io/zot/pkg/extensions/config"
|
|
"zotregistry.io/zot/pkg/extensions/monitoring"
|
|
"zotregistry.io/zot/pkg/extensions/scrub"
|
|
"zotregistry.io/zot/pkg/log"
|
|
"zotregistry.io/zot/pkg/storage"
|
|
"zotregistry.io/zot/pkg/storage/cache"
|
|
"zotregistry.io/zot/pkg/storage/local"
|
|
"zotregistry.io/zot/pkg/test"
|
|
. "zotregistry.io/zot/pkg/test/image-utils"
|
|
)
|
|
|
|
const (
|
|
repoName = "test"
|
|
)
|
|
|
|
func TestScrubExtension(t *testing.T) {
|
|
Convey("Blobs integrity not affected", t, func(c C) {
|
|
port := test.GetFreePort()
|
|
|
|
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.Remove(logFile.Name()) // clean up
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
|
|
dir := t.TempDir()
|
|
subdir := t.TempDir()
|
|
|
|
conf.Storage.RootDirectory = dir
|
|
conf.Storage.Dedupe = false
|
|
conf.Storage.GC = false
|
|
|
|
substore := config.StorageConfig{RootDirectory: subdir}
|
|
conf.Storage.SubPaths = map[string]config.StorageConfig{"/a": substore}
|
|
conf.Log.Output = logFile.Name()
|
|
trueValue := true
|
|
scrubConfig := &extconf.ScrubConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &trueValue},
|
|
Interval: 2,
|
|
}
|
|
conf.Extensions = &extconf.ExtensionConfig{
|
|
Scrub: scrubConfig,
|
|
}
|
|
|
|
ctlr := api.NewController(conf)
|
|
|
|
srcStorageCtlr := test.GetDefaultStoreController(dir, log.NewLogger("debug", ""))
|
|
err = test.WriteImageToFileSystem(CreateDefaultVulnerableImage(), repoName, "0.0.1", srcStorageCtlr)
|
|
So(err, ShouldBeNil)
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
time.Sleep(6 * time.Second)
|
|
|
|
defer cm.StopServer()
|
|
|
|
data, err := os.ReadFile(logFile.Name())
|
|
So(err, ShouldBeNil)
|
|
So(string(data), ShouldContainSubstring, "scrub: blobs/manifest ok")
|
|
})
|
|
|
|
Convey("Blobs integrity affected", t, func(c C) {
|
|
port := test.GetFreePort()
|
|
|
|
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.Remove(logFile.Name()) // clean up
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
|
|
dir := t.TempDir()
|
|
|
|
conf.Storage.RootDirectory = dir
|
|
conf.Storage.Dedupe = false
|
|
conf.Storage.GC = false
|
|
|
|
conf.Log.Output = logFile.Name()
|
|
trueValue := true
|
|
scrubConfig := &extconf.ScrubConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &trueValue},
|
|
Interval: 2,
|
|
}
|
|
conf.Extensions = &extconf.ExtensionConfig{
|
|
Scrub: scrubConfig,
|
|
}
|
|
|
|
ctlr := api.NewController(conf)
|
|
|
|
srcStorageCtlr := test.GetDefaultStoreController(dir, log.NewLogger("debug", ""))
|
|
image := CreateDefaultVulnerableImage()
|
|
err = test.WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := image.ManifestDescriptor.Digest
|
|
|
|
err = os.Remove(path.Join(dir, repoName, "blobs/sha256", manifestDigest.Encoded()))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
time.Sleep(6 * time.Second)
|
|
|
|
defer cm.StopServer()
|
|
|
|
data, err := os.ReadFile(logFile.Name())
|
|
So(err, ShouldBeNil)
|
|
So(string(data), ShouldContainSubstring, "scrub: blobs/manifest affected")
|
|
})
|
|
|
|
Convey("Generator error - not enough permissions to access root directory", t, func(c C) {
|
|
port := test.GetFreePort()
|
|
|
|
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.Remove(logFile.Name()) // clean up
|
|
|
|
conf := config.New()
|
|
conf.HTTP.Port = port
|
|
|
|
dir := t.TempDir()
|
|
|
|
conf.Storage.RootDirectory = dir
|
|
conf.Storage.Dedupe = false
|
|
conf.Storage.GC = false
|
|
|
|
conf.Log.Output = logFile.Name()
|
|
trueValue := true
|
|
scrubConfig := &extconf.ScrubConfig{
|
|
BaseConfig: extconf.BaseConfig{Enable: &trueValue},
|
|
Interval: 2,
|
|
}
|
|
conf.Extensions = &extconf.ExtensionConfig{
|
|
Scrub: scrubConfig,
|
|
}
|
|
|
|
ctlr := api.NewController(conf)
|
|
|
|
srcStorageCtlr := test.GetDefaultStoreController(dir, log.NewLogger("debug", ""))
|
|
image := CreateDefaultVulnerableImage()
|
|
|
|
err = test.WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr)
|
|
So(err, ShouldBeNil)
|
|
|
|
So(os.Chmod(path.Join(dir, repoName), 0o000), ShouldBeNil)
|
|
|
|
cm := test.NewControllerManager(ctlr)
|
|
cm.StartAndWait(port)
|
|
time.Sleep(6 * time.Second)
|
|
|
|
defer cm.StopServer()
|
|
|
|
data, err := os.ReadFile(logFile.Name())
|
|
So(err, ShouldBeNil)
|
|
So(string(data), ShouldContainSubstring, "error while executing generator")
|
|
|
|
So(os.Chmod(path.Join(dir, repoName), 0o755), ShouldBeNil)
|
|
})
|
|
}
|
|
|
|
func TestRunScrubRepo(t *testing.T) {
|
|
Convey("Blobs integrity not affected", t, func(c C) {
|
|
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.Remove(logFile.Name()) // clean up
|
|
|
|
conf := config.New()
|
|
conf.Extensions = &extconf.ExtensionConfig{}
|
|
conf.Extensions.Lint = &extconf.LintConfig{}
|
|
|
|
dir := t.TempDir()
|
|
log := log.NewLogger("debug", logFile.Name())
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
RootDir: dir,
|
|
Name: "cache",
|
|
UseRelPaths: true,
|
|
}, log)
|
|
imgStore := local.NewImageStore(dir, true,
|
|
true, log, metrics, nil, cacheDriver)
|
|
|
|
srcStorageCtlr := test.GetDefaultStoreController(dir, log)
|
|
image := CreateDefaultVulnerableImage()
|
|
|
|
err = test.WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr)
|
|
So(err, ShouldBeNil)
|
|
|
|
err = scrub.RunScrubRepo(context.Background(), imgStore, repoName, log)
|
|
So(err, ShouldBeNil)
|
|
|
|
data, err := os.ReadFile(logFile.Name())
|
|
So(err, ShouldBeNil)
|
|
So(string(data), ShouldContainSubstring, "scrub: blobs/manifest ok")
|
|
})
|
|
|
|
Convey("Blobs integrity affected", t, func(c C) {
|
|
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.Remove(logFile.Name()) // clean up
|
|
|
|
conf := config.New()
|
|
|
|
conf.Extensions = &extconf.ExtensionConfig{}
|
|
conf.Extensions.Lint = &extconf.LintConfig{}
|
|
|
|
dir := t.TempDir()
|
|
log := log.NewLogger("debug", logFile.Name())
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
RootDir: dir,
|
|
Name: "cache",
|
|
UseRelPaths: true,
|
|
}, log)
|
|
imgStore := local.NewImageStore(dir, true,
|
|
true, log, metrics, nil, cacheDriver)
|
|
|
|
srcStorageCtlr := test.GetDefaultStoreController(dir, log)
|
|
image := CreateDefaultVulnerableImage()
|
|
|
|
err = test.WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr)
|
|
So(err, ShouldBeNil)
|
|
|
|
manifestDigest := image.ManifestDescriptor.Digest
|
|
|
|
err = os.Remove(path.Join(dir, repoName, "blobs/sha256", manifestDigest.Encoded()))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = scrub.RunScrubRepo(context.Background(), imgStore, repoName, log)
|
|
So(err, ShouldBeNil)
|
|
|
|
data, err := os.ReadFile(logFile.Name())
|
|
So(err, ShouldBeNil)
|
|
So(string(data), ShouldContainSubstring, "scrub: blobs/manifest affected")
|
|
})
|
|
|
|
Convey("CheckRepo error - not enough permissions to access root directory", t, func(c C) {
|
|
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
|
So(err, ShouldBeNil)
|
|
|
|
defer os.Remove(logFile.Name()) // clean up
|
|
|
|
conf := config.New()
|
|
conf.Extensions = &extconf.ExtensionConfig{}
|
|
conf.Extensions.Lint = &extconf.LintConfig{}
|
|
|
|
dir := t.TempDir()
|
|
log := log.NewLogger("debug", logFile.Name())
|
|
metrics := monitoring.NewMetricsServer(false, log)
|
|
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
|
RootDir: dir,
|
|
Name: "cache",
|
|
UseRelPaths: true,
|
|
}, log)
|
|
imgStore := local.NewImageStore(dir, true, true, log, metrics, nil, cacheDriver)
|
|
|
|
srcStorageCtlr := test.GetDefaultStoreController(dir, log)
|
|
image := CreateDefaultVulnerableImage()
|
|
|
|
err = test.WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr)
|
|
So(err, ShouldBeNil)
|
|
|
|
So(os.Chmod(path.Join(dir, repoName), 0o000), ShouldBeNil)
|
|
|
|
err = scrub.RunScrubRepo(context.Background(), imgStore, repoName, log)
|
|
So(err, ShouldNotBeNil)
|
|
|
|
data, err := os.ReadFile(logFile.Name())
|
|
So(err, ShouldBeNil)
|
|
So(string(data), ShouldContainSubstring,
|
|
fmt.Sprintf("error while running scrub for %s", imgStore.RootDir()))
|
|
So(os.Chmod(path.Join(dir, repoName), 0o755), ShouldBeNil)
|
|
})
|
|
}
|