github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/ctl/master/check_task.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package master 15 16 import ( 17 "bytes" 18 "context" 19 "errors" 20 "os" 21 22 "github.com/pingcap/tiflow/dm/checker" 23 "github.com/pingcap/tiflow/dm/config" 24 "github.com/pingcap/tiflow/dm/ctl/common" 25 "github.com/pingcap/tiflow/dm/pb" 26 "github.com/spf13/cobra" 27 ) 28 29 // NewCheckTaskCmd creates a CheckTask command. 30 func NewCheckTaskCmd() *cobra.Command { 31 cmd := &cobra.Command{ 32 Use: "check-task <config-file> [--error count] [--warn count]", 33 Short: "Checks the configuration file of the task", 34 RunE: checkTaskFunc, 35 } 36 cmd.Flags().Int64P("error", "e", common.DefaultErrorCnt, "max count of errors to display") 37 cmd.Flags().Int64P("warn", "w", common.DefaultWarnCnt, "max count of warns to display") 38 cmd.Flags().String("start-time", "", "specify the start time of binlog replication, e.g. '2021-10-21 00:01:00' or 2021-10-21T00:01:00") 39 return cmd 40 } 41 42 // checkTaskFunc does check task request. 43 func checkTaskFunc(cmd *cobra.Command, _ []string) error { 44 if len(cmd.Flags().Args()) != 1 { 45 cmd.SetOut(os.Stdout) 46 common.PrintCmdUsage(cmd) 47 return errors.New("please check output to see error") 48 } 49 content, err := common.GetFileContent(cmd.Flags().Arg(0)) 50 if err != nil { 51 return err 52 } 53 54 errCnt, err := cmd.Flags().GetInt64("error") 55 if err != nil { 56 return err 57 } 58 warnCnt, err := cmd.Flags().GetInt64("warn") 59 if err != nil { 60 return err 61 } 62 startTime, err := cmd.Flags().GetString("start-time") 63 if err != nil { 64 return err 65 } 66 67 lines := bytes.Split(content, []byte("\n")) 68 // we check if `is-sharding` is explicitly set, to distinguish between `false` from default value 69 isShardingSet := false 70 for i := range lines { 71 if bytes.HasPrefix(lines[i], []byte("is-sharding")) { 72 isShardingSet = true 73 break 74 } 75 } 76 // we check if `shard-mode` is explicitly set, to distinguish between "" from default value 77 shardModeSet := false 78 for i := range lines { 79 if bytes.HasPrefix(lines[i], []byte("shard-mode")) { 80 shardModeSet = true 81 break 82 } 83 } 84 85 task := config.NewTaskConfig() 86 yamlErr := task.RawDecode(string(content)) 87 // if can't parse yaml, we ignore this check 88 if yamlErr == nil { 89 if isShardingSet && !task.IsSharding && task.ShardMode != "" { 90 common.PrintLinesf("The behaviour of `is-sharding` and `shard-mode` is conflicting. `is-sharding` is deprecated, please use `shard-mode` only.") 91 return errors.New("please check output to see error") 92 } 93 if shardModeSet && task.ShardMode == "" && task.IsSharding { 94 common.PrintLinesf("The behaviour of `is-sharding` and `shard-mode` is conflicting. `is-sharding` is deprecated, please use `shard-mode` only.") 95 return errors.New("please check output to see error") 96 } 97 } 98 99 ctx, cancel := context.WithCancel(context.Background()) 100 defer cancel() 101 102 resp := &pb.CheckTaskResponse{} 103 err = common.SendRequest( 104 ctx, 105 "CheckTask", 106 &pb.CheckTaskRequest{ 107 Task: string(content), 108 ErrCnt: errCnt, 109 WarnCnt: warnCnt, 110 StartTime: startTime, 111 }, 112 &resp, 113 ) 114 115 if err != nil { 116 return err 117 } 118 119 if !common.PrettyPrintResponseWithCheckTask(resp, checker.CheckTaskMsgHeader) { 120 common.PrettyPrintResponse(resp) 121 } 122 return nil 123 }