Beispiel #1
0
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)
}
Beispiel #2
0
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
}
Beispiel #3
0
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)
}
Beispiel #4
0
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)
}
Beispiel #5
0
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)
}
Beispiel #6
0
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)
	}
}
Beispiel #7
0
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)
}
Beispiel #8
0
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)
}
Beispiel #9
0
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)
}
Beispiel #10
0
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
		}
	}
}
Beispiel #11
0
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)
}
Beispiel #12
0
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--
				}
			}
		}
	}
}