Skip to content

Commit

Permalink
Minor changes to common package usage
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Lord <[email protected]>
  • Loading branch information
mattlord committed Sep 11, 2023
1 parent 26f9e0b commit 256591f
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 151 deletions.
14 changes: 6 additions & 8 deletions go/cmd/vtctldclient/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ import (
"strconv"
"time"

common "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/common"
"github.com/spf13/cobra"

// these immports ensure init()s within them get called and they register their commands/subcommands.
// These imports ensure init()s within them get called and they register their commands/subcommands.
vreplcommon "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/common"
_ "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/movetables"
_ "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/reshard"
_ "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/workflow"

"github.com/spf13/cobra"

"vitess.io/vitess/go/trace"
"vitess.io/vitess/go/vt/logutil"
"vitess.io/vitess/go/vt/servenv"
Expand Down Expand Up @@ -67,8 +65,8 @@ var (
ctx = context.Background()
}
commandCtx, commandCancel = context.WithTimeout(ctx, actionTimeout)
common.SetClient(client)
common.SetCommandCtx(commandCtx)
vreplcommon.SetClient(client)
vreplcommon.SetCommandCtx(commandCtx)
return err
},
// Similarly, PersistentPostRun cleans up the resources spawned by
Expand Down Expand Up @@ -142,5 +140,5 @@ func getClientForCommand(cmd *cobra.Command) (vtctldclient.VtctldClient, error)
func init() {
Root.PersistentFlags().StringVar(&server, "server", "", "server to use for connection (required)")
Root.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout for the total command")
common.RegisterCommands(Root)
vreplcommon.RegisterCommands(Root)
}
6 changes: 3 additions & 3 deletions go/cmd/vtctldclient/command/vreplication/common/cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ func GetCancelCommand(opts *SubCommandsOpts) *cobra.Command {
}

func commandCancel(cmd *cobra.Command, args []string) error {
format, err := ParseAndValidateFormat(cmd, &CommonVROptions.VrCommonOptions)
format, err := GetOutputFormat(cmd)
if err != nil {
return err
}

cli.FinishedParsing(cmd)

req := &vtctldatapb.WorkflowDeleteRequest{
Keyspace: CommonVROptions.TargetKeyspace,
Workflow: CommonVROptions.Workflow,
Keyspace: BaseOptions.TargetKeyspace,
Workflow: BaseOptions.Workflow,
KeepData: cancelOptions.KeepData,
KeepRoutingRules: cancelOptions.KeepRoutingRules,
}
Expand Down
16 changes: 8 additions & 8 deletions go/cmd/vtctldclient/command/vreplication/common/complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata"
)

