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  }