Example #1
0
func register(rwMutex *sync.RWMutex, domain, name string, proxys map[string]*structs.ProxyInfo, topology *structs.Topology, conn net.Conn, msg *message, cs *consul.Consul) error {
	var pi structs.ProxyInfo
	err := json.Unmarshal([]byte(msg.Body), &pi)
	if err != nil {
		return err
	}

	rwMutex.Lock()
	proxys[msg.From].StartupTime = pi.StartupTime
	proxys[msg.From].ClientAddress = pi.ClientAddress
	proxys[msg.From].ProxyAddress = pi.ProxyAddress
	proxys[msg.From].ActiveTime = time.Now().Unix()
	proxys[msg.From].Status = consts.ProxyOK
	rwMutex.Unlock()

	rp := reply{
		Version: topology.Version,
	}
	b, err := json.Marshal(&rp)
	if err != nil {
		return err
	}
	err = sendMessage(domain, "register", name, string(b), conn)
	if err != nil {
		return err
	}

	rwMutex.RLock()
	bproxy, _ := json.Marshal(proxys)
	rwMutex.RUnlock()
	// push to consul
	prefix := domain + "/" + name + "/"
	err = cs.PutVal(prefix+consts.ProxyKey, bproxy)
	if err != nil {
		log.WithFields(log.Fields{
			"key": prefix + consts.ProxyKey,
			"val": string(bproxy),
			"err": err.Error(),
		}).Error("push proxy to consul fail, continue")
	}
	err = presistent.ProxyPresist(string(bproxy))
	if err != nil {
		log.WithFields(log.Fields{
			"val": string(bproxy),
			"err": err.Error(),
		}).Error("proxy presist fail, continue")
	}

	return nil
}
Example #2
0
func setProxys(w http.ResponseWriter, req *http.Request) {
	log.WithFields(log.Fields{
		"RemoteAddr": req.RemoteAddr,
		"URL":        req.URL,
	}).Info("handle `/proxys` start")
	var err error
	defer func() {
		log.WithFields(log.Fields{
			"RemoteAddr": req.RemoteAddr,
			"URL":        req.URL,
		}).Info("handle `/proxys` end")
		if err != nil {
			w.Write([]byte(err.Error()))
		}
	}()
	var proxyNames []string
	if err := json.NewDecoder(req.Body).Decode(&proxyNames); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	sm.rwMutex.Lock()
	for _, proxyName := range proxyNames {
		sm.proxys[proxyName] = &structs.ProxyInfo{}
	}
	bproxy, _ := json.Marshal(sm.proxys)
	sm.rwMutex.Unlock()
	err = sm.consul.PutVal(prefix+consts.ProxyKey, bproxy)
	if err != nil {
		log.WithFields(log.Fields{
			"key": prefix + consts.ProxyKey,
			"val": string(bproxy),
			"err": err.Error(),
		}).Error("push proxy to consul fail, continue")
	}
	err = presistent.ProxyPresist(string(bproxy))
	if err != nil {
		log.WithFields(log.Fields{
			"val": string(bproxy),
			"err": err.Error(),
		}).Error("proxy presist fail, continue")
	}

	w.WriteHeader(http.StatusOK)
}
Example #3
0
File: sm.go Project: yiduoyunQ/sm
// no need lock
func NewSwitchManager(context *cli.Context) error {
	config, err := NewConfig(context)
	if err != nil {
		return err
	}
	sm = &switchManager{
		config:  config,
		rwMutex: new(sync.RWMutex),
		steps:   []string{},
		closed:  true,
	}

	if sm.config.Domain == "" {
		return errors.New("need Domain specify")
	}
	if sm.config.Name == "" {
		return errors.New("need Name specify")
	}
	if sm.config.Port == "" {
		return errors.New("need Port specify")
	}
	if sm.config.ProxyPort == "" {
		return errors.New("need ProxyPort specify")
	}

	prefix = sm.config.Domain + "/" + sm.config.Name + "/"

	cs, err := consul.NewConsul(context)
	if err != nil {
		sm.steps = append(sm.steps, fmt.Sprintf("Step1. New Consul fail:%s\n", err.Error()))
		return err
	}
	sm.steps = append(sm.steps, "Step1. New Consul success\n")
	sm.consul = cs
	swm, err := swarm.NewSwarm(context, cs)
	if err != nil {
		sm.steps = append(sm.steps, fmt.Sprintf("Step2. New Swarm fail:%s\n", err.Error()))
		return err
	}
	sm.steps = append(sm.steps, "Step2. New Swarm success\n")
	sm.swarm = swm

	// init from consul
	isInitalized, err := sm.consul.GetVal(prefix + consts.InitKey)
	if err == nil && isInitalized == "true" {
		log.Info("init from consul")
		err = initProxy()
		if err != nil {
			log.WithFields(log.Fields{
				"err:": err.Error(),
			}).Error("pull proxy from consul fail, return")
			sm.steps = append(sm.steps, fmt.Sprintf("Step3. Init from consul fail:%s\n", err.Error()))
			return err
		}
		err = initTopo()
		if err != nil {
			log.WithFields(log.Fields{
				"err:": err.Error(),
			}).Error("pull topology from consul fail, continue")
			sm.steps = append(sm.steps, fmt.Sprintf("Step3. Init from consul fail:%s\n", err.Error()))
			return err
		}
		err = initSwarm()
		if err != nil {
			log.WithFields(log.Fields{
				"err:": err.Error(),
			}).Error("pull swarm from consul fail, continue")
			sm.steps = append(sm.steps, fmt.Sprintf("Step3. Init from consul fail:%s\n", err.Error()))
			return err
		}
		sm.steps = append(sm.steps, "Step3. Init from consul success\n")
	} else {
		sm.steps = append(sm.steps, "Step3. No init from consul\n")
	}

	sm.closed = false
	sm.state = 0

	// recover action no need lock
	actionVal, err := sm.consul.GetVal(prefix + consts.ActionKey)
	if actionVal != "" {
		log.Info("recover action:%s\n", actionVal)
		split := strings.Split(actionVal, ",")
		actionVal := split[0]
		name := split[1]
		if actionVal == consts.ActionIsolateProxyVal {
			if sm.proxys[name].Status != consts.ProxyClose {
				err = CloseProxy(name)
				if err != nil {
					sm.steps = append(sm.steps, fmt.Sprintf("Step4. Init recover action %s fail:%s\n", actionVal, err.Error()))
					return err
				}
				bproxys, _ := json.Marshal(sm.proxys)
				err = sm.consul.PutVal(prefix+consts.ProxyKey, bproxys)
				if err != nil {
					log.WithFields(log.Fields{
						"key": prefix + consts.ProxyKey,
						"val": string(bproxys),
						"err": err.Error(),
					}).Error("push proxy to consul fail, continue")
				}
				err = presistent.ProxyPresist(string(bproxys))
				if err != nil {
					log.WithFields(log.Fields{
						"val": string(bproxys),
						"err": err.Error(),
					}).Error("proxy presist fail, continue")
				}
			}
			err := sm.consul.PutVal(prefix+consts.ActionKey, []byte(""))
			if err != nil {
				log.WithFields(log.Fields{
					"key": prefix + consts.ActionKey,
					"val": "",
					"err": err.Error(),
				}).Error("push action key to consul fail, continue")
			}
			sm.steps = append(sm.steps, "Step4. Init recover action %s success\n")
		} else if actionVal == consts.ActionIsolateDbVal {
			if sm.topology.DataNodeGroup["default"][name].Status != consts.Abnormal {
				err, _ = ha.IsolateDB(name, sm.rwMutex, sm.topology, sm.swarm)
				if err != nil {
					sm.steps = append(sm.steps, fmt.Sprintf("Step4. Init recover action %s fail:%s\n", actionVal, err.Error()))
					return err
				}
				btopology, _ := json.Marshal(sm.topology)
				err = sm.consul.PutVal(prefix+consts.TopologyKey, btopology)
				if err != nil {
					log.WithFields(log.Fields{
						"key": prefix + consts.TopologyKey,
						"val": string(btopology),
						"err": err.Error(),
					}).Error("push topology to consul fail, continue")
				}
				err = presistent.TopologyPresist(string(btopology))
				if err != nil {
					log.WithFields(log.Fields{
						"val": string(btopology),
						"err": err.Error(),
					}).Error("topology presist fail, continue")
				}
			}
			err := sm.consul.PutVal(prefix+consts.ActionKey, []byte(""))
			if err != nil {
				log.WithFields(log.Fields{
					"key": prefix + consts.ActionKey,
					"val": "",
					"err": err.Error(),
				}).Error("push action key to consul fail, continue")
			}
			sm.steps = append(sm.steps, "Step4. Init recover action %s success\n")
		} else if actionVal == consts.ActionRecoverDbVal {
			if sm.topology.DataNodeGroup["default"][name].Status != consts.Normal {
				err, _ = ha.RecoverDb(name, sm.rwMutex, sm.topology, sm.swarm)
				if err != nil {
					sm.steps = append(sm.steps, fmt.Sprintf("Step4. Init recover action %s fail:%s\n", actionVal, err.Error()))
					return err
				}
				btopology, _ := json.Marshal(sm.topology)
				err = sm.consul.PutVal(prefix+consts.TopologyKey, btopology)
				if err != nil {
					log.WithFields(log.Fields{
						"key": prefix + consts.TopologyKey,
						"val": string(btopology),
						"err": err.Error(),
					}).Error("push topology to consul fail, continue")
				}
				err = presistent.TopologyPresist(string(btopology))
				if err != nil {
					log.WithFields(log.Fields{
						"val": string(btopology),
						"err": err.Error(),
					}).Error("topology presist fail, continue")
				}
			}
			err := sm.consul.PutVal(prefix+consts.ActionKey, []byte(""))
			if err != nil {
				log.WithFields(log.Fields{
					"key": prefix + consts.ActionKey,
					"val": "",
					"err": err.Error(),
				}).Error("push action key to consul fail, continue")
			}
			sm.steps = append(sm.steps, "Step4. Init recover action %s success\n")
		}
	} else {
		sm.steps = append(sm.steps, "Step4. No init recover action\n")
	}

	log.Info("sm init success")

	return nil
}
Example #4
0
func recover(w http.ResponseWriter, req *http.Request) {
	var steps []string
	vars := mux.Vars(req)
	n := vars["name"]
	log.WithFields(log.Fields{
		"RemoteAddr": req.RemoteAddr,
		"URL":        req.URL,
		"Name":       n,
	}).Info("handle `/recover/{name}` start")
	var err error
	defer func() {
		log.WithFields(log.Fields{
			"RemoteAddr": req.RemoteAddr,
			"URL":        req.URL,
			"Name":       n,
		}).Info("handle `/recover/{name}` end")

		if err != nil {
			w.Write([]byte(err.Error()))
		}

		if len(sm.steps) != 0 {
			s := ""
			for _, v := range steps {
				s = s + v
			}
			w.Write([]byte(s))
		}

		atomic.CompareAndSwapInt64(&sm.state, 2, 0)
	}()

	if !getLock(2) {
		w.WriteHeader(http.StatusNotModified)
		err = errors.New("http recover get lock fail")
		return
	}

	var t string
	sm.rwMutex.RLock()
	_, ok := sm.proxys[n]
	if ok {
		if sm.proxys[n].Status != consts.ProxyClose {
			w.WriteHeader(http.StatusBadRequest)
		} else {
			t = consts.Type_Proxy
		}

	} else {
		_, ok = sm.topology.DataNodeGroup["default"][n]
		if ok {
			status := sm.topology.DataNodeGroup["default"][n].Status
			if status == consts.Abnormal {
				t = consts.Type_Db
			} else {
				w.WriteHeader(http.StatusBadRequest)
			}
		}
	}
	sm.rwMutex.RUnlock()

	if t == consts.Type_Proxy {
		sm.rwMutex.Lock()
		if ok := sm.swarm.UpproxyStart(n); !ok {
			sm.rwMutex.Unlock()
			return
		}
		sm.proxys[n] = &structs.ProxyInfo{}
		bproxy, _ := json.Marshal(sm.proxys)
		sm.rwMutex.Unlock()
		err = sm.consul.PutVal(prefix+consts.ProxyKey, bproxy)
		if err != nil {
			log.WithFields(log.Fields{
				"key": prefix + consts.ProxyKey,
				"val": string(bproxy),
				"err": err.Error(),
			}).Error("push proxy to consul fail, continue")
		}
		err = presistent.ProxyPresist(string(bproxy))
		if err != nil {
			log.WithFields(log.Fields{
				"val": string(bproxy),
				"err": err.Error(),
			}).Error("proxy presist fail, continue")
		}

		w.WriteHeader(http.StatusOK)
	} else if t == consts.Type_Db {
		err = sm.consul.PutVal(prefix+consts.ActionKey, []byte(consts.ActionRecoverDbVal+","+n))
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		err, steps = ha.RecoverDb(n, sm.rwMutex, sm.topology, sm.swarm)
		sm.steps = steps
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
		} else {
			w.WriteHeader(http.StatusOK)
		}
		sm.rwMutex.RLock()
		btopology, _ := json.Marshal(sm.topology)
		sm.rwMutex.RUnlock()
		err = sm.consul.PutVal(prefix+consts.TopologyKey, btopology)
		if err != nil {
			log.WithFields(log.Fields{
				"key": prefix + consts.TopologyKey,
				"val": string(btopology),
				"err": err.Error(),
			}).Error("push topology to consul fail, continue")
		}
		err = presistent.TopologyPresist(string(btopology))
		if err != nil {
			log.WithFields(log.Fields{
				"val": string(btopology),
				"err": err.Error(),
			}).Error("topology presist fail, continue")
		}
		err = sm.consul.PutVal(prefix+consts.ActionKey, []byte(""))
		if err != nil {
			log.WithFields(log.Fields{
				"key": prefix + consts.ActionKey,
				"val": "",
				"err": err.Error(),
			}).Error("push action key to consul fail, continue")
		}
	} else {
		w.WriteHeader(http.StatusBadRequest)
		err = errors.New(http.StatusText(http.StatusBadRequest))
	}

}
Example #5
0
func initSm(w http.ResponseWriter, req *http.Request) {
	log.WithFields(log.Fields{
		"RemoteAddr": req.RemoteAddr,
		"URL":        req.URL,
	}).Info("handle `/init` start")
	var err error
	var steps []string
	defer func() {
		log.WithFields(log.Fields{
			"RemoteAddr": req.RemoteAddr,
			"URL":        req.URL,
		}).Info("handle `/init` end")

		if err != nil {
			log.Error(err)
			w.Write([]byte(err.Error()))
		}

		if len(sm.steps) != 0 {
			s := ""
			for _, v := range steps {
				s = s + v
			}
			w.Write([]byte(s))
		}
		atomic.CompareAndSwapInt64(&sm.state, 2, 0)
	}()

	if !getLock(2) {
		err = errors.New("init get lock fail")
		return
	}

	var mgmPost structs.MgmPost
	if err = json.NewDecoder(req.Body).Decode(&mgmPost); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	log.WithFields(log.Fields{
		"mgmPost": mgmPost,
	}).Infoln("******mgmPost**********")

	proxys := make(map[string]*structs.ProxyInfo)
	for _, proxyName := range mgmPost.ProxyNames {
		proxys[proxyName] = &structs.ProxyInfo{}
	}

	sm.rwMutex.Lock()
	sm.swarm.ApiVersion = mgmPost.SwarmApiVersion
	sm.swarm.DbRootUser = mgmPost.DbRootUser
	sm.swarm.DbRootPassword = mgmPost.DbRootPassword
	sm.swarm.DbReplicateUser = mgmPost.DbReplicateUser
	sm.swarm.DbReplicatePassword = mgmPost.DbReplicatePassword
	sm.rwMutex.Unlock()

	var topo *structs.Topology
	topo, err, steps = ha.InitTopo(mgmPost, sm.swarm)
	sm.steps = steps
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	sm.rwMutex.Lock()
	sm.proxys = proxys
	sm.topology = topo
	sm.rwMutex.Unlock()

	w.WriteHeader(http.StatusOK)

	bproxy, _ := json.Marshal(proxys)
	// push to consul
	err = sm.consul.PutVal(prefix+consts.ProxyKey, bproxy)
	if err != nil {
		log.WithFields(log.Fields{
			"key": prefix + consts.ProxyKey,
			"val": string(bproxy),
			"err": err.Error(),
		}).Error("push proxy to consul fail, continue")
	}
	err = presistent.ProxyPresist(string(bproxy))
	if err != nil {
		log.WithFields(log.Fields{
			"val": string(bproxy),
			"err": err.Error(),
		}).Error("proxy presist fail, continue")
	}

	btopology, _ := json.Marshal(topo)
	err = sm.consul.PutVal(prefix+consts.TopologyKey, btopology)
	if err != nil {
		log.WithFields(log.Fields{
			"key": prefix + consts.TopologyKey,
			"val": string(btopology),
			"err": err.Error(),
		}).Error("push topology to consul fail, continue")
	}
	err = presistent.TopologyPresist(string(btopology))
	if err != nil {
		log.WithFields(log.Fields{
			"val": string(btopology),
			"err": err.Error(),
		}).Error("topology presist fail, continue")
	}

	bswarm, _ := json.Marshal(sm.swarm)
	err = sm.consul.PutVal(prefix+consts.SwarmKey, bswarm)
	if err != nil {
		log.WithFields(log.Fields{
			"key": prefix + consts.SwarmKey,
			"val": string(bswarm),
			"err": err.Error(),
		}).Error("push swarm to consul fail, continue")
	}
	err = presistent.SwarmPresist(string(bswarm))
	if err != nil {
		log.WithFields(log.Fields{
			"val": string(bswarm),
			"err": err.Error(),
		}).Error("swarm presist fail, continue")
	}

	err = sm.consul.PutVal(prefix+consts.InitKey, []byte("true"))
	if err != nil {
		log.WithFields(log.Fields{
			"key": prefix + consts.InitKey,
			"val": "true",
			"err": err.Error(),
		}).Error("push init key to consul fail, continue")
	}
}