Пример #1
0
func appDelAction(c *cli.Context) {
	appname := c.String("d")
	super, err := context.CheckSuperPerm(context.Config.User)
	if err != nil {
		fmt.Println(err)
		return
	}
	if !super {
		fmt.Println("You have no permission to this operation")
		return
	}
	if appname == "" {
		appname = context.GetAppName()
	}

	fmt.Printf("Type %s to continue: ", "yes")
	var cmd string
	fmt.Scanf("%s\n", &cmd)
	if cmd != "yes" {
		return
	}
	_, version, err := context.GetApp(appname)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = context.DelApp(appname, version)
	if err != nil {
		fmt.Println(err)
		return
	} else {
		fmt.Printf("Delete %s success\n", appname)
	}
}
Пример #2
0
func appDelAction(c *cli.Context) {
	appname := context.GetAppName()

	fmt.Printf("Type %s to continue: ", "yes")
	var cmd string
	fmt.Scanf("%s\n", &cmd)
	if cmd != "yes" {
		return
	}
	_, version, err := context.GetApp(appname)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = context.DelApp(appname, version)
	if err != nil {
		fmt.Println(err)
		return
	} else {
		fmt.Printf("Delete %s success\n", appname)
	}
}
Пример #3
0
Файл: appmod.go Проект: ketor/cc
func appModAction(c *cli.Context) {
	appname := context.GetAppName()
	s := c.String("s")
	m := c.String("m")
	f := c.String("f")
	i := c.Int("i")
	r := c.String("r")
	R := c.String("R")
	k := c.Int("k")
	t := c.Int("t")

	appConfig := meta.AppConfig{}
	config, version, err := context.GetApp(appname)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = json.Unmarshal(config, &appConfig)
	if err != nil {
		fmt.Println(err)
		return
	}
	//update config if needed
	if s != "" {
		if s == "true" {
			appConfig.AutoEnableSlaveRead = true
		} else if s == "false" {
			appConfig.AutoEnableSlaveRead = false
		}
	}
	if m != "" {
		if m == "true" {
			appConfig.AutoEnableMasterWrite = true
		} else if m == "false" {
			appConfig.AutoEnableMasterWrite = false
		}
	}
	if f != "" {
		if f == "true" {
			appConfig.AutoFailover = true
		} else if f == "false" {
			appConfig.AutoFailover = false
		}
	}
	if i != -1 {
		appConfig.AutoFailoverInterval = time.Duration(i)
	}
	if r != "" {
		appConfig.MasterRegion = r
	}
	if R != "" {
		appConfig.Regions = strings.Split(R, ",")
	}
	if k != -1 {
		appConfig.MigrateKeysEachTime = k
	}
	if t != -1 {
		appConfig.MigrateTimeout = t
	}

	out, err := json.Marshal(appConfig)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = context.ModApp(appname, out, version)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("Mod %s success\n%s\n", appname, string(out))
}
Пример #4
0
func upgradeSlaves(c *cli.Context) {

	pid := context.GetAppName()
	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))

	iidx, err := getIdx(IdxServerAddr, pid, "slaves")
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Printf("Get last idx record: %d\n", iidx)
	for idx, rs := range rss.ReplicaSets {
		if rs.Master.IsArbiter() {
			continue
		}
		if idx <= iidx {
			fmt.Printf("Skipping replica(id:%s) (%d/%d) slaves\n", rs.Master.Id, idx, len(rss.ReplicaSets))
			continue
		}

		fmt.Printf("Upgrading replica(id:%s) (%d/%d) slaves\n", rs.Master.Id, idx, len(rss.ReplicaSets))
		for _, s := range rs.Slaves {

			//disable read
			_, err := configRead(s, false)
			if err != nil {
				fmt.Println(err)
			}
			fmt.Printf("Disable read %s\n", s.Addr())

			err = configAofAndRdb(s, false)
			if err != nil {
				fmt.Println(err)
			}
			fmt.Printf("Disable aof feature %s\n", s.Addr())

			//send shutdown command
			err = shutdownServer(s)
			if err != nil {
				fmt.Printf("server %s restart\n", s.Addr())
			}
			//sleep for 5 seconds
			time.Sleep(5 * time.Second)
		}
		//check slaves replica status and loading status
		inner := func(nodes []*topo.Node) bool {
			for _, n := range nodes {
				ok, err := checkSlaveRepliStatusOk(n)
				if err != nil {
					return false
				}
				if !ok {
					return false
				}
			}
			return true
		}
		cnt := 0
		for {
			ok := inner(rs.Slaves)
			if ok {
				break
			}
			cnt++
			fmt.Printf("Checking slaves replication status %d times\n", cnt)
			time.Sleep(5 * time.Second)
		}
		//enable slaves aof and read flag
		for _, s := range rs.Slaves {
			err := configAofAndRdb(s, true)
			if err != nil {
				fmt.Println(err)
			}
			_, err = configRead(s, true)
			if err != nil {
				fmt.Println(err)
			}
			fmt.Printf("Enable slaves %s aof and read flag\n", s.Addr())
		}
		//status ok, record the idx to a redis
		err := saveIdx(IdxServerAddr, pid, "slaves", idx)
		if err != nil {
			fmt.Printf("saveIdx to %d failed\n", idx)
		}
	}
}
Пример #5
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
		}
	}
}