| | |
| | | import ( |
| | | "fmt" |
| | | "github.com/gin-gonic/gin" |
| | | "io/ioutil" |
| | | "net/http" |
| | | "strconv" |
| | | "strings" |
| | |
| | | ) |
| | | |
| | | const ( |
| | | StartServerScript = "seaweedfs_start.sh" |
| | | StopServerScript = "seaweedfs_stop.sh" |
| | | StartScriptAsVolume = "option=1" |
| | | StartScriptAsMaster = "option=2" |
| | | StartServerScript = "seaweedfs_start.sh" |
| | | StopServerScript = "seaweedfs_stop.sh" |
| | | //作为 volume 启动 |
| | | StartScriptAsVolume = "1" |
| | | //作为 master 启动 |
| | | StartScriptAsMaster = "2" |
| | | //作为 master + volume 启动 |
| | | StartScriptAsMaVo = "3" |
| | | //启动项参数头 |
| | | Option = "option=" |
| | | //master列表项参数头 |
| | | Peer = "peers=" |
| | | //StartScriptAsFiler = "option=4" |
| | | ) |
| | | |
| | | type SeaweedfsController struct{} |
| | |
| | | } |
| | | |
| | | func (sc *SeaweedfsController) UpdateSWFSServiceController(c *gin.Context) { |
| | | oldPeers := GetOldPeers(config.Server.ScriptPath, StartServerScript) |
| | | newPeers := GetNewPeers() |
| | | UpdatePeers(config.Server.ScriptPath, StartServerScript, oldPeers, newPeers) |
| | | ReplaceLineContentBySearch(StartScriptAsVolume, config.Server.ScriptPath, StartServerScript) |
| | | ReplaceLineContentBySearch(GetNewPeers(), Peer, config.Server.ScriptPath, StartServerScript) |
| | | util.ResponseFormat(c, code.Success, config.Server.EsServerIp+"更新成功") |
| | | } |
| | | |
| | | // @Security ApiKeyAuth |
| | |
| | | c.BindJSON(&body) |
| | | role := body.Role |
| | | if role == "master" { |
| | | AddNewMasterToPeers() |
| | | AsMaster() |
| | | util.ResponseFormat(c, code.AddSuccess, "加入节点成功") |
| | | return |
| | |
| | | util.ResponseFormat(c, code.AddClusterInfoErr, "当前还没有主节点") |
| | | return |
| | | } |
| | | } else if role == "master+volume" { |
| | | AsMaVo() |
| | | util.ResponseFormat(c, code.AddSuccess, "加入节点成功") |
| | | } else { |
| | | util.ResponseFormat(c, code.RequestParamError, "选择节点类型错误") |
| | | return |
| | |
| | | |
| | | } |
| | | |
| | | func (sc *SeaweedfsController) RoleOfVolumeToMasterController(c *gin.Context) { |
| | | func AsMaVo() { |
| | | AsMaster() |
| | | ReplaceLineContentBySearch(StartScriptAsMaVo, Option, config.Server.ScriptPath, StartServerScript) |
| | | } |
| | | |
| | | func (sc *SeaweedfsController) RestartMasterController(c *gin.Context) { |
| | | func (sc *SeaweedfsController) RoleOfVolumeToMasterController(c *gin.Context) { |
| | | AsMaster() |
| | | ReplaceLineContentBySearch(StartScriptAsMaVo, Option, config.Server.ScriptPath, StartServerScript) |
| | | } |
| | | |
| | | func (sc *SeaweedfsController) RestartServerController(c *gin.Context) { |
| | | StopServer(config.Server.ScriptPath) |
| | | time.Sleep(time.Second * 1) |
| | | StartServer(config.Server.ScriptPath) |
| | | result := strings.Split("=", GetLocalStartupItem(config.Server.ScriptPath, StartServerScript))[1] |
| | | util.ResponseFormat(c, code.Success, result) |
| | | } |
| | | |
| | | //启动服务 |
| | |
| | | } |
| | | |
| | | //根据搜索内容替换整行内容 |
| | | func ReplaceLineContentBySearch(replaceContent string, scriptPath string, scriptFile string) { |
| | | resContent := GetNowLineContent(scriptPath+"/"+scriptFile, "option=") |
| | | replaceStr := "sed -ie 's/" + resContent + "/" + replaceContent + "/g' " + scriptPath + "/" + scriptFile |
| | | func ReplaceLineContentBySearch(replaceContent string, searchContent string, scriptPath string, scriptFile string) { |
| | | resSearchContent := GetNowLineContent(scriptPath+"/"+scriptFile, searchContent) |
| | | replaceStr := "sed -ie 's/" + resSearchContent + "/" + replaceContent + "/g' " + scriptPath + "/" + scriptFile |
| | | util.RunScript(replaceStr) |
| | | } |
| | | |
| | |
| | | RestartAllServer(nowPeers, coreBaseUnit) |
| | | } |
| | | |
| | | //重启其他节点服务并验证 |
| | | func RestartServer(ip string, timeOut int) { |
| | | url := "http://" + ip + ":7020/node/api-v/swfs/restartMaster" |
| | | http.Get(url) |
| | | //重启所有节点服务并验证 |
| | | func Restart(ip string, timeOut int) { |
| | | url := "http://" + ip + ":7020/node/api-v/swfs/restartServer" |
| | | httpRes, _ := http.Get(url) |
| | | defer httpRes.Body.Close() |
| | | body, _ := ioutil.ReadAll(httpRes.Body) |
| | | startupItem := "" |
| | | if httpRes.StatusCode == 200 { |
| | | startupItem = string(body) |
| | | } |
| | | tick := time.Tick(1 * time.Second) |
| | | for countdown := timeOut; countdown > 0; countdown-- { |
| | | verificationMasterUrl := "http://" + ip + ":6333" |
| | | verificationVolume1Url := "http://" + ip + ":6700" |
| | | verificationVolume2Url := "http://" + ip + ":6701" |
| | | _, masterErr := http.Get(verificationMasterUrl) |
| | | _, volume1Err := http.Get(verificationVolume1Url) |
| | | _, volume2Err := http.Get(verificationVolume2Url) |
| | | if masterErr == nil && volume1Err == nil && volume2Err == nil { |
| | | break |
| | | } |
| | | Verification(startupItem, ip) |
| | | <-tick |
| | | } |
| | | } |
| | | |
| | | func Verification(startupItem string, ip string) { |
| | | switch startupItem { |
| | | case StartScriptAsVolume: |
| | | verificationVolumeUrl := "http://" + ip + ":6700" |
| | | _, volume1Err := http.Get(verificationVolumeUrl) |
| | | if volume1Err == nil { |
| | | break |
| | | } |
| | | case StartScriptAsMaster: |
| | | verificationMasterUrl := "http://" + ip + ":6333" |
| | | _, masterErr := http.Get(verificationMasterUrl) |
| | | if masterErr == nil { |
| | | break |
| | | } |
| | | case StartScriptAsMaVo: |
| | | verificationMasterUrl := "http://" + ip + ":6333" |
| | | verificationVolumeUrl := "http://" + ip + ":6700" |
| | | _, masterErr := http.Get(verificationMasterUrl) |
| | | _, volume1Err := http.Get(verificationVolumeUrl) |
| | | if masterErr == nil && volume1Err == nil { |
| | | break |
| | | } |
| | | } |
| | | } |
| | | |
| | | //获取本地启动项 |
| | | func GetLocalStartupItem(scriptPath string, scriptFile string) string { |
| | | startupItem := GetNowLineContent(scriptPath+"/"+scriptFile, Option) |
| | | fmt.Println(startupItem) |
| | | return startupItem |
| | | } |
| | | |
| | | //构建重启流程 |
| | |
| | | if (i+1)%coreThread == 0 { |
| | | masterIp = append(masterIp, strings.Split(ip, ":")[0]) |
| | | for i := 0; i < len(masterIp); i++ { |
| | | go RestartServer(masterIp[i], timeOut) |
| | | go Restart(masterIp[i], timeOut) |
| | | waitGroup.Add(1) //每创建一个goroutine,就把任务队列中任务的数量+1 |
| | | } |
| | | waitGroup.Wait() //.Wait()这里会发生阻塞,直到队列中所有的任务结束就会解除阻塞 |
| | |
| | | if len(nowPeers) == i+1 { |
| | | var waitGroup sync.WaitGroup |
| | | for i := 0; i < len(masterIp); i++ { |
| | | go RestartServer(masterIp[i], timeOut) |
| | | go Restart(masterIp[i], timeOut) |
| | | waitGroup.Add(1) //每创建一个goroutine,就把任务队列中任务的数量+1 |
| | | } |
| | | waitGroup.Wait() //.Wait()这里会发生阻塞,直到队列中所有的任务结束就会解除阻塞 |
| | |
| | | } |
| | | continue |
| | | } |
| | | } |
| | | |
| | | //获取本地以使用集群表单 |
| | | func GetOldPeers(scriptPath string, scriptFile string) string { |
| | | return GetNowLineContent(scriptPath+"/"+scriptFile, "peers=") |
| | | } |
| | | |
| | | //获取查找内容当前行内容 |
| | |
| | | if nowPeers == nil || len(nowPeers) == 0 { |
| | | return false |
| | | } |
| | | UpdatePeers(config.Server.ScriptPath, StartServerScript, GetNewPeers(), GetNewPeers()) |
| | | ReplaceLineContentBySearch(StartScriptAsVolume, config.Server.ScriptPath, StartServerScript) |
| | | ReplaceLineContentBySearch("peers=", config.Server.ScriptPath, StartServerScript) |
| | | ReplaceLineContentBySearch(StartScriptAsVolume, Option, config.Server.ScriptPath, StartServerScript) |
| | | ReplaceLineContentBySearch(GetNewPeers(), Peer, config.Server.ScriptPath, StartServerScript) |
| | | StartServer(config.Server.ScriptPath) |
| | | return true |
| | | } |
| | | |
| | | //作为主节点加入(默认包含数据节点) |
| | | func AsMaster() bool { |
| | | AddNewMasterToPeers() |
| | | nowPeers := GetNowPeersList() |
| | | RequestMasterNodesOperation(nowPeers) |
| | | return true |
| | |
| | | //获取当前集群列表格式化信息 |
| | | func GetNewPeers() string { |
| | | peers := GetNowPeersList() |
| | | p := "peers=" + strings.Replace(strings.Trim(fmt.Sprint(peers), "[]"), " ", ",", -1) |
| | | p := Peer + strings.Replace(strings.Trim(fmt.Sprint(peers), "[]"), " ", ",", -1) |
| | | return p |
| | | } |
| | | |
| | | //更新本地集群列表 |
| | | func UpdatePeers(scriptPath string, scriptFile string, oldPeers string, newPeers string) { |
| | | str := "sed -ie 's/" + oldPeers + "/" + newPeers + "/g' " + scriptPath + "/" + scriptFile |
| | | util.RunScript(str) |
| | | } |
| | | |
| | | //向集群加入新的master |