Skip to content

Commit 212c28b

Browse files
refactor(storage): move storage init from controller to storagefactory
Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
1 parent 3510ef0 commit 212c28b

29 files changed

Lines changed: 639 additions & 565 deletions

pkg/api/config/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
distspec "github.com/opencontainers/distribution-spec/specs-go"
99

1010
extconf "zotregistry.io/zot/pkg/extensions/config"
11-
"zotregistry.io/zot/pkg/storage"
11+
storageConstants "zotregistry.io/zot/pkg/storage/constants"
1212
)
1313

1414
var (
@@ -147,7 +147,7 @@ func New() *Config {
147147
ReleaseTag: ReleaseTag,
148148
BinaryType: BinaryType,
149149
Storage: GlobalStorageConfig{
150-
StorageConfig: StorageConfig{GC: true, GCDelay: storage.DefaultGCDelay, Dedupe: true},
150+
StorageConfig: StorageConfig{GC: true, GCDelay: storageConstants.DefaultGCDelay, Dedupe: true},
151151
},
152152
HTTP: HTTPConfig{Address: "127.0.0.1", Port: "8080", Auth: &AuthConfig{FailDelay: 0}},
153153
Log: &LogConfig{Level: "debug"},

pkg/api/controller.go

Lines changed: 7 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"syscall"
1515
"time"
1616

17-
"github.com/docker/distribution/registry/storage/driver/factory"
1817
"github.com/gorilla/handlers"
1918
"github.com/gorilla/mux"
2019

@@ -27,10 +26,7 @@ import (
2726
"zotregistry.io/zot/pkg/meta/repodb/repodbfactory"
2827
"zotregistry.io/zot/pkg/scheduler"
2928
"zotregistry.io/zot/pkg/storage"
30-
"zotregistry.io/zot/pkg/storage/cache"
31-
"zotregistry.io/zot/pkg/storage/constants"
32-
"zotregistry.io/zot/pkg/storage/local"
33-
"zotregistry.io/zot/pkg/storage/s3"
29+
"zotregistry.io/zot/pkg/storage/storagefactory"
3430
)
3531

3632
const (
@@ -248,7 +244,8 @@ func (c *Controller) Init(reloadCtx context.Context) error {
248244

249245
c.Metrics = monitoring.NewMetricsServer(enabled, c.Log)
250246

251-
if err := c.InitImageStore(reloadCtx); err != nil {
247+
//nolint: contextcheck
248+
if err := c.InitImageStore(); err != nil {
252249
return err
253250
}
254251

@@ -268,234 +265,15 @@ func (c *Controller) InitCVEInfo() {
268265
}
269266
}
270267

271-
func (c *Controller) InitImageStore(ctx context.Context) error {
272-
c.StoreController = storage.StoreController{}
273-
268+
func (c *Controller) InitImageStore() error {
274269
linter := ext.GetLinter(c.Config, c.Log)
275270

276-
if c.Config.Storage.RootDirectory != "" {
277-
// no need to validate hard links work on s3
278-
if c.Config.Storage.Dedupe && c.Config.Storage.StorageDriver == nil {
279-
err := local.ValidateHardLink(c.Config.Storage.RootDirectory)
280-
if err != nil {
281-
c.Log.Warn().Msg("input storage root directory filesystem does not supports hardlinking," +
282-
"disabling dedupe functionality")
283-
284-
c.Config.Storage.Dedupe = false
285-
}
286-
}
287-
288-
var defaultStore storage.ImageStore
289-
if c.Config.Storage.StorageDriver == nil {
290-
// false positive lint - linter does not implement Lint method
291-
//nolint:typecheck,contextcheck
292-
defaultStore = local.NewImageStore(c.Config.Storage.RootDirectory,
293-
c.Config.Storage.GC, c.Config.Storage.GCDelay,
294-
c.Config.Storage.Dedupe, c.Config.Storage.Commit, c.Log, c.Metrics, linter,
295-
CreateCacheDatabaseDriver(c.Config.Storage.StorageConfig, c.Log),
296-
)
297-
} else {
298-
storeName := fmt.Sprintf("%v", c.Config.Storage.StorageDriver["name"])
299-
if storeName != storage.S3StorageDriverName {
300-
c.Log.Fatal().Err(errors.ErrBadConfig).Msgf("unsupported storage driver: %s",
301-
c.Config.Storage.StorageDriver["name"])
302-
}
303-
// Init a Storager from connection string.
304-
store, err := factory.Create(storeName, c.Config.Storage.StorageDriver)
305-
if err != nil {
306-
c.Log.Error().Err(err).Str("rootDir", c.Config.Storage.RootDirectory).Msg("unable to create s3 service")
307-
308-
return err
309-
}
310-
311-
/* in the case of s3 c.Config.Storage.RootDirectory is used for caching blobs locally and
312-
c.Config.Storage.StorageDriver["rootdirectory"] is the actual rootDir in s3 */
313-
rootDir := "/"
314-
if c.Config.Storage.StorageDriver["rootdirectory"] != nil {
315-
rootDir = fmt.Sprintf("%v", c.Config.Storage.StorageDriver["rootdirectory"])
316-
}
317-
318-
// false positive lint - linter does not implement Lint method
319-
//nolint: typecheck,contextcheck
320-
defaultStore = s3.NewImageStore(rootDir, c.Config.Storage.RootDirectory,
321-
c.Config.Storage.GC, c.Config.Storage.GCDelay, c.Config.Storage.Dedupe,
322-
c.Config.Storage.Commit, c.Log, c.Metrics, linter, store,
323-
CreateCacheDatabaseDriver(c.Config.Storage.StorageConfig, c.Log))
324-
}
325-
326-
c.StoreController.DefaultStore = defaultStore
327-
} else {
328-
// we can't proceed without global storage
329-
c.Log.Error().Err(errors.ErrImgStoreNotFound).Msg("controller: no storage config provided")
330-
331-
return errors.ErrImgStoreNotFound
332-
}
333-
334-
if c.Config.Storage.SubPaths != nil {
335-
if len(c.Config.Storage.SubPaths) > 0 {
336-
subPaths := c.Config.Storage.SubPaths
337-
338-
//nolint: contextcheck
339-
subImageStore, err := c.getSubStore(subPaths, linter)
340-
if err != nil {
341-
c.Log.Error().Err(err).Msg("controller: error getting sub image store")
342-
343-
return err
344-
}
345-
346-
c.StoreController.SubStore = subImageStore
347-
}
348-
}
349-
350-
return nil
351-
}
352-
353-
func (c *Controller) getSubStore(subPaths map[string]config.StorageConfig,
354-
linter storage.Lint,
355-
) (map[string]storage.ImageStore, error) {
356-
imgStoreMap := make(map[string]storage.ImageStore, 0)
357-
358-
subImageStore := make(map[string]storage.ImageStore)
359-
360-
// creating image store per subpaths
361-
for route, storageConfig := range subPaths {
362-
// no need to validate hard links work on s3
363-
if storageConfig.Dedupe && storageConfig.StorageDriver == nil {
364-
err := local.ValidateHardLink(storageConfig.RootDirectory)
365-
if err != nil {
366-
c.Log.Warn().Msg("input storage root directory filesystem does not supports hardlinking, " +
367-
"disabling dedupe functionality")
368-
369-
storageConfig.Dedupe = false
370-
}
371-
}
372-
373-
if storageConfig.StorageDriver == nil {
374-
// Compare if subpath root dir is same as default root dir
375-
isSame, _ := config.SameFile(c.Config.Storage.RootDirectory, storageConfig.RootDirectory)
376-
377-
if isSame {
378-
c.Log.Error().Err(errors.ErrBadConfig).Msg("sub path storage directory is same as root directory")
379-
380-
return nil, errors.ErrBadConfig
381-
}
382-
383-
isUnique := true
384-
385-
// Compare subpath unique files
386-
for file := range imgStoreMap {
387-
// We already have image storage for this file
388-
if compareImageStore(file, storageConfig.RootDirectory) {
389-
subImageStore[route] = imgStoreMap[file]
390-
391-
isUnique = true
392-
}
393-
}
394-
395-
// subpath root directory is unique
396-
// add it to uniqueSubFiles
397-
// Create a new image store and assign it to imgStoreMap
398-
if isUnique {
399-
imgStoreMap[storageConfig.RootDirectory] = local.NewImageStore(storageConfig.RootDirectory,
400-
storageConfig.GC, storageConfig.GCDelay, storageConfig.Dedupe,
401-
storageConfig.Commit, c.Log, c.Metrics, linter, CreateCacheDatabaseDriver(storageConfig, c.Log))
402-
403-
subImageStore[route] = imgStoreMap[storageConfig.RootDirectory]
404-
}
405-
} else {
406-
storeName := fmt.Sprintf("%v", storageConfig.StorageDriver["name"])
407-
if storeName != storage.S3StorageDriverName {
408-
c.Log.Fatal().Err(errors.ErrBadConfig).Msgf("unsupported storage driver: %s", storageConfig.StorageDriver["name"])
409-
}
410-
411-
// Init a Storager from connection string.
412-
store, err := factory.Create(storeName, storageConfig.StorageDriver)
413-
if err != nil {
414-
c.Log.Error().Err(err).Str("rootDir", storageConfig.RootDirectory).Msg("Unable to create s3 service")
415-
416-
return nil, err
417-
}
418-
419-
/* in the case of s3 c.Config.Storage.RootDirectory is used for caching blobs locally and
420-
c.Config.Storage.StorageDriver["rootdirectory"] is the actual rootDir in s3 */
421-
rootDir := "/"
422-
if c.Config.Storage.StorageDriver["rootdirectory"] != nil {
423-
rootDir = fmt.Sprintf("%v", c.Config.Storage.StorageDriver["rootdirectory"])
424-
}
425-
426-
// false positive lint - linter does not implement Lint method
427-
//nolint: typecheck
428-
subImageStore[route] = s3.NewImageStore(rootDir, storageConfig.RootDirectory,
429-
storageConfig.GC, storageConfig.GCDelay,
430-
storageConfig.Dedupe, storageConfig.Commit, c.Log, c.Metrics, linter, store,
431-
CreateCacheDatabaseDriver(storageConfig, c.Log),
432-
)
433-
}
434-
}
435-
436-
return subImageStore, nil
437-
}
438-
439-
func compareImageStore(root1, root2 string) bool {
440-
isSameFile, err := config.SameFile(root1, root2)
441-
// This error is path error that means either of root directory doesn't exist, in that case do string match
271+
storeController, err := storagefactory.New(c.Config, linter, c.Metrics, c.Log)
442272
if err != nil {
443-
return strings.EqualFold(root1, root2)
273+
return err
444274
}
445275

446-
return isSameFile
447-
}
448-
449-
func getUseRelPaths(storageConfig *config.StorageConfig) bool {
450-
return storageConfig.StorageDriver == nil
451-
}
452-
453-
func CreateCacheDatabaseDriver(storageConfig config.StorageConfig, log log.Logger) cache.Cache {
454-
if storageConfig.Dedupe || storageConfig.StorageDriver != nil {
455-
if !storageConfig.RemoteCache {
456-
params := cache.BoltDBDriverParameters{}
457-
params.RootDir = storageConfig.RootDirectory
458-
params.Name = constants.BoltdbName
459-
460-
if storageConfig.StorageDriver != nil {
461-
params.Name = s3.CacheDBName
462-
}
463-
464-
params.UseRelPaths = getUseRelPaths(&storageConfig)
465-
466-
driver, _ := storage.Create("boltdb", params, log)
467-
468-
return driver
469-
}
470-
471-
// remote cache
472-
if storageConfig.CacheDriver != nil {
473-
name, ok := storageConfig.CacheDriver["name"].(string)
474-
if !ok {
475-
log.Warn().Msg("remote cache driver name missing!")
476-
477-
return nil
478-
}
479-
480-
if name != constants.DynamoDBDriverName {
481-
log.Warn().Str("driver", name).Msg("remote cache driver unsupported!")
482-
483-
return nil
484-
}
485-
486-
// dynamodb
487-
dynamoParams := cache.DynamoDBDriverParameters{}
488-
dynamoParams.Endpoint, _ = storageConfig.CacheDriver["endpoint"].(string)
489-
dynamoParams.Region, _ = storageConfig.CacheDriver["region"].(string)
490-
dynamoParams.TableName, _ = storageConfig.CacheDriver["cachetablename"].(string)
491-
492-
driver, _ := storage.Create("dynamodb", dynamoParams, log)
493-
494-
return driver
495-
}
496-
497-
return nil
498-
}
276+
c.StoreController = storeController
499277

500278
return nil
501279
}

pkg/api/controller_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,13 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
122122
panic(err)
123123
}
124124

125-
driver := api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
125+
driver := storage.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
126126
So(driver, ShouldBeNil)
127127

128128
conf.Storage.RemoteCache = true
129129
conf.Storage.RootDirectory = t.TempDir()
130130

131-
driver = api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
131+
driver = storage.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
132132
So(driver, ShouldBeNil)
133133
})
134134
skipDynamo(t)
@@ -161,7 +161,7 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
161161
"versionTablename": "Version",
162162
}
163163

164-
driver := api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
164+
driver := storage.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
165165
So(driver, ShouldNotBeNil)
166166

167167
// negative test cases
@@ -176,7 +176,7 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
176176
"versionTablename": "Version",
177177
}
178178

