package main import ( "fmt" "path/filepath" "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" engineconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine" shardconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine/shard" loggerconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/logger" treeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/tree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/blobovniczatree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" "github.com/nspcc-dev/neofs-node/pkg/util/logger" ) // validateConfig validates storage node configuration. func validateConfig(c *config.Config) error { // logger configuration validation var loggerPrm logger.Prm err := loggerPrm.SetLevelString(loggerconfig.Level(c)) if err != nil { return fmt.Errorf("invalid logger level: %w", err) } // shard configuration validation shardNum := 0 paths := make(map[string]pathDescription) return engineconfig.IterateShards(c, false, func(sc *shardconfig.Config) error { if sc.WriteCache().Enabled() { err := addPath(paths, "writecache", shardNum, sc.WriteCache().Path()) if err != nil { return err } } if err := addPath(paths, "metabase", shardNum, sc.Metabase().Path()); err != nil { return err } treeConfig := treeconfig.Tree(c) if treeConfig.Enabled() { err := addPath(paths, "pilorama", shardNum, sc.Pilorama().Path()) if err != nil { return err } } blobstor := sc.BlobStor().Storages() if len(blobstor) != 2 { // TODO (@fyrcik): remove after #1522 return fmt.Errorf("blobstor section must have 2 components, got: %d", len(blobstor)) } for i := range blobstor { switch blobstor[i].Type() { case fstree.Type, blobovniczatree.Type: default: // FIXME #1764 (@fyrchik): this line is currently unreachable, // because we panic in `sc.BlobStor().Storages()`. return fmt.Errorf("unexpected storage type: %s (shard %d)", blobstor[i].Type(), shardNum) } if blobstor[i].Perm()&0600 != 0600 { return fmt.Errorf("invalid permissions for blobstor component: %s, "+ "expected at least rw- for the owner (shard %d)", blobstor[i].Perm(), shardNum) } if blobstor[i].Path() == "" { return fmt.Errorf("blobstor component path is empty (shard %d)", shardNum) } err := addPath(paths, fmt.Sprintf("blobstor[%d]", i), shardNum, blobstor[i].Path()) if err != nil { return err } } shardNum++ return nil }) } type pathDescription struct { shard int component string } func addPath(paths map[string]pathDescription, component string, shard int, path string) error { if path == "" { return fmt.Errorf("%s at shard %d has empty path", component, shard) } path = filepath.Clean(path) c, ok := paths[path] if ok { return fmt.Errorf("%s at shard %d and %s at shard %d have the same paths: %s", c.component, c.shard, component, shard, path) } paths[path] = pathDescription{shard: shard, component: component} return nil }