frostfs-node/cmd/frostfs-node/validate.go

106 lines
3.1 KiB
Go

package main
import (
"fmt"
"path/filepath"
"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"
)
// 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)
}
err = loggerPrm.SetDestination(loggerconfig.Destination(c))
if err != nil {
return fmt.Errorf("invalid logger destination: %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 {
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:
return fmt.Errorf("unexpected storage type: %s (shard %d)", blobstor[i].Type(), shardNum)
}
if blobstor[i].Perm()&0o600 != 0o600 {
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
}