Skip to content

Commit

Permalink
kubectl-moco: add switchover subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
ymmt2005 committed Apr 30, 2021
1 parent f6fb39f commit f349f5e
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cmd/kubectl-moco/cmd/credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var credentialConfig struct {

// credentialCmd represents the credential command
var credentialCmd = &cobra.Command{
Use: "credential <CLUSTER_NAME>",
Use: "credential CLUSTER_NAME",
Short: "Fetch the credential of a specified user",
Long: "Fetch the credential of a specified user.",
Args: cobra.ExactArgs(1),
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubectl-moco/cmd/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var mysqlConfig struct {

// mysqlCmd represents the mysql command
var mysqlCmd = &cobra.Command{
Use: "mysql <CLUSTER_NAME> [COMMANDS]",
Use: "mysql CLUSTER_NAME -- [COMMANDS]",
Short: "Run mysql command in a specified MySQL instance",
Long: "Run mysql command in a specified MySQL instance.",
Args: cobra.MinimumNArgs(1),
Expand Down
50 changes: 50 additions & 0 deletions cmd/kubectl-moco/cmd/switchover.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cmd

import (
"context"
"errors"

mocov1beta1 "github.com/cybozu-go/moco/api/v1beta1"
"github.com/cybozu-go/moco/pkg/constants"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
)

var switchoverCmd = &cobra.Command{
Use: "switchover CLUSTER_NAME",
Short: "Switch the primary instance",
Long: "Switch the primary instance to one of the replicas.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return switchover(cmd.Context(), args[0])
},
}

func switchover(ctx context.Context, name string) error {
cluster := &mocov1beta1.MySQLCluster{}
if err := kubeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: name}, cluster); err != nil {
return err
}

if cluster.Spec.Replicas == 1 {
return errors.New("single-instance cluster is not able to switch")
}

podName := cluster.PodName(cluster.Status.CurrentPrimaryIndex)
pod := &corev1.Pod{}
if err := kubeClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: podName}, pod); err != nil {
return err
}

if pod.Annotations == nil {
pod.Annotations = make(map[string]string)
}
pod.Annotations[constants.AnnDemote] = "true"

return kubeClient.Update(ctx, pod)
}

func init() {
rootCmd.AddCommand(switchoverCmd)
}
4 changes: 4 additions & 0 deletions docs/kubectl-moco.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ Fetch the credential information of a specified user
| ------------------ | --------------- | ------------------------------------------ |
| `-u, --mysql-user` | `moco-readonly` | Fetch the credential of the specified user |
| `--format` | `plain` | Output format: `plain` or `mycnf` |

## `kubectl moco switchover CLUSTER_NAME`

Switch the primary instance to one of the replicas.
7 changes: 2 additions & 5 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,8 @@ Switchver is an operation to change the live primary to one of the replicas.

MOCO automatically switch the primary when the Pod of the primary instance is to be deleted.

Users can manually trigger a switchover by annotating the Pod of the primary instance with `moco.cybozu.com/demote: true`. You can use `kubectl` to do this:

```console
$ kubectl annotate mysqlcluster <name> moco.cybozu.com/demote=true
```
Users can manually trigger a switchover with `kubectl moco switchover CLUSTER_NAME`.
Read [`kubectl-moco.md`](kubectl-moco.md) for details.

### Failover

Expand Down
2 changes: 1 addition & 1 deletion e2e/replication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ var _ = Context("replication", func() {
})

It("should switch the primary if requested", func() {
kubectlSafe(nil, "-n", "repl", "annotate", "pod", "moco-test-0", "moco.cybozu.com/demote=true")
kubectlSafe(nil, "moco", "-n", "repl", "switchover", "test")
Eventually(func() int {
cluster, err := getCluster("repl", "test")
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion e2e/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ var _ = Context("upgrade", func() {
fmt.Printf("The current primary = %d\n", primary)

By("doing a switchover")
kubectlSafe(nil, "annotate", "-n", "upgrade", "pod", cluster.PodName(primary), "moco.cybozu.com/demote=true")
kubectlSafe(nil, "moco", "-n", "upgrade", "switchover", "test")
Eventually(func() error {
var err error
cluster, err = getCluster("upgrade", "test")
Expand Down

0 comments on commit f349f5e

Please sign in to comment.