github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/pkg/cmd/master/master.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 master 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/pkg/cmd/util" 23 "github.com/pingcap/tiflow/engine/servermaster" 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 masterConfig *servermaster.Config 37 masterConfigFilePath string 38 } 39 40 // newOptions creates new options for the `server` command. 41 func newOptions() *options { 42 return &options{ 43 masterConfig: servermaster.GetDefaultMasterConfig(), 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.masterConfig.Name, "name", o.masterConfig.Name, "human readable name for master") 51 cmd.Flags().StringVar(&o.masterConfig.Addr, "addr", o.masterConfig.Addr, "Set the listening address for server master") 52 cmd.Flags().StringVar(&o.masterConfig.AdvertiseAddr, "advertise-addr", o.masterConfig.AdvertiseAddr, "Set the advertise listening address for client communication") 53 54 cmd.Flags().StringSliceVar(&o.masterConfig.FrameworkMeta.Endpoints, "framework-meta-endpoints", o.masterConfig.FrameworkMeta.Endpoints, "framework metastore endpoint") 55 cmd.Flags().StringSliceVar(&o.masterConfig.BusinessMeta.Endpoints, "business-meta-endpoints", o.masterConfig.BusinessMeta.Endpoints, "business metastore endpoint") 56 57 cmd.Flags().StringVar(&o.masterConfigFilePath, "config", "", "Path of the configuration file") 58 cmd.Flags().StringVar(&o.masterConfig.LogConf.File, "log-file", o.masterConfig.LogConf.File, "log file path") 59 cmd.Flags().StringVar(&o.masterConfig.LogConf.Level, "log-level", o.masterConfig.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.masterConfig.LogConf) 65 if err != nil { 66 return errors.Trace(err) 67 } 68 69 version.LogVersionInfo("TiFlow Master") 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, err := servermaster.NewServer(o.masterConfig) 80 if err != nil { 81 return errors.Trace(err) 82 } 83 84 err = server.Run(cmdconetxt.GetDefaultContext()) 85 if err != nil && errors.Cause(err) != context.Canceled { 86 log.Error("run dataflow server master with error", zap.Error(err)) 87 return errors.Trace(err) 88 } 89 log.Info("dataflow server master exits successfully") 90 91 return nil 92 } 93 94 // complete adapts from the command line args and config file to the data required. 95 func (o *options) complete(cmd *cobra.Command) error { 96 cfg := servermaster.GetDefaultMasterConfig() 97 98 if len(o.masterConfigFilePath) > 0 { 99 if err := ticdcutil.StrictDecodeFile( 100 o.masterConfigFilePath, "dataflow engine server master", cfg); err != nil { 101 return err 102 } 103 } 104 105 cmd.Flags().Visit(func(flag *pflag.Flag) { 106 switch flag.Name { 107 case "name": 108 cfg.Name = o.masterConfig.Name 109 case "addr": 110 cfg.Addr = o.masterConfig.Addr 111 case "advertise-addr": 112 cfg.AdvertiseAddr = o.masterConfig.AdvertiseAddr 113 case "framework-meta-endpoints": 114 cfg.FrameworkMeta.Endpoints = o.masterConfig.FrameworkMeta.Endpoints 115 case "business-meta-endpoints": 116 cfg.BusinessMeta.Endpoints = o.masterConfig.BusinessMeta.Endpoints 117 case "config": 118 // do nothing 119 case "log-file": 120 cfg.LogConf.File = o.masterConfig.LogConf.File 121 case "log-level": 122 cfg.LogConf.Level = o.masterConfig.LogConf.Level 123 default: 124 log.Panic("unknown flag, please report a bug", zap.String("flagName", flag.Name)) 125 } 126 }) 127 128 if err := cfg.AdjustAndValidate(); err != nil { 129 return errors.Trace(err) 130 } 131 132 o.masterConfig = cfg 133 134 return nil 135 } 136 137 // NewCmdMaster creates the `master` command. 138 func NewCmdMaster() *cobra.Command { 139 o := newOptions() 140 141 command := &cobra.Command{ 142 Use: "master", 143 Short: "Start a dataflow engine server master", 144 Args: cobra.NoArgs, 145 RunE: func(cmd *cobra.Command, args []string) error { 146 err := o.complete(cmd) 147 if err != nil { 148 return err 149 } 150 err = o.run(cmd) 151 cobra.CheckErr(err) 152 return nil 153 }, 154 } 155 156 o.addFlags(command) 157 158 return command 159 }