package control import ( "fmt" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/engine" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control" "github.com/mr-tron/base58" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func stateToResponse(state *engine.EvacuationState) (*control.GetShardEvacuationStatusResponse, error) { shardIDs := make([][]byte, 0, len(state.ShardIDs())) for _, shID := range state.ShardIDs() { id, err := base58.Decode(shID) if err != nil { return nil, status.Error(codes.Internal, fmt.Sprintf("invalid shard id format: %s", shID)) } shardIDs = append(shardIDs, id) } var evacStatus control.GetShardEvacuationStatusResponse_Body_Status switch state.ProcessingStatus() { case engine.EvacuateProcessStateRunning: evacStatus = control.GetShardEvacuationStatusResponse_Body_RUNNING case engine.EvacuateProcessStateCompleted: evacStatus = control.GetShardEvacuationStatusResponse_Body_COMPLETED default: evacStatus = control.GetShardEvacuationStatusResponse_Body_EVACUATE_SHARD_STATUS_UNDEFINED } var startedAt *control.GetShardEvacuationStatusResponse_Body_UnixTimestamp if state.StartedAt() != nil { startedAt = &control.GetShardEvacuationStatusResponse_Body_UnixTimestamp{ Value: state.StartedAt().Unix(), } } var duration *control.GetShardEvacuationStatusResponse_Body_Duration if state.StartedAt() != nil { end := time.Now().UTC() if state.FinishedAt() != nil { end = *state.FinishedAt() } duration = &control.GetShardEvacuationStatusResponse_Body_Duration{ Seconds: int64(end.Sub(*state.StartedAt()).Seconds()), } } return &control.GetShardEvacuationStatusResponse{ Body: &control.GetShardEvacuationStatusResponse_Body{ Shard_ID: shardIDs, Evacuated: state.Evacuated(), Total: state.Total(), Failed: state.Failed(), Status: evacStatus, StartedAt: startedAt, Duration: duration, ErrorMessage: state.ErrorMessage(), Skipped: state.Skipped(), }, }, nil }