func meetAction(c *cli.Context) { if len(c.Args()) != 1 { Put(ErrInvalidParameter) return } addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.NodeMeetPath nodeid, err := context.GetId(c.Args()[0]) if err != nil { Put(err) return } req := api.MeetNodeParams{ NodeId: nodeid, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { Put(err) return } ShowResponse(resp) }
func configRead(node *topo.Node, state bool) (*api.Response, error) { addr := context.GetLeaderAddr() //send failover command to new_master extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url_perm := "http://" + addr + api.NodePermPath req_disableread := api.ToggleModeParams{ NodeId: node.Id, Action: "disable", Perm: "read", } req_enableread := api.ToggleModeParams{ NodeId: node.Id, Action: "enable", Perm: "read", } var req api.ToggleModeParams if state { req = req_enableread } else { req = req_disableread } resp, err := utils.HttpPostExtra(url_perm, req, 5*time.Second, extraHeader) return resp, err }
func migrateRecoverAction(c *cli.Context) { if len(c.Args()) != 0 { fmt.Println(ErrInvalidParameter) return } addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.MigrateRecoverPath show := c.Bool("r") == false req := api.MigrateRecoverParams{ ShowOnly: show, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponseArray(resp) }
func takeoverAction(c *cli.Context) { if len(c.Args()) != 1 { fmt.Println(ErrInvalidParameter) return } addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.FailoverTakeoverPath nodeid, err := context.GetId(c.Args()[0]) if err != nil { fmt.Println(err) return } req := api.FailoverTakeoverParams{ NodeId: nodeid, } resp, err := utils.HttpPostExtra(url, req, 60*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponse(resp) }
func RenewToken() { addr := GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: Config.User, Role: Config.Role, Token: Config.Token, } url := "http://" + addr + api.UpdateTokenId utils.HttpPostExtra(url, nil, 10*time.Second, extraHeader) }
func rebalanceAction(c *cli.Context) { if len(c.Args()) != 0 { fmt.Println(ErrInvalidParameter) return } addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.RebalancePath method := c.String("m") ratio := c.Int("c") show := c.Bool("r") == false req := api.RebalanceParams{ Method: method, Ratio: ratio, ShowPlanOnly: show, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } for _, v := range resp.Body.([]interface{}) { sourceId := v.(map[string]interface{})["SourceId"] targetId := v.(map[string]interface{})["TargetId"] ranges := v.(map[string]interface{})["Ranges"] var rangesT topo.Ranges for _, r := range ranges.([]interface{}) { ri := r.(map[string]interface{}) left, _ := ri["Left"].(json.Number).Int64() right, _ := ri["Right"].(json.Number).Int64() rs := topo.Range{ Left: int(left), Right: int(right), } rangesT = append(rangesT, rs) } plan := fmt.Sprintf("%s => %s Ranges:%s", sourceId.(string), targetId.(string), rangesT.String()) fmt.Println(plan) } }
func migrateAction(c *cli.Context) { fmt.Println(c.Args()) if len(c.Args()) < 3 { fmt.Println(ErrInvalidParameter) return } addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.MigrateCreatePath snodeid, err := context.GetId(c.Args()[0]) if err != nil { fmt.Println(err) return } tnodeid, err := context.GetId(c.Args()[1]) if err != nil { fmt.Println(err) return } ranges := c.Args()[2:] req := api.MigrateParams{ SourceId: snodeid, TargetId: tnodeid, Ranges: ranges, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponse(resp) }
func doTaskAction(path, sourceId string) { addr := context.GetLeaderAddr() url := "http://" + addr + path nodeid, err := context.GetId(sourceId) if err != nil { Put(err) return } req := api.MigrateActionParams{ SourceId: nodeid, } extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { Put(err) return } ShowResponse(resp) }
func replicateAction(c *cli.Context) { if len(c.Args()) != 2 { fmt.Println(ErrInvalidParameter) return } addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.NodeReplicatePath cnodeid, err := context.GetId(c.Args()[0]) if err != nil { fmt.Println(err) return } pnodeid, err := context.GetId(c.Args()[1]) if err != nil { fmt.Println(err) return } req := api.ReplicateParams{ ChildId: cnodeid, ParentId: pnodeid, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponse(resp) }
func upgradeMaster(c *cli.Context) { pid := context.GetAppName() addr := context.GetLeaderAddr() url_fr := "http://" + addr + api.FetchReplicaSetsPath url_fl := "http://" + addr + api.NodeSetAsMasterPath extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } resp, err := utils.HttpGet(url_fr, nil, 5*time.Second) if err != nil { fmt.Println(err) return } var rss command.FetchReplicaSetsResult err = utils.InterfaceToStruct(resp.Body, &rss) if err != nil { fmt.Println(err) return } sort.Sort(topo.ByMasterId(rss.ReplicaSets)) sort.Sort(topo.ByNodeState(rss.ReplicaSets)) iidx, err := getIdx(IdxServerAddr, pid, "master") if err != nil { fmt.Println(err) return } fmt.Printf("Get last idx record: %d\n", iidx) var old_master *topo.Node var new_master *topo.Node //used to check status var new_slaves []*topo.Node old_master = nil new_master = nil for idx, rs := range rss.ReplicaSets { if rs.Master.IsArbiter() { continue } if idx <= iidx { fmt.Printf("Skipping replica(id:%s) (%d/%d) master\n", rs.Master.Id, idx, len(rss.ReplicaSets)) continue } //select a slave in the same IDC old_master = rs.Master old_master_r := getRegion(old_master) if old_master_r == "" { return } new_slaves = append(new_slaves, old_master) fmt.Printf("Upgrading replica(id:%s) (%d/%d) master\n", rs.Master.Id, idx, len(rss.ReplicaSets)) skip := false for _, s := range rs.Slaves { re := getRegion(s) if re == "" { return } if re == old_master_r && !skip { new_master = s skip = true } else { new_slaves = append(new_slaves, s) } } if new_master == nil { fmt.Printf("Select new master failed for master(%s) replica\n", old_master.Id) return } //send failover to the new master req := api.FailoverTakeoverParams{ NodeId: new_master.Id, } resp, err := utils.HttpPostExtra(url_fl, req, 10*time.Second, extraHeader) if err != nil { fmt.Println(err) return } if resp.Errno != 0 { fmt.Println(resp.Errmsg) return } //send failover request done,check the new_master role to a real master for { ismaster, err := checkMasterRole(new_master, true) if err != nil { fmt.Println(err) time.Sleep(10 * time.Second) continue } if ismaster == true { //to be a new master break } else { //wait for next check time.Sleep(10 * time.Second) } } //disable read flag of the all new slaves,including old master for _, s := range new_slaves { resp, err = configRead(s, false) if err != nil { fmt.Println(err) return } if resp.Errno != 0 { fmt.Println(resp.Errmsg) return } } //disable aof and rdb to speed up start err = configAofAndRdb(old_master, false) if err != nil { fmt.Println(err) return } //shutdown server err = shutdownServer(old_master) if err != nil { fmt.Printf("server %s restart\n", old_master.Addr()) } //check the status of old master cnt := 1 for { fmt.Printf("Check slave status %d times\n", cnt) cnt++ inner := func(nodes []*topo.Node) bool { rok := true for _, n := range nodes { ok, err := checkSlaveRepliStatusOk(n) if ok { //replica status ok,enable read flag,ignore result configRead(n, true) continue } if !ok || err != nil { rok = false } } return rok } ok := inner(new_slaves) if !ok { //not ok, wait for next trun check time.Sleep(10 * time.Second) } else { break } } //enable aof and rdb err = configAofAndRdb(old_master, true) if err != nil { fmt.Println(err) return } //save the idx of the process err = saveIdx(IdxServerAddr, pid, "master", idx) if err != nil { fmt.Println(err) return } } }
func chmodAction(c *cli.Context) { r := c.Bool("r") w := c.Bool("w") addr := context.GetLeaderAddr() extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url := "http://" + addr + api.NodePermPath var act string var nodeid string var action string var perm string var err error //-r -w if r || w { if len(c.Args()) != 1 || r == w { fmt.Println(ErrInvalidParameter) return } action = "disable" nodeid, err = context.GetId(c.Args()[0]) if err != nil { fmt.Println(err) return } if r { perm = "read" } else { perm = "write" } } else { //+r +w if len(c.Args()) != 2 { fmt.Println(ErrInvalidParameter) return } act = c.Args()[0] if string(act[0]) == "+" { action = "enable" nodeid, err = context.GetId(c.Args()[1]) if err != nil { fmt.Println(err) return } if string(act[1]) == "r" { perm = "read" } else if string(act[1]) == "w" { perm = "write" } else { fmt.Println(ErrInvalidParameter) return } } else { fmt.Println(ErrInvalidParameter) return } } req := api.ToggleModeParams{ NodeId: nodeid, Action: action, Perm: perm, } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponse(resp) }
func disableDuplicatedAction(c *cli.Context) { region := c.String("r") zone := c.String("z") if region == "" && zone == "" { fmt.Println("region or zone should be assigned") return } if region != "" && zone != "" { fmt.Println("region or zone should be choose one") return } limit := c.Int("l") if limit < 1 { fmt.Println("limit should be >=1 ") return } addr := context.GetLeaderAddr() url := "http://" + addr + api.FetchReplicaSetsPath resp, err := utils.HttpGet(url, nil, 5*time.Second) if err != nil { fmt.Println(err) return } var rss command.FetchReplicaSetsResult err = utils.InterfaceToStruct(resp.Body, &rss) if err != nil { fmt.Println(err) return } sort.Sort(topo.ByMasterId(rss.ReplicaSets)) sort.Sort(topo.ByNodeState(rss.ReplicaSets)) extraHeader := &utils.ExtraHeader{ User: context.Config.User, Role: context.Config.Role, Token: context.Config.Token, } url = "http://" + addr + api.NodePermPath for _, rs := range rss.ReplicaSets { rlimit := limit if region != "" { n := rs.Master if n.Region == region { rlimit-- } //slaves for _, ns := range rs.Slaves { if rlimit <= 0 && ns.Region == region { //chmod -r fmt.Printf("Disable node addr: %s region: %s\n", ns.Addr(), ns.Region) req := api.ToggleModeParams{ NodeId: ns.Id, Action: "disable", Perm: "read", } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponse(resp) } if ns.Region == region { rlimit-- } } } else { n := rs.Master if n.Zone == zone { rlimit-- } //slaves for _, ns := range rs.Slaves { if rlimit <= 0 && ns.Zone == zone { //chmod -r fmt.Printf("Disable node addr: %s zone: %s\n", ns.Addr(), ns.Zone) req := api.ToggleModeParams{ NodeId: ns.Id, Action: "disable", Perm: "read", } resp, err := utils.HttpPostExtra(url, req, 5*time.Second, extraHeader) if err != nil { fmt.Println(err) return } ShowResponse(resp) } if ns.Zone == zone { rlimit-- } } } } }