github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/ctl/master/start_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/pingcap/tiflow/dm/pkg/log" 27 "github.com/pingcap/tiflow/dm/pkg/terror" 28 "github.com/spf13/cobra" 29 "go.uber.org/zap" 30 ) 31 32 // NewStartTaskCmd creates a StartTask command. 33 func NewStartTaskCmd() *cobra.Command { 34 cmd := &cobra.Command{ 35 Use: "start-task [-s source ...] [--remove-meta] <config-file>", 36 Short: "Starts a task as defined in the configuration file", 37 RunE: startTaskFunc, 38 } 39 cmd.Flags().BoolP("remove-meta", "", false, "whether to remove task's meta data") 40 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") 41 return cmd 42 } 43 44 // startTaskFunc does start task request. 45 func startTaskFunc(cmd *cobra.Command, _ []string) error { 46 if len(cmd.Flags().Args()) != 1 { 47 cmd.SetOut(os.Stdout) 48 common.PrintCmdUsage(cmd) 49 return errors.New("please check output to see error") 50 } 51 content, err := common.GetFileContent(cmd.Flags().Arg(0)) 52 if err != nil { 53 return err 54 } 55 56 // If task's target db is configured with tls certificate related content 57 // the contents of the certificate need to be read and transferred to the dm-master 58 task := config.NewTaskConfig() 59 yamlErr := task.RawDecode(string(content)) 60 if yamlErr != nil { 61 return yamlErr 62 } 63 if task.TargetDB != nil && task.TargetDB.Security != nil { 64 loadErr := task.TargetDB.Security.LoadTLSContent() 65 if loadErr != nil { 66 log.L().Warn("load tls content failed", zap.Error(terror.ErrCtlLoadTLSCfg.Generate(loadErr))) 67 } 68 content = []byte(task.String()) 69 } 70 71 lines := bytes.Split(content, []byte("\n")) 72 // we check if `is-sharding` is explicitly set, to distinguish between `false` from default value 73 isShardingSet := false 74 for i := range lines { 75 if bytes.HasPrefix(lines[i], []byte("is-sharding")) { 76 isShardingSet = true 77 break 78 } 79 } 80 // we check if `shard-mode` is explicitly set, to distinguish between "" from default value 81 shardModeSet := false 82 for i := range lines { 83 if bytes.HasPrefix(lines[i], []byte("shard-mode")) { 84 shardModeSet = true 85 break 86 } 87 } 88 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 sources, err := common.GetSourceArgs(cmd) 99 if err != nil { 100 return err 101 } 102 103 removeMeta, err := cmd.Flags().GetBool("remove-meta") 104 if err != nil { 105 common.PrintLinesf("error in parse `--remove-meta`") 106 return err 107 } 108 startTime, err := cmd.Flags().GetString("start-time") 109 if err != nil { 110 common.PrintLinesf("error in parse `--start-time`") 111 return err 112 } 113 114 ctx, cancel := context.WithCancel(context.Background()) 115 defer cancel() 116 117 // start task 118 resp := &pb.StartTaskResponse{} 119 err = common.SendRequest( 120 ctx, 121 "StartTask", 122 &pb.StartTaskRequest{ 123 Task: string(content), 124 Sources: sources, 125 RemoveMeta: removeMeta, 126 StartTime: startTime, 127 }, 128 &resp, 129 ) 130 131 if err != nil { 132 return err 133 } 134 135 if !common.PrettyPrintResponseWithCheckTask(resp, checker.CheckTaskMsgHeader) { 136 common.PrettyPrintResponse(resp) 137 } 138 return nil 139 }