mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 12:28:01 +08:00
refactor(cache): rewrote/refactored cachedb functionality to use interface (#667)
Moved boltdb to a driver implementation for such interface Added CreateCacheDatabaseDriver in controller Fixed default directory creation (boltDB will only create the file, not the dir Added coverage tests Added example config for boltdb Re-added caching on subpaths, rewrote CreateCacheDatabaseDriver Fix tests Made cacheDriver argument mandatory for NewImageStore, added more validation, added defaults Moved cache interface to own file, removed useRelPaths from config Got rid of cache config, refactored Moved cache to own package and folder Renamed + removed cache factory to backend, replaced CloudCache to RemoteCache Moved storage constants back to storage package moved cache interface and factory to storage package, changed remoteCache defaulting Signed-off-by: Catalin Hofnar <catalin.hofnar@gmail.com>
This commit is contained in:
committed by
GitHub
parent
e6539290d4
commit
4170d2adbc
@@ -22,8 +22,9 @@ var (
|
||||
|
||||
type StorageConfig struct {
|
||||
RootDirectory string
|
||||
GC bool
|
||||
Dedupe bool
|
||||
RemoteCache bool
|
||||
GC bool
|
||||
Commit bool
|
||||
GCDelay time.Duration
|
||||
GCInterval time.Duration
|
||||
@@ -95,13 +96,7 @@ type LogConfig struct {
|
||||
}
|
||||
|
||||
type GlobalStorageConfig struct {
|
||||
Dedupe bool
|
||||
GC bool
|
||||
Commit bool
|
||||
GCDelay time.Duration
|
||||
GCInterval time.Duration
|
||||
RootDirectory string
|
||||
StorageDriver map[string]interface{} `mapstructure:",omitempty"`
|
||||
StorageConfig `mapstructure:",squash"`
|
||||
SubPaths map[string]StorageConfig
|
||||
}
|
||||
|
||||
@@ -143,9 +138,11 @@ func New() *Config {
|
||||
Commit: Commit,
|
||||
ReleaseTag: ReleaseTag,
|
||||
BinaryType: BinaryType,
|
||||
Storage: GlobalStorageConfig{GC: true, GCDelay: storage.DefaultGCDelay, Dedupe: true},
|
||||
HTTP: HTTPConfig{Address: "127.0.0.1", Port: "8080", Auth: &AuthConfig{FailDelay: 0}},
|
||||
Log: &LogConfig{Level: "debug"},
|
||||
Storage: GlobalStorageConfig{
|
||||
StorageConfig: StorageConfig{GC: true, GCDelay: storage.DefaultGCDelay, Dedupe: true},
|
||||
},
|
||||
HTTP: HTTPConfig{Address: "127.0.0.1", Port: "8080", Auth: &AuthConfig{FailDelay: 0}},
|
||||
Log: &LogConfig{Level: "debug"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-2
@@ -26,6 +26,8 @@ import (
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/scheduler"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/cache"
|
||||
storageConstants "zotregistry.io/zot/pkg/storage/constants"
|
||||
"zotregistry.io/zot/pkg/storage/local"
|
||||
"zotregistry.io/zot/pkg/storage/s3"
|
||||
)
|
||||
@@ -270,6 +272,7 @@ func (c *Controller) InitImageStore(reloadCtx context.Context) error {
|
||||
defaultStore = local.NewImageStore(c.Config.Storage.RootDirectory,
|
||||
c.Config.Storage.GC, c.Config.Storage.GCDelay,
|
||||
c.Config.Storage.Dedupe, c.Config.Storage.Commit, c.Log, c.Metrics, linter,
|
||||
CreateCacheDatabaseDriver(c.Config.Storage.StorageConfig, c.Log),
|
||||
)
|
||||
} else {
|
||||
storeName := fmt.Sprintf("%v", c.Config.Storage.StorageDriver["name"])
|
||||
@@ -296,7 +299,8 @@ func (c *Controller) InitImageStore(reloadCtx context.Context) error {
|
||||
//nolint: typecheck
|
||||
defaultStore = s3.NewImageStore(rootDir, c.Config.Storage.RootDirectory,
|
||||
c.Config.Storage.GC, c.Config.Storage.GCDelay, c.Config.Storage.Dedupe,
|
||||
c.Config.Storage.Commit, c.Log, c.Metrics, linter, store)
|
||||
c.Config.Storage.Commit, c.Log, c.Metrics, linter, store,
|
||||
CreateCacheDatabaseDriver(c.Config.Storage.StorageConfig, c.Log))
|
||||
}
|
||||
|
||||
c.StoreController.DefaultStore = defaultStore
|
||||
@@ -374,7 +378,8 @@ func (c *Controller) getSubStore(subPaths map[string]config.StorageConfig,
|
||||
// Create a new image store and assign it to imgStoreMap
|
||||
if isUnique {
|
||||
imgStoreMap[storageConfig.RootDirectory] = local.NewImageStore(storageConfig.RootDirectory,
|
||||
storageConfig.GC, storageConfig.GCDelay, storageConfig.Dedupe, storageConfig.Commit, c.Log, c.Metrics, linter)
|
||||
storageConfig.GC, storageConfig.GCDelay, storageConfig.Dedupe,
|
||||
storageConfig.Commit, c.Log, c.Metrics, linter, CreateCacheDatabaseDriver(storageConfig, c.Log))
|
||||
|
||||
subImageStore[route] = imgStoreMap[storageConfig.RootDirectory]
|
||||
}
|
||||
@@ -404,6 +409,7 @@ func (c *Controller) getSubStore(subPaths map[string]config.StorageConfig,
|
||||
subImageStore[route] = s3.NewImageStore(rootDir, storageConfig.RootDirectory,
|
||||
storageConfig.GC, storageConfig.GCDelay,
|
||||
storageConfig.Dedupe, storageConfig.Commit, c.Log, c.Metrics, linter, store,
|
||||
CreateCacheDatabaseDriver(storageConfig, c.Log),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -421,6 +427,29 @@ func compareImageStore(root1, root2 string) bool {
|
||||
return isSameFile
|
||||
}
|
||||
|
||||
func getUseRelPaths(storageConfig *config.StorageConfig) bool {
|
||||
return storageConfig.StorageDriver == nil
|
||||
}
|
||||
|
||||
func CreateCacheDatabaseDriver(storageConfig config.StorageConfig, log log.Logger) cache.Cache {
|
||||
if storageConfig.Dedupe {
|
||||
if !storageConfig.RemoteCache {
|
||||
params := cache.BoltDBDriverParameters{}
|
||||
params.RootDir = storageConfig.RootDirectory
|
||||
params.Name = storageConstants.BoltdbName
|
||||
params.UseRelPaths = getUseRelPaths(&storageConfig)
|
||||
|
||||
driver, _ := storage.Create("boltdb", params, log)
|
||||
|
||||
return driver
|
||||
}
|
||||
// used for tests, dynamodb when it comes
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) LoadNewConfig(reloadCtx context.Context, config *config.Config) {
|
||||
// reload access control config
|
||||
c.Config.AccessControl = config.AccessControl
|
||||
|
||||
@@ -49,6 +49,7 @@ import (
|
||||
"zotregistry.io/zot/pkg/api/config"
|
||||
"zotregistry.io/zot/pkg/api/constants"
|
||||
extconf "zotregistry.io/zot/pkg/extensions/config"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/local"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
@@ -106,6 +107,33 @@ func TestNew(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCreateCacheDatabaseDriver(t *testing.T) {
|
||||
Convey("Test CreateCacheDatabaseDriver", t, func() {
|
||||
log := log.NewLogger("debug", "")
|
||||
|
||||
// fail create db, no perm
|
||||
dir := t.TempDir()
|
||||
conf := config.New()
|
||||
conf.Storage.RootDirectory = dir
|
||||
conf.Storage.Dedupe = true
|
||||
conf.Storage.RemoteCache = false
|
||||
|
||||
err := os.Chmod(dir, 0o000)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
driver := api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
|
||||
So(driver, ShouldBeNil)
|
||||
|
||||
conf.Storage.RemoteCache = true
|
||||
conf.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
driver = api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
|
||||
So(driver, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunAlreadyRunningServer(t *testing.T) {
|
||||
Convey("Run server on unavailable port", t, func() {
|
||||
port := test.GetFreePort()
|
||||
@@ -3180,6 +3208,7 @@ func TestCrossRepoMount(t *testing.T) {
|
||||
panic(err)
|
||||
}
|
||||
ctlr.Config.Storage.RootDirectory = dir
|
||||
ctlr.Config.Storage.RemoteCache = false
|
||||
|
||||
go startServer(ctlr)
|
||||
defer stopServer(ctlr)
|
||||
@@ -5746,6 +5775,7 @@ func TestInjectTooManyOpenFiles(t *testing.T) {
|
||||
ctlr := api.NewController(conf)
|
||||
dir := t.TempDir()
|
||||
ctlr.Config.Storage.RootDirectory = dir
|
||||
conf.Storage.RemoteCache = false
|
||||
|
||||
go startServer(ctlr)
|
||||
defer stopServer(ctlr)
|
||||
@@ -5981,6 +6011,7 @@ func TestPeriodicGC(t *testing.T) {
|
||||
baseURL := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
conf.Storage.RemoteCache = false
|
||||
|
||||
logFile, err := os.CreateTemp("", "zot-log*.txt")
|
||||
So(err, ShouldBeNil)
|
||||
@@ -6032,7 +6063,7 @@ func TestPeriodicGC(t *testing.T) {
|
||||
|
||||
subPaths := make(map[string]config.StorageConfig)
|
||||
|
||||
subPaths["/a"] = config.StorageConfig{RootDirectory: subDir, GC: true, GCDelay: 1 * time.Second, GCInterval: 24 * time.Hour} //nolint:lll // gofumpt conflicts with lll
|
||||
subPaths["/a"] = config.StorageConfig{RootDirectory: subDir, GC: true, GCDelay: 1 * time.Second, GCInterval: 24 * time.Hour, RemoteCache: false} //nolint:lll // gofumpt conflicts with lll
|
||||
|
||||
ctlr.Config.Storage.SubPaths = subPaths
|
||||
ctlr.Config.Storage.RootDirectory = dir
|
||||
@@ -6045,10 +6076,10 @@ func TestPeriodicGC(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
// periodic GC is not enabled for default store
|
||||
So(string(data), ShouldContainSubstring,
|
||||
"\"GCDelay\":3600000000000,\"GCInterval\":0,\"RootDirectory\":\""+dir+"\"")
|
||||
"\"GCDelay\":3600000000000,\"GCInterval\":0,\"")
|
||||
// periodic GC is enabled for sub store
|
||||
So(string(data), ShouldContainSubstring,
|
||||
fmt.Sprintf("\"SubPaths\":{\"/a\":{\"RootDirectory\":\"%s\",\"GC\":true,\"Dedupe\":false,\"Commit\":false,\"GCDelay\":1000000000,\"GCInterval\":86400000000000", subDir)) //nolint:lll // gofumpt conflicts with lll
|
||||
fmt.Sprintf("\"SubPaths\":{\"/a\":{\"RootDirectory\":\"%s\",\"Dedupe\":false,\"RemoteCache\":false,\"GC\":true,\"Commit\":false,\"GCDelay\":1000000000,\"GCInterval\":86400000000000", subDir)) //nolint:lll // gofumpt conflicts with lll
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user