179-
driver = api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
179+
driver = storage.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
180180
So(driver, ShouldBeNil)
181181

182182
conf.Storage.CacheDriver = map[string]interface{}{
@@ -190,7 +190,7 @@ func TestCreateCacheDatabaseDriver(t *testing.T) {
190190
"versionTablename": "Version",
191191
}
192192

193-
driver = api.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
193+
driver = storage.CreateCacheDatabaseDriver(conf.Storage.StorageConfig, log)
194194
So(driver, ShouldBeNil)
195195
})
196196
}

pkg/api/routes.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
zreg "zotregistry.io/zot/pkg/regexp"
4040
localCtx "zotregistry.io/zot/pkg/requestcontext"
4141
"zotregistry.io/zot/pkg/storage"
42+
"zotregistry.io/zot/pkg/storage/common"
4243
"zotregistry.io/zot/pkg/test" //nolint:goimports
4344
)
4445

@@ -550,7 +551,7 @@ func (rh *RouteHandler) UpdateManifest(response http.ResponseWriter, request *ht
550551
}
551552

552553
mediaType := request.Header.Get("Content-Type")
553-
if !storage.IsSupportedMediaType(mediaType) {
554+
if !common.IsSupportedMediaType(mediaType) {
554555
// response.WriteHeader(http.StatusUnsupportedMediaType)
555556
WriteJSON(response, http.StatusUnsupportedMediaType,
556557
NewErrorList(NewError(MANIFEST_INVALID, map[string]string{"mediaType": mediaType})))

pkg/cli/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func newScrubCmd(conf *config.Config) *cobra.Command {
116116
ctlr := api.NewController(conf)
117117
ctlr.Metrics = monitoring.NewMetricsServer(false, ctlr.Log)
118118

119-
if err := ctlr.InitImageStore(context.Background()); err != nil {
119+
if err := ctlr.InitImageStore(); err != nil {
120120
panic(err)
121121
}
122122

@@ -566,7 +566,7 @@ func applyDefaultValues(config *config.Config, viperInstance *viper.Viper) {
566566

567567
// if gc is enabled and gcDelay is not set, it is set to default value
568568
if storageConfig.GC && !viperInstance.IsSet("storage::subpaths::"+name+"::gcdelay") {
569-
storageConfig.GCDelay = storage.DefaultGCDelay
569+
storageConfig.GCDelay = storageConstants.DefaultGCDelay
570570
config.Storage.SubPaths[name] = storageConfig
571571
}
572572
}

pkg/cli/root_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"zotregistry.io/zot/pkg/api"
1414
"zotregistry.io/zot/pkg/api/config"
1515
"zotregistry.io/zot/pkg/cli"
16-
"zotregistry.io/zot/pkg/storage"
1716
storageConstants "zotregistry.io/zot/pkg/storage/constants"
1817
"zotregistry.io/zot/pkg/storage/s3"
1918
. "zotregistry.io/zot/pkg/test"
@@ -1133,10 +1132,10 @@ func TestGC(t *testing.T) {
11331132
config := config.New()
11341133
err := cli.LoadConfiguration(config, "../../examples/config-multiple.json")
11351134
So(err, ShouldBeNil)
1136-
So(config.Storage.GCDelay, ShouldEqual, storage.DefaultGCDelay)
1135+
So(config.Storage.GCDelay, ShouldEqual, storageConstants.DefaultGCDelay)
11371136
err = cli.LoadConfiguration(config, "../../examples/config-gc.json")
11381137
So(err, ShouldBeNil)
1139-
So(config.Storage.GCDelay, ShouldNotEqual, storage.DefaultGCDelay)
1138+
So(config.Storage.GCDelay, ShouldNotEqual, storageConstants.DefaultGCDelay)
11401139
err = cli.LoadConfiguration(config, "../../examples/config-gc-periodic.json")
11411140
So(err, ShouldBeNil)
11421141
})

0 commit comments

Comments
 (0)