2022-09-20 13:20:45 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"path/filepath"
|
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
|
|
|
engineconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine"
|
|
|
|
shardconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard"
|
|
|
|
loggerconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/logger"
|
|
|
|
treeconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/tree"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/blobovniczatree"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
2022-09-20 13:20:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// validateConfig validates storage node configuration.
|
|
|
|
func validateConfig(c *config.Config) error {
|
2022-09-28 09:03:14 +00:00
|
|
|
// 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
|
|
|
|
|
2022-09-20 13:20:45 +00:00
|
|
|
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 {
|
|
|
|
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:
|
2023-06-26 11:43:25 +00:00
|
|
|
return fmt.Errorf("unexpected storage type: %s (shard %d)", blobstor[i].Type(), shardNum)
|
2022-09-20 13:20:45 +00:00
|
|
|
}
|
2023-10-31 11:56:55 +00:00
|
|
|
if blobstor[i].Perm()&0o600 != 0o600 {
|
2022-09-20 13:20:45 +00:00
|
|
|
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
|
|
|
|
}
|