From b3f3505adaca55ec9aeca1a1a6d6a0a2e584f3f9 Mon Sep 17 00:00:00 2001
From: Dmitrii Stepanov <d.stepanov@yadro.com>
Date: Mon, 5 Feb 2024 16:33:09 +0300
Subject: [PATCH] [#947] cli: Allow to specify evacuation scope

It may be required to evacuate only objects or only tree or all, so
now it spossible to specify.

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
---
 cmd/frostfs-cli/modules/control/evacuation.go |  23 ++++++++++++++
 pkg/local_object_storage/engine/evacuate.go   |  30 ++++++++++++++++++
 pkg/services/control/server/evacuate.go       |   1 +
 pkg/services/control/server/evacuate_async.go |   5 +++
 pkg/services/control/service.pb.go            | Bin 231700 -> 234031 bytes
 pkg/services/control/service.proto            |   8 +++++
 pkg/services/control/service_frostfs.pb.go    | Bin 107641 -> 107736 bytes
 7 files changed, 67 insertions(+)

diff --git a/cmd/frostfs-cli/modules/control/evacuation.go b/cmd/frostfs-cli/modules/control/evacuation.go
index 821dd1a6c..9d4cb64ac 100644
--- a/cmd/frostfs-cli/modules/control/evacuation.go
+++ b/cmd/frostfs-cli/modules/control/evacuation.go
@@ -19,6 +19,11 @@ import (
 const (
 	awaitFlag      = "await"
 	noProgressFlag = "no-progress"
+	scopeFlag      = "scope"
+
+	scopeAll     = "all"
+	scopeObjects = "objects"
+	scopeTrees   = "trees"
 )
 
 var evacuationShardCmd = &cobra.Command{
@@ -57,6 +62,7 @@ func startEvacuateShard(cmd *cobra.Command, _ []string) {
 		Body: &control.StartShardEvacuationRequest_Body{
 			Shard_ID:     getShardIDList(cmd),
 			IgnoreErrors: ignoreErrors,
+			Scope:        getEvacuationScope(cmd),
 		},
 	}
 
@@ -82,6 +88,22 @@ func startEvacuateShard(cmd *cobra.Command, _ []string) {
 	}
 }
 
+func getEvacuationScope(cmd *cobra.Command) uint32 {
+	rawScope, err := cmd.Flags().GetString(scopeFlag)
+	commonCmd.ExitOnErr(cmd, "Invalid scope value: %w", err)
+	switch rawScope {
+	case scopeAll:
+		return uint32(control.StartShardEvacuationRequest_Body_OBJECTS) | uint32(control.StartShardEvacuationRequest_Body_TREES)
+	case scopeObjects:
+		return uint32(control.StartShardEvacuationRequest_Body_OBJECTS)
+	case scopeTrees:
+		return uint32(control.StartShardEvacuationRequest_Body_TREES)
+	default:
+		commonCmd.ExitOnErr(cmd, "Invalid scope value: %w", fmt.Errorf("unknown scope %s", rawScope))
+	}
+	return uint32(control.StartShardEvacuationRequest_Body_NONE)
+}
+
 func getEvacuateShardStatus(cmd *cobra.Command, _ []string) {
 	pk := key.Get(cmd)
 	req := &control.GetShardEvacuationStatusRequest{
@@ -309,6 +331,7 @@ func initControlStartEvacuationShardCmd() {
 	flags.StringSlice(shardIDFlag, nil, "List of shard IDs in base58 encoding")
 	flags.Bool(shardAllFlag, false, "Process all shards")
 	flags.Bool(ignoreErrorsFlag, true, "Skip invalid/unreadable objects")
+	flags.String(scopeFlag, scopeAll, fmt.Sprintf("Evacuation scope; possible values: %s, %s, %s", scopeTrees, scopeObjects, scopeAll))
 	flags.Bool(awaitFlag, false, "Block execution until evacuation is completed")
 	flags.Bool(noProgressFlag, false, fmt.Sprintf("Print progress if %s provided", awaitFlag))
 
diff --git a/pkg/local_object_storage/engine/evacuate.go b/pkg/local_object_storage/engine/evacuate.go
index d95098fbf..ad432e400 100644
--- a/pkg/local_object_storage/engine/evacuate.go
+++ b/pkg/local_object_storage/engine/evacuate.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"strings"
 	"sync/atomic"
 
 	"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
@@ -28,12 +29,40 @@ var (
 	evacuationOperationLogField = zap.String("operation", "evacuation")
 )
 
+// EvacuateScope is an evacuation scope. Keep in sync with pkg/services/control/service.proto.
+type EvacuateScope uint32
+
+var (
+	EvacuateScopeObjects EvacuateScope = 1
+	EvacuateScopeTrees   EvacuateScope = 2
+)
+
+func (s EvacuateScope) String() string {
+	var sb strings.Builder
+	first := true
+	if s&EvacuateScopeObjects == EvacuateScopeObjects {
+		if !first {
+			sb.WriteString(";")
+		}
+		sb.WriteString("objects")
+		first = false
+	}
+	if s&EvacuateScopeTrees == EvacuateScopeTrees {
+		if !first {
+			sb.WriteString(";")
+		}
+		sb.WriteString("trees")
+	}
+	return sb.String()
+}
+
 // EvacuateShardPrm represents parameters for the EvacuateShard operation.
 type EvacuateShardPrm struct {
 	ShardID      []*shard.ID
 	Handler      func(context.Context, oid.Address, *objectSDK.Object) error
 	IgnoreErrors bool
 	Async        bool
+	Scope        EvacuateScope
 }
 
 // EvacuateShardRes represents result of the EvacuateShard operation.
@@ -135,6 +164,7 @@ func (e *StorageEngine) Evacuate(ctx context.Context, prm EvacuateShardPrm) (*Ev
 			attribute.StringSlice("shardIDs", shardIDs),
 			attribute.Bool("async", prm.Async),
 			attribute.Bool("ignoreErrors", prm.IgnoreErrors),
+			attribute.Stringer("scope", prm.Scope),
 		))
 	defer span.End()
 
diff --git a/pkg/services/control/server/evacuate.go b/pkg/services/control/server/evacuate.go
index 52ef083c4..6cba72d71 100644
--- a/pkg/services/control/server/evacuate.go
+++ b/pkg/services/control/server/evacuate.go
@@ -29,6 +29,7 @@ func (s *Server) EvacuateShard(ctx context.Context, req *control.EvacuateShardRe
 		ShardID:      s.getShardIDList(req.GetBody().GetShard_ID()),
 		IgnoreErrors: req.GetBody().GetIgnoreErrors(),
 		Handler:      s.replicate,
+		Scope:        engine.EvacuateScopeObjects,
 	}
 
 	res, err := s.s.Evacuate(ctx, prm)
diff --git a/pkg/services/control/server/evacuate_async.go b/pkg/services/control/server/evacuate_async.go
index 112d4449f..0b2851275 100644
--- a/pkg/services/control/server/evacuate_async.go
+++ b/pkg/services/control/server/evacuate_async.go
@@ -17,11 +17,16 @@ func (s *Server) StartShardEvacuation(ctx context.Context, req *control.StartSha
 		return nil, status.Error(codes.PermissionDenied, err.Error())
 	}
 
+	if req.GetBody().GetScope() == uint32(control.StartShardEvacuationRequest_Body_NONE) {
+		return nil, status.Error(codes.InvalidArgument, "no evacuation scope")
+	}
+
 	prm := engine.EvacuateShardPrm{
 		ShardID:      s.getShardIDList(req.GetBody().GetShard_ID()),
 		IgnoreErrors: req.GetBody().GetIgnoreErrors(),
 		Handler:      s.replicate,
 		Async:        true,
+		Scope:        engine.EvacuateScope(req.GetBody().GetScope()),
 	}
 
 	_, err = s.s.Evacuate(ctx, prm)
diff --git a/pkg/services/control/service.pb.go b/pkg/services/control/service.pb.go
index c9645941bfd63bc551c73279be3a9bfd67f8788b..9c1a8741561d3a4412aca26b8a4b7548b4c31c19 100644
GIT binary patch
delta 8842
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
KZpX8tFZ~}#zU!a>

delta 8670
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

diff --git a/pkg/services/control/service.proto b/pkg/services/control/service.proto
index 4cb1dee33..73e8ca90f 100644
--- a/pkg/services/control/service.proto
+++ b/pkg/services/control/service.proto
@@ -336,10 +336,18 @@ message DoctorResponse {
 message StartShardEvacuationRequest {
     // Request body structure.
     message Body {
+        enum Scope {
+            NONE = 0;
+            OBJECTS = 1;
+            TREES = 2;
+        }
+
         // IDs of the shards.
         repeated bytes shard_ID = 1;
         // Flag indicating whether object read errors should be ignored.
         bool ignore_errors = 2;
+        // Evacuation scope.
+        uint32 scope = 3;
     }
 
     Body body = 1;
diff --git a/pkg/services/control/service_frostfs.pb.go b/pkg/services/control/service_frostfs.pb.go
index 125a12d00e215708483faa88effe2dcda169988c..b18d30dba167296cd71e7ba491163df66e94c18a 100644
GIT binary patch
delta 71
zcmex)g6+mhwhfE-O%Cjm<TTb%sL%^e&M(;f@$OW{$=>J0HhUeAW1K7^BrsXvCCg;r
bHC&U`a)ntyN+t*H5}h31)VlfK!Rki<P9`3^

delta 49
zcmV-10M7r|$p-nz2C$>Pw-9#$k^z%V#~PEI^9`2{K>@>)d{-NjAcDk`?!6n6zr+Z$
HfWlbfPnj4D