github.com/pingcap/tiup@v1.15.1/components/ctl/main.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"path"
     9  	"strings"
    10  
    11  	"github.com/fatih/color"
    12  	"github.com/pingcap/tiup/pkg/localdata"
    13  	"github.com/pingcap/tiup/pkg/utils"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  func main() {
    18  	if err := execute(); err != nil {
    19  		os.Exit(1)
    20  	}
    21  }
    22  
    23  func execute() error {
    24  	ignoreVersion := false
    25  	home := os.Getenv(localdata.EnvNameComponentInstallDir)
    26  	if home == "" {
    27  		return errors.New("component `ctl` cannot run in standalone mode")
    28  	}
    29  	rootCmd := &cobra.Command{
    30  		Use:                "tiup ctl {tidb/pd/tikv/binlog/etcd/cdc/tidb-lightning}",
    31  		Short:              "TiDB controllers",
    32  		SilenceUsage:       true,
    33  		FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
    34  		RunE: func(cmd *cobra.Command, args []string) error {
    35  			if len(args) == 0 {
    36  				return cmd.Help()
    37  			}
    38  
    39  			var transparentParams []string
    40  			componentSpec := args[0]
    41  			for i, arg := range os.Args {
    42  				if arg == componentSpec {
    43  					transparentParams = os.Args[i+1:]
    44  					break
    45  				}
    46  			}
    47  
    48  			if ignoreVersion {
    49  				for i, arg := range transparentParams {
    50  					if arg == "--ignore-version" {
    51  						transparentParams = append(transparentParams[:i], transparentParams[i+1:]...)
    52  					}
    53  				}
    54  			} else if os.Getenv(localdata.EnvNameUserInputVersion) == "" {
    55  				// if user not set component version explicitly
    56  				return errors.New(
    57  					"ctl needs an explicit version, please run with `tiup ctl:<cluster-version>`, if you continue seeing this error, please upgrade your TiUP with `tiup update --self`",
    58  				)
    59  			}
    60  
    61  			bin, err := binaryPath(home, componentSpec)
    62  			if err != nil {
    63  				return err
    64  			}
    65  			return run(bin, transparentParams...)
    66  		},
    67  	}
    68  
    69  	originHelpFunc := rootCmd.HelpFunc()
    70  	rootCmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
    71  		if len(args) < 2 {
    72  			originHelpFunc(cmd, args)
    73  			return
    74  		}
    75  		args = utils.RebuildArgs(args)
    76  		bin, err := binaryPath(home, args[0])
    77  		if err != nil {
    78  			fmt.Println(color.RedString("Error: %v", err))
    79  			return
    80  		}
    81  		if err := run(bin, args[1:]...); err != nil {
    82  			fmt.Println(color.RedString("Error: %v", err))
    83  		}
    84  	})
    85  	rootCmd.Flags().BoolVar(&ignoreVersion, "ignore-version", false, "Skip explicit version check")
    86  
    87  	return rootCmd.Execute()
    88  }
    89  
    90  func binaryPath(home, cmd string) (string, error) {
    91  	switch cmd {
    92  	case "tidb", "tikv", "pd", "tidb-lightning":
    93  		return path.Join(home, cmd+"-ctl"), nil
    94  	case "binlog", "etcd":
    95  		return path.Join(home, cmd+"ctl"), nil
    96  	case "cdc":
    97  		return path.Join(home, cmd+" cli"), nil
    98  	default:
    99  		return "", errors.New("ctl only supports tidb, tikv, pd, binlog, tidb-lightning, etcd and cdc currently")
   100  	}
   101  }
   102  
   103  func run(name string, args ...string) error {
   104  	os.Setenv("ETCDCTL_API", "3")
   105  	// Handle `cdc cli`
   106  	if strings.Contains(name, " ") {
   107  		xs := strings.Split(name, " ")
   108  		name = xs[0]
   109  		args = append(xs[1:], args...)
   110  	}
   111  	cmd := exec.Command(name, args...)
   112  	cmd.Stdout = os.Stdout
   113  	cmd.Stderr = os.Stderr
   114  	cmd.Stdin = os.Stdin
   115  	return cmd.Run()
   116  }