package control import ( "context" "errors" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/engine" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server/ctrlmessage" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func (s *Server) StartShardEvacuation(ctx context.Context, req *control.StartShardEvacuationRequest) (*control.StartShardEvacuationResponse, error) { err := s.isValidRequest(req) if err != nil { 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(), ObjectsHandler: s.replicateObject, TreeHandler: s.replicateTree, Async: true, Scope: engine.EvacuateScope(req.GetBody().GetScope()), } _, err = s.s.Evacuate(ctx, prm) if err != nil { var logicalErr logicerr.Logical if errors.As(err, &logicalErr) { return nil, status.Error(codes.Aborted, err.Error()) } return nil, status.Error(codes.Internal, err.Error()) } resp := &control.StartShardEvacuationResponse{ Body: &control.StartShardEvacuationResponse_Body{}, } err = ctrlmessage.Sign(s.key, resp) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } return resp, nil } func (s *Server) GetShardEvacuationStatus(ctx context.Context, req *control.GetShardEvacuationStatusRequest) (*control.GetShardEvacuationStatusResponse, error) { err := s.isValidRequest(req) if err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) } state, err := s.s.GetEvacuationState(ctx) if err != nil { var logicalErr logicerr.Logical if errors.As(err, &logicalErr) { return nil, status.Error(codes.Aborted, err.Error()) } return nil, status.Error(codes.Internal, err.Error()) } resp, err := stateToResponse(state) if err != nil { return nil, err } err = ctrlmessage.Sign(s.key, resp) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } return resp, nil } func (s *Server) StopShardEvacuation(ctx context.Context, req *control.StopShardEvacuationRequest) (*control.StopShardEvacuationResponse, error) { err := s.isValidRequest(req) if err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) } err = s.s.EnqueRunningEvacuationStop(ctx) if err != nil { var logicalErr logicerr.Logical if errors.As(err, &logicalErr) { return nil, status.Error(codes.Aborted, err.Error()) } return nil, status.Error(codes.Internal, err.Error()) } resp := &control.StopShardEvacuationResponse{ Body: &control.StopShardEvacuationResponse_Body{}, } err = ctrlmessage.Sign(s.key, resp) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } s.s.ResetEvacuationStatusForShards() return resp, nil } func (s *Server) ResetShardEvacuationStatus(ctx context.Context, req *control.ResetShardEvacuationStatusRequest) (*control.ResetShardEvacuationStatusResponse, error) { err := s.isValidRequest(req) if err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) } err = s.s.ResetEvacuationStatus(ctx) if err != nil { var logicalErr logicerr.Logical if errors.As(err, &logicalErr) { return nil, status.Error(codes.Aborted, err.Error()) } return nil, status.Error(codes.Internal, err.Error()) } resp := &control.ResetShardEvacuationStatusResponse{ Body: &control.ResetShardEvacuationStatusResponse_Body{}, } err = ctrlmessage.Sign(s.key, resp) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } return resp, nil }