forked from TrueCloudLab/frostfs-node
[#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>
This commit is contained in:
parent
a6eb66bf9c
commit
b3f3505ada
7 changed files with 67 additions and 0 deletions
|
@ -19,6 +19,11 @@ import (
|
||||||
const (
|
const (
|
||||||
awaitFlag = "await"
|
awaitFlag = "await"
|
||||||
noProgressFlag = "no-progress"
|
noProgressFlag = "no-progress"
|
||||||
|
scopeFlag = "scope"
|
||||||
|
|
||||||
|
scopeAll = "all"
|
||||||
|
scopeObjects = "objects"
|
||||||
|
scopeTrees = "trees"
|
||||||
)
|
)
|
||||||
|
|
||||||
var evacuationShardCmd = &cobra.Command{
|
var evacuationShardCmd = &cobra.Command{
|
||||||
|
@ -57,6 +62,7 @@ func startEvacuateShard(cmd *cobra.Command, _ []string) {
|
||||||
Body: &control.StartShardEvacuationRequest_Body{
|
Body: &control.StartShardEvacuationRequest_Body{
|
||||||
Shard_ID: getShardIDList(cmd),
|
Shard_ID: getShardIDList(cmd),
|
||||||
IgnoreErrors: ignoreErrors,
|
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) {
|
func getEvacuateShardStatus(cmd *cobra.Command, _ []string) {
|
||||||
pk := key.Get(cmd)
|
pk := key.Get(cmd)
|
||||||
req := &control.GetShardEvacuationStatusRequest{
|
req := &control.GetShardEvacuationStatusRequest{
|
||||||
|
@ -309,6 +331,7 @@ func initControlStartEvacuationShardCmd() {
|
||||||
flags.StringSlice(shardIDFlag, nil, "List of shard IDs in base58 encoding")
|
flags.StringSlice(shardIDFlag, nil, "List of shard IDs in base58 encoding")
|
||||||
flags.Bool(shardAllFlag, false, "Process all shards")
|
flags.Bool(shardAllFlag, false, "Process all shards")
|
||||||
flags.Bool(ignoreErrorsFlag, true, "Skip invalid/unreadable objects")
|
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(awaitFlag, false, "Block execution until evacuation is completed")
|
||||||
flags.Bool(noProgressFlag, false, fmt.Sprintf("Print progress if %s provided", awaitFlag))
|
flags.Bool(noProgressFlag, false, fmt.Sprintf("Print progress if %s provided", awaitFlag))
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
|
@ -28,12 +29,40 @@ var (
|
||||||
evacuationOperationLogField = zap.String("operation", "evacuation")
|
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.
|
// EvacuateShardPrm represents parameters for the EvacuateShard operation.
|
||||||
type EvacuateShardPrm struct {
|
type EvacuateShardPrm struct {
|
||||||
ShardID []*shard.ID
|
ShardID []*shard.ID
|
||||||
Handler func(context.Context, oid.Address, *objectSDK.Object) error
|
Handler func(context.Context, oid.Address, *objectSDK.Object) error
|
||||||
IgnoreErrors bool
|
IgnoreErrors bool
|
||||||
Async bool
|
Async bool
|
||||||
|
Scope EvacuateScope
|
||||||
}
|
}
|
||||||
|
|
||||||
// EvacuateShardRes represents result of the EvacuateShard operation.
|
// 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.StringSlice("shardIDs", shardIDs),
|
||||||
attribute.Bool("async", prm.Async),
|
attribute.Bool("async", prm.Async),
|
||||||
attribute.Bool("ignoreErrors", prm.IgnoreErrors),
|
attribute.Bool("ignoreErrors", prm.IgnoreErrors),
|
||||||
|
attribute.Stringer("scope", prm.Scope),
|
||||||
))
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ func (s *Server) EvacuateShard(ctx context.Context, req *control.EvacuateShardRe
|
||||||
ShardID: s.getShardIDList(req.GetBody().GetShard_ID()),
|
ShardID: s.getShardIDList(req.GetBody().GetShard_ID()),
|
||||||
IgnoreErrors: req.GetBody().GetIgnoreErrors(),
|
IgnoreErrors: req.GetBody().GetIgnoreErrors(),
|
||||||
Handler: s.replicate,
|
Handler: s.replicate,
|
||||||
|
Scope: engine.EvacuateScopeObjects,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.s.Evacuate(ctx, prm)
|
res, err := s.s.Evacuate(ctx, prm)
|
||||||
|
|
|
@ -17,11 +17,16 @@ func (s *Server) StartShardEvacuation(ctx context.Context, req *control.StartSha
|
||||||
return nil, status.Error(codes.PermissionDenied, err.Error())
|
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{
|
prm := engine.EvacuateShardPrm{
|
||||||
ShardID: s.getShardIDList(req.GetBody().GetShard_ID()),
|
ShardID: s.getShardIDList(req.GetBody().GetShard_ID()),
|
||||||
IgnoreErrors: req.GetBody().GetIgnoreErrors(),
|
IgnoreErrors: req.GetBody().GetIgnoreErrors(),
|
||||||
Handler: s.replicate,
|
Handler: s.replicate,
|
||||||
Async: true,
|
Async: true,
|
||||||
|
Scope: engine.EvacuateScope(req.GetBody().GetScope()),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.s.Evacuate(ctx, prm)
|
_, err = s.s.Evacuate(ctx, prm)
|
||||||
|
|
BIN
pkg/services/control/service.pb.go
generated
BIN
pkg/services/control/service.pb.go
generated
Binary file not shown.
|
@ -336,10 +336,18 @@ message DoctorResponse {
|
||||||
message StartShardEvacuationRequest {
|
message StartShardEvacuationRequest {
|
||||||
// Request body structure.
|
// Request body structure.
|
||||||
message Body {
|
message Body {
|
||||||
|
enum Scope {
|
||||||
|
NONE = 0;
|
||||||
|
OBJECTS = 1;
|
||||||
|
TREES = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// IDs of the shards.
|
// IDs of the shards.
|
||||||
repeated bytes shard_ID = 1;
|
repeated bytes shard_ID = 1;
|
||||||
// Flag indicating whether object read errors should be ignored.
|
// Flag indicating whether object read errors should be ignored.
|
||||||
bool ignore_errors = 2;
|
bool ignore_errors = 2;
|
||||||
|
// Evacuation scope.
|
||||||
|
uint32 scope = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
Body body = 1;
|
Body body = 1;
|
||||||
|
|
BIN
pkg/services/control/service_frostfs.pb.go
generated
BIN
pkg/services/control/service_frostfs.pb.go
generated
Binary file not shown.
Loading…
Reference in a new issue