var completeOptions = struct {
var CompleteOptions = struct {
KeepData bool
KeepRoutingRules bool
RenameTables bool
Expand All @@ -32,19 +32,19 @@ func GetCompleteCommand(opts *SubCommandsOpts) *cobra.Command {
}

func commandComplete(cmd *cobra.Command, args []string) error {
format, err := ParseAndValidateFormat(cmd, &CommonVROptions.VrCommonOptions)
format, err := GetOutputFormat(cmd)
if err != nil {
return err
}
cli.FinishedParsing(cmd)

req := &vtctldatapb.MoveTablesCompleteRequest{
Workflow: CommonVROptions.Workflow,
TargetKeyspace: CommonVROptions.TargetKeyspace,
KeepData: completeOptions.KeepData,
KeepRoutingRules: completeOptions.KeepRoutingRules,
RenameTables: completeOptions.RenameTables,
DryRun: completeOptions.DryRun,
Workflow: BaseOptions.Workflow,
TargetKeyspace: BaseOptions.TargetKeyspace,
KeepData: CompleteOptions.KeepData,
KeepRoutingRules: CompleteOptions.KeepRoutingRules,
RenameTables: CompleteOptions.RenameTables,
DryRun: CompleteOptions.DryRun,
}
resp, err := GetClient().MoveTablesComplete(GetCommandCtx(), req)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions go/cmd/vtctldclient/command/vreplication/common/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func commandShow(cmd *cobra.Command, args []string) error {
cli.FinishedParsing(cmd)

req := &vtctldatapb.GetWorkflowsRequest{
Keyspace: CommonVROptions.TargetKeyspace,
Workflow: CommonVROptions.Workflow,
Keyspace: BaseOptions.TargetKeyspace,
Workflow: BaseOptions.Workflow,
}
resp, err := GetClient().GetWorkflows(GetCommandCtx(), req)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions go/cmd/vtctldclient/command/vreplication/common/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ func commandStatus(cmd *cobra.Command, args []string) error {
cli.FinishedParsing(cmd)

req := &vtctldatapb.WorkflowStatusRequest{
Keyspace: CommonVROptions.TargetKeyspace,
Workflow: CommonVROptions.Workflow,
Keyspace: BaseOptions.TargetKeyspace,
Workflow: BaseOptions.Workflow,
}
resp, err := GetClient().WorkflowStatus(GetCommandCtx(), req)
if err != nil {
Expand Down
28 changes: 14 additions & 14 deletions go/cmd/vtctldclient/command/vreplication/common/switchtraffic.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ func GetSwitchTrafficCommand(opts *SubCommandsOpts) *cobra.Command {
Aliases: []string{"switchtraffic"},
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
CommonSwitchTrafficOptions.Direction = workflow.DirectionForward
SwitchTrafficOptions.Direction = workflow.DirectionForward
if !cmd.Flags().Lookup("tablet-types").Changed {
// We switch traffic for all tablet types if none are provided.
CommonSwitchTrafficOptions.TabletTypes = []topodatapb.TabletType{
SwitchTrafficOptions.TabletTypes = []topodatapb.TabletType{
topodatapb.TabletType_PRIMARY,
topodatapb.TabletType_REPLICA,
topodatapb.TabletType_RDONLY,
Expand All @@ -64,10 +64,10 @@ func GetReverseTrafficCommand(opts *SubCommandsOpts) *cobra.Command {
Aliases: []string{"reversetraffic"},
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
CommonSwitchTrafficOptions.Direction = workflow.DirectionBackward
SwitchTrafficOptions.Direction = workflow.DirectionBackward
if !cmd.Flags().Lookup("tablet-types").Changed {
// We switch traffic for all tablet types if none are provided.
CommonSwitchTrafficOptions.TabletTypes = []topodatapb.TabletType{
SwitchTrafficOptions.TabletTypes = []topodatapb.TabletType{
topodatapb.TabletType_PRIMARY,
topodatapb.TabletType_REPLICA,
topodatapb.TabletType_RDONLY,
Expand All @@ -81,23 +81,23 @@ func GetReverseTrafficCommand(opts *SubCommandsOpts) *cobra.Command {
}

func commandSwitchTraffic(cmd *cobra.Command, args []string) error {
format, err := ParseAndValidateFormat(cmd, &CommonVROptions.VrCommonOptions)
format, err := GetOutputFormat(cmd)
if err != nil {
return err
}

cli.FinishedParsing(cmd)

req := &vtctldatapb.WorkflowSwitchTrafficRequest{
Keyspace: CommonVROptions.TargetKeyspace,
Workflow: CommonVROptions.Workflow,
TabletTypes: CommonSwitchTrafficOptions.TabletTypes,
MaxReplicationLagAllowed: protoutil.DurationToProto(CommonSwitchTrafficOptions.MaxReplicationLagAllowed),
Timeout: protoutil.DurationToProto(CommonSwitchTrafficOptions.Timeout),
DryRun: CommonSwitchTrafficOptions.DryRun,
EnableReverseReplication: CommonSwitchTrafficOptions.EnableReverseReplication,
InitializeTargetSequences: CommonSwitchTrafficOptions.InitializeTargetSequences,
Direction: int32(CommonSwitchTrafficOptions.Direction),
Keyspace: BaseOptions.TargetKeyspace,
Workflow: BaseOptions.Workflow,
TabletTypes: SwitchTrafficOptions.TabletTypes,
MaxReplicationLagAllowed: protoutil.DurationToProto(SwitchTrafficOptions.MaxReplicationLagAllowed),
Timeout: protoutil.DurationToProto(SwitchTrafficOptions.Timeout),
DryRun: SwitchTrafficOptions.DryRun,
EnableReverseReplication: SwitchTrafficOptions.EnableReverseReplication,
InitializeTargetSequences: SwitchTrafficOptions.InitializeTargetSequences,
Direction: int32(SwitchTrafficOptions.Direction),
}
resp, err := GetClient().WorkflowSwitchTraffic(GetCommandCtx(), req)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions go/cmd/vtctldclient/command/vreplication/common/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ import (
)

func bridgeToWorkflow(cmd *cobra.Command, args []string) {
workflowUpdateOptions.Workflow = CommonVROptions.Workflow
workflowOptions.Keyspace = CommonVROptions.TargetKeyspace
workflowUpdateOptions.Workflow = BaseOptions.Workflow
workflowOptions.Keyspace = BaseOptions.TargetKeyspace
}

var (
Expand Down
115 changes: 49 additions & 66 deletions go/cmd/vtctldclient/command/vreplication/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,20 @@ var (
MaxReplicationLagDefault = 30 * time.Second
TimeoutDefault = 30 * time.Second

// CommonVROptions are common options for all vreplication commands.
CommonVROptions = struct {
VrCommonOptions
BaseOptions = struct {
Workflow string
TargetKeyspace string
Format string
}{}

CommonVRCreateOptions = struct {
VrCreateCommonOptions
CreateOptions = struct {
Cells []string
TabletTypes []topodatapb.TabletType
TabletTypesInPreferenceOrder bool
OnDDL string
DeferSecondaryKeys bool
AutoStart bool
StopAfterCopy bool
}{}
)

Expand All @@ -70,22 +77,6 @@ func RegisterCommands(root *cobra.Command) {
}
}

type VrCommonOptions = struct {
Workflow string
TargetKeyspace string
Format string
}

type VrCreateCommonOptions = struct {
Cells []string
TabletTypes []topodatapb.TabletType
TabletTypesInPreferenceOrder bool
OnDDL string
DeferSecondaryKeys bool
AutoStart bool
StopAfterCopy bool
}

type SubCommandsOpts struct {
SubCommand string
Workflow string
Expand All @@ -107,57 +98,49 @@ func GetCommandCtx() context.Context {
return commandCtx
}

func ParseCells(cmd *cobra.Command, opts *VrCreateCommonOptions) {
func ParseCells(cmd *cobra.Command) {
if cmd.Flags().Lookup("cells").Changed { // Validate the provided value(s)
for i, cell := range opts.Cells { // Which only means trimming whitespace
opts.Cells[i] = strings.TrimSpace(cell)
for i, cell := range CreateOptions.Cells { // Which only means trimming whitespace
CreateOptions.Cells[i] = strings.TrimSpace(cell)
}
}
}

func ParseTabletTypes(cmd *cobra.Command, opts *VrCreateCommonOptions) {
func ParseTabletTypes(cmd *cobra.Command) {
if !cmd.Flags().Lookup("tablet-types").Changed {
opts.TabletTypes = tabletTypesDefault
CreateOptions.TabletTypes = tabletTypesDefault
}
}

func validateOnDDL(cmd *cobra.Command, opts *VrCreateCommonOptions) error {
if _, ok := binlogdatapb.OnDDLAction_value[strings.ToUpper(opts.OnDDL)]; !ok {
return fmt.Errorf("invalid on-ddl value: %s", opts.OnDDL)
func validateOnDDL(cmd *cobra.Command) error {
if _, ok := binlogdatapb.OnDDLAction_value[strings.ToUpper(CreateOptions.OnDDL)]; !ok {
return fmt.Errorf("invalid on-ddl value: %s", CreateOptions.OnDDL)
}
return nil
}

func ParseAndValidateCreateOptions(cmd *cobra.Command, opts *VrCreateCommonOptions) error {
if err := validateOnDDL(cmd, opts); err != nil {
func ParseAndValidateCreateOptions(cmd *cobra.Command) error {
if err := validateOnDDL(cmd); err != nil {
return err
}
ParseCells(cmd, opts)
ParseTabletTypes(cmd, opts)
ParseCells(cmd)
ParseTabletTypes(cmd)
return nil
}

func ParseAndValidateFormat(cmd *cobra.Command, opts *VrCommonOptions) (string, error) {
format := strings.ToLower(strings.TrimSpace(opts.Format))
func GetOutputFormat(cmd *cobra.Command) (string, error) {
format := strings.ToLower(strings.TrimSpace(BaseOptions.Format))
switch format {
case "text", "json":
return format, nil
default:
return "", fmt.Errorf("invalid output format, got %s", opts.Format)
}
}

func GetCommonOptions(cmd *cobra.Command, opts *VrCommonOptions) (string, error) {
format, err := ParseAndValidateFormat(cmd, opts)
if err != nil {
return "", err
return "", fmt.Errorf("invalid output format, got %s", BaseOptions.Format)
}
return format, nil
}

func GetCreateOptions(cmd *cobra.Command, opts *VrCreateCommonOptions) tabletmanagerdatapb.TabletSelectionPreference {
func GetTabletSelectionPreference(cmd *cobra.Command) tabletmanagerdatapb.TabletSelectionPreference {
tsp := tabletmanagerdatapb.TabletSelectionPreference_ANY
if opts.TabletTypesInPreferenceOrder {
if CreateOptions.TabletTypesInPreferenceOrder {
tsp = tabletmanagerdatapb.TabletSelectionPreference_INORDER
}
return tsp
Expand All @@ -174,12 +157,12 @@ func OutputStatusResponse(resp *vtctldatapb.WorkflowStatusResponse, format strin
} else {
tout := bytes.Buffer{}
tout.WriteString(fmt.Sprintf("The following vreplication streams exist for workflow %s.%s:\n\n",
CommonVROptions.TargetKeyspace, CommonVROptions.Workflow))
BaseOptions.TargetKeyspace, BaseOptions.Workflow))
for _, shardstreams := range resp.ShardStreams {
for _, shardstream := range shardstreams.Streams {
tablet := fmt.Sprintf("%s-%d", shardstream.Tablet.Cell, shardstream.Tablet.Uid)
tout.WriteString(fmt.Sprintf("id=%d on %s/%s: Status: %s. %s.\n",
shardstream.Id, CommonVROptions.TargetKeyspace, tablet, shardstream.Status, shardstream.Info))
shardstream.Id, BaseOptions.TargetKeyspace, tablet, shardstream.Status, shardstream.Info))
}
}
output = tout.Bytes()
Expand All @@ -189,24 +172,24 @@ func OutputStatusResponse(resp *vtctldatapb.WorkflowStatusResponse, format strin
}

func AddCommonFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&CommonVROptions.TargetKeyspace, "target-keyspace", "", "Target keyspace for this workflow exists (required)")
cmd.Flags().StringVar(&BaseOptions.TargetKeyspace, "target-keyspace", "", "Target keyspace for this workflow exists (required)")
cmd.MarkFlagRequired("target-keyspace")
cmd.Flags().StringVarP(&CommonVROptions.Workflow, "workflow", "w", "", "The workflow you want to perform the command on (required)")
cmd.Flags().StringVarP(&BaseOptions.Workflow, "workflow", "w", "", "The workflow you want to perform the command on (required)")
cmd.MarkFlagRequired("workflow")
cmd.Flags().StringVar(&CommonVROptions.Format, "format", "text", "The format of the output; supported formats are: text,json")
cmd.Flags().StringVar(&BaseOptions.Format, "format", "text", "The format of the output; supported formats are: text,json")
}

func AddCommonCreateFlags(cmd *cobra.Command) {
cmd.Flags().StringSliceVarP(&CommonVRCreateOptions.Cells, "cells", "c", nil, "Cells and/or CellAliases to copy table data from")
cmd.Flags().Var((*topoproto.TabletTypeListFlag)(&CommonVRCreateOptions.TabletTypes), "tablet-types", "Source tablet types to replicate table data from (e.g. PRIMARY,REPLICA,RDONLY)")
cmd.Flags().BoolVar(&CommonVRCreateOptions.TabletTypesInPreferenceOrder, "tablet-types-in-preference-order", true, "When performing source tablet selection, look for candidates in the type order as they are listed in the tablet-types flag")
cmd.Flags().StringVar(&CommonVRCreateOptions.OnDDL, "on-ddl", onDDLDefault, "What to do when DDL is encountered in the VReplication stream. Possible values are IGNORE, STOP, EXEC, and EXEC_IGNORE")
cmd.Flags().BoolVar(&CommonVRCreateOptions.DeferSecondaryKeys, "defer-secondary-keys", false, "Defer secondary index creation for a table until after it has been copied")
cmd.Flags().BoolVar(&CommonVRCreateOptions.AutoStart, "auto-start", true, "Start the MoveTables workflow after creating it")
cmd.Flags().BoolVar(&CommonVRCreateOptions.StopAfterCopy, "stop-after-copy", false, "Stop the MoveTables workflow after it's finished copying the existing rows and before it starts replicating changes")
cmd.Flags().StringSliceVarP(&CreateOptions.Cells, "cells", "c", nil, "Cells and/or CellAliases to copy table data from")
cmd.Flags().Var((*topoproto.TabletTypeListFlag)(&CreateOptions.TabletTypes), "tablet-types", "Source tablet types to replicate table data from (e.g. PRIMARY,REPLICA,RDONLY)")
cmd.Flags().BoolVar(&CreateOptions.TabletTypesInPreferenceOrder, "tablet-types-in-preference-order", true, "When performing source tablet selection, look for candidates in the type order as they are listed in the tablet-types flag")
cmd.Flags().StringVar(&CreateOptions.OnDDL, "on-ddl", onDDLDefault, "What to do when DDL is encountered in the VReplication stream. Possible values are IGNORE, STOP, EXEC, and EXEC_IGNORE")
cmd.Flags().BoolVar(&CreateOptions.DeferSecondaryKeys, "defer-secondary-keys", false, "Defer secondary index creation for a table until after it has been copied")
cmd.Flags().BoolVar(&CreateOptions.AutoStart, "auto-start", true, "Start the MoveTables workflow after creating it")
cmd.Flags().BoolVar(&CreateOptions.StopAfterCopy, "stop-after-copy", false, "Stop the MoveTables workflow after it's finished copying the existing rows and before it starts replicating changes")
}

var CommonSwitchTrafficOptions = struct {
var SwitchTrafficOptions = struct {
Cells []string
TabletTypes []topodatapb.TabletType
Timeout time.Duration
Expand All @@ -218,13 +201,13 @@ var CommonSwitchTrafficOptions = struct {
}{}

func AddCommonSwitchTrafficFlags(cmd *cobra.Command, initializeTargetSequences bool) {
cmd.Flags().StringSliceVarP(&CommonSwitchTrafficOptions.Cells, "cells", "c", nil, "Cells and/or CellAliases to switch traffic in")
cmd.Flags().Var((*topoproto.TabletTypeListFlag)(&CommonSwitchTrafficOptions.TabletTypes), "tablet-types", "Tablet types to switch traffic for")
cmd.Flags().DurationVar(&CommonSwitchTrafficOptions.Timeout, "timeout", TimeoutDefault, "Specifies the maximum time to wait, in seconds, for VReplication to catch up on primary tablets. The traffic switch will be cancelled on timeout.")
cmd.Flags().DurationVar(&CommonSwitchTrafficOptions.MaxReplicationLagAllowed, "max-replication-lag-allowed", MaxReplicationLagDefault, "Allow traffic to be switched only if VReplication lag is below this")
cmd.Flags().BoolVar(&CommonSwitchTrafficOptions.EnableReverseReplication, "enable-reverse-replication", true, "Setup replication going back to the original source keyspace to support rolling back the traffic cutover")
cmd.Flags().BoolVar(&CommonSwitchTrafficOptions.DryRun, "dry-run", false, "Print the actions that would be taken and report any known errors that would have occurred")
cmd.Flags().StringSliceVarP(&SwitchTrafficOptions.Cells, "cells", "c", nil, "Cells and/or CellAliases to switch traffic in")
cmd.Flags().Var((*topoproto.TabletTypeListFlag)(&SwitchTrafficOptions.TabletTypes), "tablet-types", "Tablet types to switch traffic for")
cmd.Flags().DurationVar(&SwitchTrafficOptions.Timeout, "timeout", TimeoutDefault, "Specifies the maximum time to wait, in seconds, for VReplication to catch up on primary tablets. The traffic switch will be cancelled on timeout.")
cmd.Flags().DurationVar(&SwitchTrafficOptions.MaxReplicationLagAllowed, "max-replication-lag-allowed", MaxReplicationLagDefault, "Allow traffic to be switched only if VReplication lag is below this")
cmd.Flags().BoolVar(&SwitchTrafficOptions.EnableReverseReplication, "enable-reverse-replication", true, "Setup replication going back to the original source keyspace to support rolling back the traffic cutover")
cmd.Flags().BoolVar(&SwitchTrafficOptions.DryRun, "dry-run", false, "Print the actions that would be taken and report any known errors that would have occurred")
if initializeTargetSequences {
cmd.Flags().BoolVar(&CommonSwitchTrafficOptions.InitializeTargetSequences, "initialize-target-sequences", false, "When moving tables from an unsharded keyspace to a sharded keyspace, initialize any sequences that are being used on the target when switching writes.")
cmd.Flags().BoolVar(&SwitchTrafficOptions.InitializeTargetSequences, "initialize-target-sequences", false, "When moving tables from an unsharded keyspace to a sharded keyspace, initialize any sequences that are being used on the target when switching writes.")
}
}
Loading

0 comments on commit 256591f

Please sign in to comment.