github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/pkg/cmd/executor/executor.go (about) 1 // Copyright 2022 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 executor 15 16 import ( 17 "context" 18 "os" 19 20 "github.com/gin-gonic/gin" 21 "github.com/pingcap/log" 22 "github.com/pingcap/tiflow/engine/executor" 23 "github.com/pingcap/tiflow/engine/pkg/cmd/util" 24 cmdconetxt "github.com/pingcap/tiflow/pkg/cmd/context" 25 ticdcutil "github.com/pingcap/tiflow/pkg/cmd/util" 26 "github.com/pingcap/tiflow/pkg/errors" 27 "github.com/pingcap/tiflow/pkg/logutil" 28 "github.com/pingcap/tiflow/pkg/version" 29 "github.com/spf13/cobra" 30 "github.com/spf13/pflag" 31 "go.uber.org/zap" 32 ) 33 34 // options defines flags for the `server` command. 35 type options struct { 36 executorConfig *executor.Config 37 executorConfigFilePath string 38 } 39 40 // newOptions creates new options for the `server` command. 41 func newOptions() *options { 42 return &options{ 43 executorConfig: executor.GetDefaultExecutorConfig(), 44 } 45 } 46 47 // addFlags receives a *cobra.Command reference and binds 48 // flags related to template printing to it. 49 func (o *options) addFlags(cmd *cobra.Command) { 50 cmd.Flags().StringVar(&o.executorConfig.Name, "name", o.executorConfig.Name, "human readable name for executor") 51 cmd.Flags().StringVar(&o.executorConfig.Addr, "addr", o.executorConfig.Addr, "Set the listening address for executor") 52 cmd.Flags().StringVar(&o.executorConfig.AdvertiseAddr, "advertise-addr", o.executorConfig.AdvertiseAddr, "Set the advertise listening address for client communication") 53 54 cmd.Flags().StringVar(&o.executorConfig.Join, "join", o.executorConfig.Join, "join to an existing cluster (usage: server masters' address)") 55 cmd.Flags().StringToStringVar(&o.executorConfig.Labels, "labels", map[string]string{}, "labels to the executor in key-value pairs") 56 57 cmd.Flags().StringVar(&o.executorConfigFilePath, "config", "", "Path of the configuration file") 58 cmd.Flags().StringVar(&o.executorConfig.LogConf.File, "log-file", o.executorConfig.LogConf.File, "log file path") 59 cmd.Flags().StringVar(&o.executorConfig.LogConf.Level, "log-level", o.executorConfig.LogConf.Level, "log level (etc: debug|info|warn|error)") 60 } 61 62 // run runs the server cmd. 63 func (o *options) run(cmd *cobra.Command) error { 64 err := logutil.InitLogger(&o.executorConfig.LogConf) 65 if err != nil { 66 return errors.Trace(err) 67 } 68 69 version.LogVersionInfo("TiFlow Executor") 70 if os.Getenv(gin.EnvGinMode) == "" { 71 gin.SetMode(gin.ReleaseMode) 72 } 73 74 cancel := util.InitCmd(cmd) 75 defer cancel() 76 77 ticdcutil.LogHTTPProxies() 78 79 server := executor.NewServer(o.executorConfig) 80 81 err = server.Run(cmdconetxt.GetDefaultContext()) 82 if err != nil && errors.Cause(err) != context.Canceled { 83 log.Error("run dataflow executor with error", zap.Error(err)) 84 return errors.Trace(err) 85 } 86 log.Info("dataflow executor exits successfully") 87 88 return nil 89 } 90 91 // complete adapts from the command line args and config file to the data required. 92 func (o *options) complete(cmd *cobra.Command) error { 93 cfg := executor.GetDefaultExecutorConfig() 94 95 if len(o.executorConfigFilePath) > 0 { 96 if err := ticdcutil.StrictDecodeFile( 97 o.executorConfigFilePath, "dataflow engine executor", cfg); err != nil { 98 return err 99 } 100 } 101 102 cmd.Flags().Visit(func(flag *pflag.Flag) { 103 switch flag.Name { 104 case "name": 105 cfg.Name = o.executorConfig.Name 106 case "addr": 107 cfg.Addr = o.executorConfig.Addr 108 case "advertise-addr": 109 cfg.AdvertiseAddr = o.executorConfig.AdvertiseAddr 110 case "join": 111 cfg.Join = o.executorConfig.Join 112 case "labels": 113 cfg.Labels = o.executorConfig.Labels 114 case "config": 115 // do nothing 116 case "log-file": 117 cfg.LogConf.File = o.executorConfig.LogConf.File 118 case "log-level": 119 cfg.LogConf.Level = o.executorConfig.LogConf.Level 120 default: 121 log.Panic("unknown flag, please report a bug", zap.String("flagName", flag.Name)) 122 } 123 }) 124 125 if err := cfg.Adjust(); err != nil { 126 return errors.Trace(err) 127 } 128 129 o.executorConfig = cfg 130 131 return nil 132 } 133 134 // NewCmdExecutor creates the `master` command. 135 func NewCmdExecutor() *cobra.Command { 136 o := newOptions() 137 138 command := &cobra.Command{ 139 Use: "executor", 140 Short: "Start a dataflow engine executor", 141 Args: cobra.NoArgs, 142 RunE: func(cmd *cobra.Command, args []string) error { 143 err := o.complete(cmd) 144 if err != nil { 145 return err 146 } 147 err = o.run(cmd) 148 cobra.CheckErr(err) 149 return nil 150 }, 151 } 152 153 o.addFlags(command) 154 155 return command 156 }