diff --git a/cmd/neofs-cli/modules/control/shards_list.go b/cmd/neofs-cli/modules/control/shards_list.go index 4d4eef63a..879b712b0 100644 --- a/cmd/neofs-cli/modules/control/shards_list.go +++ b/cmd/neofs-cli/modules/control/shards_list.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "strings" "github.com/mr-tron/base58" rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" @@ -65,7 +66,7 @@ func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) { "shard_id": base58.Encode(i.Shard_ID), "mode": shardModeToString(i.GetMode()), "metabase": i.GetMetabasePath(), - "blobstor": i.GetBlobstorPath(), + "blobstor": i.GetBlobstor(), "writecache": i.GetWritecachePath(), "error_count": i.GetErrorCount(), }) @@ -89,9 +90,16 @@ func prettyPrintShards(cmd *cobra.Command, ii []*control.ShardInfo) { return fmt.Sprintf("%s: %s\n", name, path) } + var sb strings.Builder + sb.WriteString("Blobstor:\n") + for j, info := range i.GetBlobstor() { + sb.WriteString(fmt.Sprintf("\tPath %d: %s\n\tType %d: %s\n", + j, info.GetPath(), j, info.GetType())) + } + cmd.Printf("Shard %s:\nMode: %s\n"+ pathPrinter("Metabase", i.GetMetabasePath())+ - pathPrinter("Blobstor", i.GetBlobstorPath())+ + sb.String()+ pathPrinter("Write-cache", i.GetWritecachePath())+ pathPrinter("Pilorama", i.GetPiloramaPath())+ fmt.Sprintf("Error count: %d\n", i.GetErrorCount()), diff --git a/pkg/local_object_storage/blobstor/blobstor.go b/pkg/local_object_storage/blobstor/blobstor.go index 4d8bd94f9..0480db0d2 100644 --- a/pkg/local_object_storage/blobstor/blobstor.go +++ b/pkg/local_object_storage/blobstor/blobstor.go @@ -5,7 +5,6 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/compression" - "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard/mode" "github.com/nspcc-dev/neofs-node/pkg/util/logger" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" @@ -26,7 +25,16 @@ type BlobStor struct { mode mode.Mode } -type Info = fstree.Info +// Info contains information about blobstor. +type Info struct { + SubStorages []SubStorageInfo +} + +// SubStorageInfo contains information about blobstor storage component. +type SubStorageInfo struct { + Type string + Path string +} // Option represents BlobStor's constructor option. type Option func(*cfg) diff --git a/pkg/local_object_storage/blobstor/info.go b/pkg/local_object_storage/blobstor/info.go index 60a143ce1..e3e790ebc 100644 --- a/pkg/local_object_storage/blobstor/info.go +++ b/pkg/local_object_storage/blobstor/info.go @@ -1,13 +1,14 @@ package blobstor -import "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" - // DumpInfo returns information about blob stor. -func (b *BlobStor) DumpInfo() fstree.Info { +func (b *BlobStor) DumpInfo() Info { + sub := make([]SubStorageInfo, len(b.storage)) for i := range b.storage { - if b.storage[i].Storage.Type() == "fstree" { - return b.storage[i].Storage.(*fstree.FSTree).Info - } + sub[i].Path = b.storage[i].Storage.Path() + sub[i].Type = b.storage[i].Storage.Type() + } + + return Info{ + SubStorages: sub, } - return fstree.Info{} } diff --git a/pkg/local_object_storage/engine/error_test.go b/pkg/local_object_storage/engine/error_test.go index 2439d667b..ccbe8c04e 100644 --- a/pkg/local_object_storage/engine/error_test.go +++ b/pkg/local_object_storage/engine/error_test.go @@ -167,8 +167,8 @@ func TestBlobstorFailback(t *testing.T) { checkShardState(t, e, id[0], 0, mode.ReadWrite) require.NoError(t, e.Close()) - p1 := e.shards[id[0].String()].Shard.DumpInfo().BlobStorInfo.RootPath - p2 := e.shards[id[1].String()].Shard.DumpInfo().BlobStorInfo.RootPath + p1 := e.shards[id[0].String()].Shard.DumpInfo().BlobStorInfo.SubStorages[1].Path + p2 := e.shards[id[1].String()].Shard.DumpInfo().BlobStorInfo.SubStorages[1].Path tmp := filepath.Join(dir, "tmp") require.NoError(t, os.Rename(p1, tmp)) require.NoError(t, os.Rename(p2, p1)) diff --git a/pkg/local_object_storage/shard/control_test.go b/pkg/local_object_storage/shard/control_test.go index 01aa3f67f..eb9d2a3ff 100644 --- a/pkg/local_object_storage/shard/control_test.go +++ b/pkg/local_object_storage/shard/control_test.go @@ -82,13 +82,14 @@ func TestShardOpen(t *testing.T) { func TestRefillMetabaseCorrupted(t *testing.T) { dir := t.TempDir() + fsTree := fstree.New( + fstree.WithDirNameLen(2), + fstree.WithPath(filepath.Join(dir, "blob")), + fstree.WithDepth(1)) blobOpts := []blobstor.Option{ blobstor.WithStorages([]blobstor.SubStorage{ { - Storage: fstree.New( - fstree.WithDirNameLen(2), - fstree.WithPath(filepath.Join(dir, "blob")), - fstree.WithDepth(1)), + Storage: fsTree, }, }), } @@ -111,12 +112,7 @@ func TestRefillMetabaseCorrupted(t *testing.T) { require.NoError(t, sh.Close()) addr := object.AddressOf(obj) - fs := fstree.FSTree{ - DirNameLen: 2, - Depth: 1, - Info: sh.blobStor.DumpInfo(), - } - _, err = fs.Put(common.PutPrm{Address: addr, RawData: []byte("not an object")}) + _, err = fsTree.Put(common.PutPrm{Address: addr, RawData: []byte("not an object")}) require.NoError(t, err) sh = New( diff --git a/pkg/services/control/server/list_shards.go b/pkg/services/control/server/list_shards.go index 11a66dcd5..0e21d9028 100644 --- a/pkg/services/control/server/list_shards.go +++ b/pkg/services/control/server/list_shards.go @@ -3,6 +3,7 @@ package control import ( "context" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard/mode" "github.com/nspcc-dev/neofs-node/pkg/services/control" "google.golang.org/grpc/codes" @@ -30,7 +31,7 @@ func (s *Server) ListShards(_ context.Context, req *control.ListShardsRequest) ( si.SetID(*sh.ID) si.SetMetabasePath(sh.MetaBaseInfo.Path) - si.SetBlobstorPath(sh.BlobStorInfo.RootPath) + si.Blobstor = blobstorInfoToProto(sh.BlobStorInfo) si.SetWriteCachePath(sh.WriteCacheInfo.Path) si.SetPiloramaPath(sh.PiloramaInfo.Path) @@ -64,3 +65,14 @@ func (s *Server) ListShards(_ context.Context, req *control.ListShardsRequest) ( return resp, nil } + +func blobstorInfoToProto(info blobstor.Info) []*control.BlobstorInfo { + res := make([]*control.BlobstorInfo, len(info.SubStorages)) + for i := range info.SubStorages { + res[i] = &control.BlobstorInfo{ + Path: info.SubStorages[i].Path, + Type: info.SubStorages[i].Type, + } + } + return res +} diff --git a/pkg/services/control/service_test.go b/pkg/services/control/service_test.go index b64e67d7b..8c5f3279c 100644 --- a/pkg/services/control/service_test.go +++ b/pkg/services/control/service_test.go @@ -77,18 +77,21 @@ func equalListShardResponseBodies(b1, b2 *control.ListShardsResponse_Body) bool for i := range b1.Shards { if b1.Shards[i].GetMetabasePath() != b2.Shards[i].GetMetabasePath() || - b1.Shards[i].GetBlobstorPath() != b2.Shards[i].GetBlobstorPath() || b1.Shards[i].GetWritecachePath() != b2.Shards[i].GetWritecachePath() || b1.Shards[i].GetPiloramaPath() != b2.Shards[i].GetPiloramaPath() || !bytes.Equal(b1.Shards[i].GetShard_ID(), b2.Shards[i].GetShard_ID()) { return false } + + info1 := b1.Shards[i].GetBlobstor() + info2 := b2.Shards[i].GetBlobstor() + return compareBlobstorInfo(info1, info2) } for i := range b1.Shards { for j := i + 1; j < len(b1.Shards); j++ { if b1.Shards[i].GetMetabasePath() == b2.Shards[j].GetMetabasePath() || - b1.Shards[i].GetBlobstorPath() == b2.Shards[j].GetBlobstorPath() || + !compareBlobstorInfo(b1.Shards[i].Blobstor, b2.Shards[i].Blobstor) || b1.Shards[i].GetWritecachePath() == b2.Shards[j].GetWritecachePath() || bytes.Equal(b1.Shards[i].GetShard_ID(), b2.Shards[j].GetShard_ID()) { return false @@ -98,6 +101,18 @@ func equalListShardResponseBodies(b1, b2 *control.ListShardsResponse_Body) bool return true } +func compareBlobstorInfo(a, b []*control.BlobstorInfo) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i].Type != b[i].Type || + a[i].Path != b[i].Path { + return false + } + } + return true +} func generateListShardsResponseBody() *control.ListShardsResponse_Body { body := new(control.ListShardsResponse_Body) diff --git a/pkg/services/control/types.go b/pkg/services/control/types.go index 406a1896a..13bd87ed5 100644 --- a/pkg/services/control/types.go +++ b/pkg/services/control/types.go @@ -97,11 +97,6 @@ func (x *ShardInfo) SetMetabasePath(v string) { x.MetabasePath = v } -// SetBlobstorPath sets path to shard's blobstor. -func (x *ShardInfo) SetBlobstorPath(v string) { - x.BlobstorPath = v -} - // SetWriteCachePath sets path to shard's write-cache. func (x *ShardInfo) SetWriteCachePath(v string) { x.WritecachePath = v diff --git a/pkg/services/control/types.pb.go b/pkg/services/control/types.pb.go index 7056a225f..0f40deb50 100644 Binary files a/pkg/services/control/types.pb.go and b/pkg/services/control/types.pb.go differ diff --git a/pkg/services/control/types.proto b/pkg/services/control/types.proto index 0729e4ebb..1994e2448 100644 --- a/pkg/services/control/types.proto +++ b/pkg/services/control/types.proto @@ -128,8 +128,8 @@ message ShardInfo { // Path to shard's metabase. string metabase_path = 2 [json_name = "metabasePath"]; - // Path to shard's blobstor. - string blobstor_path = 3 [json_name = "blobstorPath"]; + // Shard's blobstor info. + repeated BlobstorInfo blobstor = 3 [json_name = "blobstor"]; // Path to shard's write-cache, empty if disabled. string writecache_path = 4 [json_name = "writecachePath"]; @@ -144,6 +144,14 @@ message ShardInfo { string pilorama_path = 7 [json_name = "piloramaPath"]; } +// Blobstor component description. +message BlobstorInfo { + // Path to the root. + string path = 1 [json_name = "path"]; + // Component type. + string type = 2 [json_name = "type"]; +} + // Work mode of the shard. enum ShardMode { // Undefined mode, default value. diff --git a/pkg/services/control/types_neofs.pb.go b/pkg/services/control/types_neofs.pb.go index 8dd46362e..148f1869c 100644 Binary files a/pkg/services/control/types_neofs.pb.go and b/pkg/services/control/types_neofs.pb.go differ diff --git a/pkg/services/control/types_test.go b/pkg/services/control/types_test.go index 40a0d17a9..79b6da8e6 100644 --- a/pkg/services/control/types_test.go +++ b/pkg/services/control/types_test.go @@ -7,6 +7,8 @@ import ( "testing" "github.com/google/uuid" + "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/services/control" ) @@ -138,7 +140,9 @@ func generateShardInfo(id int) *control.ShardInfo { si.SetID(bin) si.SetMode(control.ShardMode_READ_WRITE) si.SetMetabasePath(filepath.Join(path, "meta")) - si.SetBlobstorPath(filepath.Join(path, "blobstor")) + si.Blobstor = []*control.BlobstorInfo{ + {Type: fstree.Type, Path: filepath.Join(path, "fstree")}, + {Type: blobovniczatree.Type, Path: filepath.Join(path, "blobtree")}} si.SetWriteCachePath(filepath.Join(path, "writecache")) si.SetPiloramaPath(filepath.Join(path, "pilorama"))