diff --git a/go/cmd/vtctldclient/commands.go b/go/cmd/vtctldclient/commands.go deleted file mode 100644 index 9b8861ad5c0..00000000000 --- a/go/cmd/vtctldclient/commands.go +++ /dev/null @@ -1,328 +0,0 @@ -/* -Copyright 2020 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "fmt" - "strings" - "time" - - "github.com/golang/protobuf/ptypes" - "github.com/spf13/cobra" - - "vitess.io/vitess/go/cmd/vtctldclient/cli" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/logutil" - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/topo/topoproto" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" -) - -var ( - findAllShardsInKeyspaceCmd = &cobra.Command{ - Use: "FindAllShardsInKeyspace keyspace", - Aliases: []string{"findallshardsinkeyspace"}, - Args: cobra.ExactArgs(1), - RunE: commandFindAllShardsInKeyspace, - } - getCellInfoNamesCmd = &cobra.Command{ - Use: "GetCellInfoNames", - Args: cobra.NoArgs, - RunE: commandGetCellInfoNames, - } - getCellInfoCmd = &cobra.Command{ - Use: "GetCellInfo cell", - Args: cobra.ExactArgs(1), - RunE: commandGetCellInfo, - } - getCellsAliasesCmd = &cobra.Command{ - Use: "GetCellsAliases", - Args: cobra.NoArgs, - RunE: commandGetCellsAliases, - } - getKeyspaceCmd = &cobra.Command{ - Use: "GetKeyspace keyspace", - Aliases: []string{"getkeyspace"}, - Args: cobra.ExactArgs(1), - RunE: commandGetKeyspace, - } - getKeyspacesCmd = &cobra.Command{ - Use: "GetKeyspaces", - Aliases: []string{"getkeyspaces"}, - Args: cobra.NoArgs, - RunE: commandGetKeyspaces, - } - getTabletCmd = &cobra.Command{ - Use: "GetTablet alias", - Args: cobra.ExactArgs(1), - RunE: commandGetTablet, - } - getTabletsCmd = &cobra.Command{ - Use: "GetTablets [--cell $c1, ...] [--keyspace $ks [--shard $shard]]", - Args: cobra.NoArgs, - RunE: commandGetTablets, - } - initShardPrimaryCmd = &cobra.Command{ - Use: "InitShardPrimary", - Args: cobra.ExactArgs(2), - RunE: commandInitShardPrimary, - } -) - -func commandFindAllShardsInKeyspace(cmd *cobra.Command, args []string) error { - ks := cmd.Flags().Arg(0) - resp, err := client.FindAllShardsInKeyspace(commandCtx, &vtctldatapb.FindAllShardsInKeyspaceRequest{ - Keyspace: ks, - }) - - if err != nil { - return err - } - - data, err := cli.MarshalJSON(resp) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - return nil -} - -func commandGetCellInfoNames(cmd *cobra.Command, args []string) error { - resp, err := client.GetCellInfoNames(commandCtx, &vtctldatapb.GetCellInfoNamesRequest{}) - if err != nil { - return err - } - - fmt.Printf("%s\n", strings.Join(resp.Names, "\n")) - - return nil -} - -func commandGetCellInfo(cmd *cobra.Command, args []string) error { - cell := cmd.Flags().Arg(0) - resp, err := client.GetCellInfo(commandCtx, &vtctldatapb.GetCellInfoRequest{Cell: cell}) - - if err != nil { - return err - } - - data, err := cli.MarshalJSON(resp.CellInfo) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -func commandGetCellsAliases(cmd *cobra.Command, args []string) error { - resp, err := client.GetCellsAliases(commandCtx, &vtctldatapb.GetCellsAliasesRequest{}) - if err != nil { - return err - } - - data, err := cli.MarshalJSON(resp.Aliases) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -func commandGetKeyspace(cmd *cobra.Command, args []string) error { - ks := cmd.Flags().Arg(0) - resp, err := client.GetKeyspace(commandCtx, &vtctldatapb.GetKeyspaceRequest{ - Keyspace: ks, - }) - - if err != nil { - return err - } - - fmt.Printf("%+v\n", resp.Keyspace) - - return nil -} - -func commandGetKeyspaces(cmd *cobra.Command, args []string) error { - resp, err := client.GetKeyspaces(commandCtx, &vtctldatapb.GetKeyspacesRequest{}) - if err != nil { - return err - } - - data, err := cli.MarshalJSON(resp.Keyspaces) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -func commandGetTablet(cmd *cobra.Command, args []string) error { - aliasStr := cmd.Flags().Arg(0) - alias, err := topoproto.ParseTabletAlias(aliasStr) - if err != nil { - return err - } - - resp, err := client.GetTablet(commandCtx, &vtctldatapb.GetTabletRequest{TabletAlias: alias}) - if err != nil { - return err - } - - data, err := cli.MarshalJSON(resp.Tablet) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - - return nil -} - -var getTabletsArgs = struct { - Cells []string - Keyspace string - Shard string - - Format string -}{} - -func commandGetTablets(cmd *cobra.Command, args []string) error { - format := strings.ToLower(getTabletsArgs.Format) - - switch format { - case "awk", "json": - default: - return fmt.Errorf("invalid output format, got %s", getTabletsArgs.Format) - } - - if getTabletsArgs.Keyspace == "" && getTabletsArgs.Shard != "" { - return fmt.Errorf("--shard (= %s) cannot be passed without also passing --keyspace", getTabletsArgs.Shard) - } - - resp, err := client.GetTablets(commandCtx, &vtctldatapb.GetTabletsRequest{ - Cells: getTabletsArgs.Cells, - Keyspace: getTabletsArgs.Keyspace, - Shard: getTabletsArgs.Shard, - }) - if err != nil { - return err - } - - switch format { - case "awk": - lineFn := func(t *topodatapb.Tablet) string { - ti := topo.TabletInfo{ - Tablet: t, - } - - keyspace := t.Keyspace - if keyspace == "" { - keyspace = "" - } - - shard := t.Shard - if shard == "" { - shard = "" - } - - mtst := "" - // special case for old primary that hasn't been updated in the topo - // yet. - if t.MasterTermStartTime != nil && t.MasterTermStartTime.Seconds > 0 { - mtst = logutil.ProtoToTime(t.MasterTermStartTime).Format(time.RFC3339) - } - - return fmt.Sprintf("%v %v %v %v %v %v %v %v", topoproto.TabletAliasString(t.Alias), keyspace, shard, topoproto.TabletTypeLString(t.Type), ti.Addr(), ti.MysqlAddr(), cli.MarshalMapAWK(t.Tags), mtst) - } - - for _, t := range resp.Tablets { - fmt.Println(lineFn(t)) - } - case "json": - data, err := cli.MarshalJSON(resp.Tablets) - if err != nil { - return err - } - - fmt.Printf("%s\n", data) - } - - return nil -} - -var initShardPrimaryArgs = struct { - WaitReplicasTimeout time.Duration - Force bool -}{} - -func commandInitShardPrimary(cmd *cobra.Command, args []string) error { - keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) - if err != nil { - return err - } - - tabletAlias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(1)) - if err != nil { - return err - } - - resp, err := client.InitShardPrimary(commandCtx, &vtctldatapb.InitShardPrimaryRequest{ - Keyspace: keyspace, - Shard: shard, - PrimaryElectTabletAlias: tabletAlias, - WaitReplicasTimeout: ptypes.DurationProto(initShardPrimaryArgs.WaitReplicasTimeout), - Force: initShardPrimaryArgs.Force, - }) - - for _, event := range resp.Events { - log.Infof("%v", event) - } - - return err -} - -func init() { - rootCmd.AddCommand(findAllShardsInKeyspaceCmd) - - rootCmd.AddCommand(getCellInfoNamesCmd) - rootCmd.AddCommand(getCellInfoCmd) - rootCmd.AddCommand(getCellsAliasesCmd) - - rootCmd.AddCommand(getKeyspaceCmd) - rootCmd.AddCommand(getKeyspacesCmd) - - rootCmd.AddCommand(getTabletCmd) - getTabletsCmd.Flags().StringSliceVarP(&getTabletsArgs.Cells, "cell", "c", nil, "TODO") - getTabletsCmd.Flags().StringVarP(&getTabletsArgs.Keyspace, "keyspace", "k", "", "TODO") - getTabletsCmd.Flags().StringVarP(&getTabletsArgs.Shard, "shard", "s", "", "TODO") - getTabletsCmd.Flags().StringVar(&getTabletsArgs.Format, "format", "awk", "Output format to use; valid choices are (json, awk)") - rootCmd.AddCommand(getTabletsCmd) - - initShardPrimaryCmd.Flags().DurationVar(&initShardPrimaryArgs.WaitReplicasTimeout, "wait-replicas-timeout", 30*time.Second, "time to wait for replicas to catch up in reparenting") - initShardPrimaryCmd.Flags().BoolVar(&initShardPrimaryArgs.Force, "force", false, "will force the reparent even if the provided tablet is not a master or the shard master") - rootCmd.AddCommand(initShardPrimaryCmd) -} diff --git a/go/cmd/vtctldclient/main.go b/go/cmd/vtctldclient/main.go index f00eee7a410..9086b289b8c 100644 --- a/go/cmd/vtctldclient/main.go +++ b/go/cmd/vtctldclient/main.go @@ -17,70 +17,19 @@ limitations under the License. package main import ( - "context" - "errors" "flag" - "io" "os" - "time" - - "github.com/spf13/cobra" + "vitess.io/vitess/go/cmd/vtctldclient/internal/command" "vitess.io/vitess/go/exit" - "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/vtctl/vtctldclient" -) - -var ( - client vtctldclient.VtctldClient - traceCloser io.Closer - commandCtx context.Context - commandCancel func() - - server string - actionTimeout time.Duration - - // We use cobra to make subcommands easier to manage. And do a hack below - // in main to grab the rest of the flags globally scattered to make sure we - // pick up things like common servenv flags, tracing flags, etc. Refer to - // commands.go for all of the subcommands. - rootCmd = &cobra.Command{ - // We use PersistentPreRun to set up the tracer, grpc client, and - // command context for every command. - PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { - traceCloser = trace.StartTracing("vtctldclient") - if server == "" { - err = errors.New("please specify -server to specify the vtctld server to connect to") - log.Error(err) - return err - } - - client, err = vtctldclient.New("grpc", server) - - commandCtx, commandCancel = context.WithTimeout(context.Background(), actionTimeout) - return err - }, - // Similarly, PersistentPostRun cleans up the resources spawned by - // PersistentPreRun. - PersistentPostRunE: func(cmd *cobra.Command, args []string) error { - commandCancel() - err := client.Close() - trace.LogErrorsWhenClosing(traceCloser) - return err - }, - TraverseChildren: true, - } ) func main() { defer exit.Recover() // Grab all those global flags across the codebase and shove 'em on in. - rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) - // Attach our local flags - rootCmd.PersistentFlags().StringVar(&server, "server", "", "server to use for connection") - rootCmd.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout for the total command") + command.Root.PersistentFlags().AddGoFlagSet(flag.CommandLine) // hack to get rid of an "ERROR: logging before flag.Parse" args := os.Args[:] @@ -89,7 +38,7 @@ func main() { os.Args = args // back to your regularly scheduled cobra programming - if err := rootCmd.Execute(); err != nil { + if err := command.Root.Execute(); err != nil { log.Error(err) exit.Return(1) }