Commit bc010eaf authored by szh's avatar szh

节点操作接口 改成消息机制 支持任务查询情况

parent 87b7d166
...@@ -4,6 +4,7 @@ var JobChan chan MsgType ...@@ -4,6 +4,7 @@ var JobChan chan MsgType
type MsgType struct { type MsgType struct {
Name string Name string
JobID int32
} }
func Setup() { func Setup() {
......
...@@ -14,6 +14,8 @@ import ( ...@@ -14,6 +14,8 @@ import (
var ( var (
btyPath string btyPath string
JobID int32
JobDoneMap map[int32]string
) )
func RaspberryChan() { func RaspberryChan() {
...@@ -30,53 +32,62 @@ func RaspberryChan() { ...@@ -30,53 +32,62 @@ func RaspberryChan() {
switch value.Name { switch value.Name {
case "ROLLBACK": case "ROLLBACK":
err := rollback() err := rollback()
if err == nil { if err != nil {
tlog.Info("RaspberryChan rollback success", "err", nil)
} else {
tlog.Error("RaspberryChan rollback fail ", "err", err) tlog.Error("RaspberryChan rollback fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan rollback success", "err", nil)
case "BACKUP": case "BACKUP":
err := backup() err := backup()
if err == nil { if err != nil {
tlog.Info("RaspberryChan backup success", "err", nil)
} else {
tlog.Error("RaspberryChan backup fail ", "err", err) tlog.Error("RaspberryChan backup fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan backup success", "err", nil)
case "RECOVER": case "RECOVER":
err := recoverNode() err := recoverNode()
if err == nil { if err != nil {
tlog.Info("RaspberryChan recover success", "err", nil)
} else {
tlog.Error("RaspberryChan recover fail ", "err", err) tlog.Error("RaspberryChan recover fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan recover success", "err", nil)
case "DELETEBACKUP": case "DELETEBACKUP":
err := deleteBackup() err := deleteBackup()
if err == nil { if err != nil {
tlog.Info("RaspberryChan deleteBackup success", "err", nil)
} else {
tlog.Error("RaspberryChan deleteBackup fail ", "err", err) tlog.Error("RaspberryChan deleteBackup fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan deleteBackup success", "err", nil)
case "RESTART": case "RESTART":
err := restartNode() err := restartNode()
if err == nil { if err != nil {
tlog.Info("RaspberryChan deleteBackup success", "err", nil)
} else {
tlog.Error("RaspberryChan deleteBackup fail ", "err", err) tlog.Error("RaspberryChan deleteBackup fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan deleteBackup success", "err", nil)
case "RESET": case "RESET":
err := resetNode() err := resetNode()
if err == nil { if err != nil {
tlog.Info("RaspberryChan resetNode success", "err", nil)
} else {
tlog.Error("RaspberryChan resetNode fail ", "err", err) tlog.Error("RaspberryChan resetNode fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan resetNode success", "err", nil)
case "RESETWALLET": case "RESETWALLET":
err := resetWallet() err := resetWallet()
if err != nil {
tlog.Error("RaspberryChan resetWallet fail ", "err", err)
}
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan resetWallet success", "err", nil)
case "CLOSE":
err := closeNode()
if err == nil { if err == nil {
tlog.Info("RaspberryChan resetWallet success", "err", nil)
} else {
tlog.Error("RaspberryChan resetWallet fail ", "err", err) tlog.Error("RaspberryChan resetWallet fail ", "err", err)
} }
updateJobMap(value.JobID,err)
tlog.Info("RaspberryChan resetWallet success", "err", nil)
} }
} }
...@@ -309,6 +320,32 @@ func resetWallet() error { ...@@ -309,6 +320,32 @@ func resetWallet() error {
return nil return nil
} }
func closeNode() error {
BityuanFlag.Lock.Lock()
defer BityuanFlag.Lock.Unlock()
if btyPath == "" {
tlog.Error("btyPath empty", "err", "node not exists")
return errors.New("node not exists")
}
_, err := SafeCloseNode()
if err != nil {
return err
}
isrun := MakeSureBtyIsNotRun()
if isrun {
return errors.New("bty is running")
}
return nil
}
func updateJobMap(id int32,err error) {
if _,exists:= JobDoneMap[id];!exists {
JobDoneMap[id] = err.Error()
return
}
tlog.Error("updateJobMap error","jobid",id)
}
func MakeSureBtyIsNotRun() bool { func MakeSureBtyIsNotRun() bool {
s := time.Now() s := time.Now()
defer func() { defer func() {
......
...@@ -5,6 +5,7 @@ const ( ...@@ -5,6 +5,7 @@ const (
ERROR = 500 ERROR = 500
INVALID_PARAMS = 400 INVALID_PARAMS = 400
JOB_NOT_DONE = 300
NETWORK_ERROR = 5004 NETWORK_ERROR = 5004
NODE_ERROR = 5000 NODE_ERROR = 5000
SUCCESS_RUNNING = 5002 SUCCESS_RUNNING = 5002
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
"sync/atomic"
) )
// Setup Initialize the util // Setup Initialize the util
...@@ -128,3 +129,12 @@ func VersionCompare(version string) string { ...@@ -128,3 +129,12 @@ func VersionCompare(version string) string {
} }
return string(vo) return string(vo)
} }
func AddValue(addr *int32, delta int32){
for{
v:=atomic.LoadInt32(addr)
if atomic.CompareAndSwapInt32(&v,*addr,(delta+v)){
break;
}
}
}
\ No newline at end of file
...@@ -17,15 +17,16 @@ import ( ...@@ -17,15 +17,16 @@ import (
"os" "os"
"os/exec" "os/exec"
"reflect" "reflect"
"strconv"
"strings" "strings"
"time" "time"
"chain33-pai/pkg/util"
) )
func ResetWallet(c *gin.Context) { func ResetWallet(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
app.JobChan <- app.MsgType{Name: "RESETWALLET"} util.AddValue(&app.JobID,1)
appG.Response(http.StatusOK, e.SUCCESS, "bityuan wallet reset") app.JobChan <- app.MsgType{Name: "RESETWALLET",JobID:app.JobID}
appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
} }
//钱包更新,只替换执行文件和配置文件 //钱包更新,只替换执行文件和配置文件
...@@ -154,8 +155,9 @@ func UpdateNodeNew(c *gin.Context) { ...@@ -154,8 +155,9 @@ func UpdateNodeNew(c *gin.Context) {
//重置节点只需要删除datadir 然后重启节点 //重置节点只需要删除datadir 然后重启节点
func ResetNode(c *gin.Context) { func ResetNode(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
app.JobChan <- app.MsgType{Name: "RESET"} util.AddValue(&app.JobID,1)
appG.Response(http.StatusOK, e.SUCCESS, "bityuan reset") app.JobChan <- app.MsgType{Name: "RESET",JobID:app.JobID}
appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
} }
func UpdateDetail(c *gin.Context) { func UpdateDetail(c *gin.Context) {
...@@ -198,34 +200,16 @@ func NodeInfo(c *gin.Context) { ...@@ -198,34 +200,16 @@ func NodeInfo(c *gin.Context) {
func RestartNode(c *gin.Context) { func RestartNode(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
app.BityuanFlag.Flag = true util.AddValue(&app.JobID,1)
_, err := app.SafeCloseNode() app.JobChan <- app.MsgType{Name: "RESTART",JobID:app.JobID}
if err != nil { appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
appG.Response(http.StatusOK, e.NODE_ERROR, "node err")
app.BityuanFlag.Flag = false
return
}
app.BityuanFlag.Flag = false
appG.Response(http.StatusOK, e.SUCCESS, "node close safe")
} }
func CloseNode(c *gin.Context) { func CloseNode(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
app.BityuanFlag.Flag = true util.AddValue(&app.JobID,1)
_, err := app.SafeCloseNode() app.JobChan <- app.MsgType{Name: "CLOSE",JobID:app.JobID}
if err != nil { appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
appG.Response(http.StatusOK, e.NODE_ERROR, "node err")
app.BityuanFlag.Flag = false
return
}
//防止其他模块未关闭
//time.Sleep(time.Second * 2)
if !app.MakeSureBtyIsNotRun() {
appG.Response(http.StatusOK, e.NODE_ERROR, "node stop err")
app.BityuanFlag.Flag = false
return
}
appG.Response(http.StatusOK, e.SUCCESS, "node close safe")
} }
//反馈信息 //反馈信息
...@@ -505,35 +489,40 @@ func Test(c *gin.Context) { ...@@ -505,35 +489,40 @@ func Test(c *gin.Context) {
func Rollback(c *gin.Context) { func Rollback(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
app.JobChan <- app.MsgType{Name: "ROLLBACK"} util.AddValue(&app.JobID,1)
appG.Response(http.StatusOK, e.SUCCESS, "bityuan rollback") app.JobChan <- app.MsgType{Name: "ROLLBACK",JobID:app.JobID}
appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
} }
func NodeBackup(c *gin.Context) { func NodeBackup(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
var pai pai_service.Pai util.AddValue(&app.JobID,1)
err := pai.GetDiskUseage() app.JobChan <- app.MsgType{Name: "BACKUP",JobID:app.JobID}
if err != nil { appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
tlog.Error("GetDiskUseage", "err", err) //appG := app.Gin{C: c}
appG.Response(http.StatusOK, e.ENV_ERROR, "get diskuseage err") //var pai pai_service.Pai
return //err := pai.GetDiskUseage()
} //if err != nil {
if len(pai.Disks) == 0 { // tlog.Error("GetDiskUseage", "err", err)
tlog.Error("disk ", "err", "disk not find") // appG.Response(http.StatusOK, e.ENV_ERROR, "get diskuseage err")
appG.Response(http.StatusOK, e.ENV_ERROR, "disk not find") // return
return //}
} //if len(pai.Disks) == 0 {
tlog.Info("disk info", "ssd", pai.Disks[0]) // tlog.Error("disk ", "err", "disk not find")
p := pai.Disks[0].Use // appG.Response(http.StatusOK, e.ENV_ERROR, "disk not find")
ps := strings.Split(p, "%") // return
pint, _ := strconv.Atoi(ps[0]) //}
if pint*2 > 80 { //tlog.Info("disk info", "ssd", pai.Disks[0])
tlog.Error("disk space ", "err", "space not enough to backup") //p := pai.Disks[0].Use
appG.Response(http.StatusOK, e.ENV_ERROR, "disk space not enough") //ps := strings.Split(p, "%")
return //pint, _ := strconv.Atoi(ps[0])
} //if pint*2 > 80 {
app.JobChan <- app.MsgType{Name: "BACKUP"} // tlog.Error("disk space ", "err", "space not enough to backup")
appG.Response(http.StatusOK, e.SUCCESS, "bityuan ready to backup") // appG.Response(http.StatusOK, e.ENV_ERROR, "disk space not enough")
// return
//}
//app.JobChan <- app.MsgType{Name: "BACKUP"}
//appG.Response(http.StatusOK, e.SUCCESS, "bityuan ready to backup")
} }
func CheckBackup(c *gin.Context) { func CheckBackup(c *gin.Context) {
...@@ -553,45 +542,76 @@ func CheckBackup(c *gin.Context) { ...@@ -553,45 +542,76 @@ func CheckBackup(c *gin.Context) {
func NodeRecover(c *gin.Context) { func NodeRecover(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
var pai pai_service.Pai util.AddValue(&app.JobID,1)
err := pai.GetDiskUseage() app.JobChan <- app.MsgType{Name: "RECOVER",JobID:app.JobID}
if err != nil { appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
tlog.Error("GetDiskUseage", "err", err) //appG := app.Gin{C: c}
appG.Response(http.StatusOK, e.ENV_ERROR, "get diskuseage err") //var pai pai_service.Pai
return //err := pai.GetDiskUseage()
} //if err != nil {
if len(pai.Disks) == 0 { // tlog.Error("GetDiskUseage", "err", err)
tlog.Error("disk ", "err", "disk not find") // appG.Response(http.StatusOK, e.ENV_ERROR, "get diskuseage err")
appG.Response(http.StatusOK, e.ENV_ERROR, "disk not find") // return
return //}
} //if len(pai.Disks) == 0 {
tlog.Info("disk info", "ssd", pai.Disks[0]) // tlog.Error("disk ", "err", "disk not find")
p := pai.Disks[0].Use // appG.Response(http.StatusOK, e.ENV_ERROR, "disk not find")
ps := strings.Split(p, "%") // return
pint, _ := strconv.Atoi(ps[0]) //}
if pint > 90 { //tlog.Info("disk info", "ssd", pai.Disks[0])
tlog.Error("disk ", "err", "disk space not enough") //p := pai.Disks[0].Use
//app.JobChan <- app.MsgType{Name:"DELETEBACKUP"} //ps := strings.Split(p, "%")
} //pint, _ := strconv.Atoi(ps[0])
app.JobChan <- app.MsgType{Name: "RECOVER"} //if pint > 90 {
appG.Response(http.StatusOK, e.SUCCESS, "bityuan ready to recover") // tlog.Error("disk ", "err", "disk space not enough")
// //app.JobChan <- app.MsgType{Name:"DELETEBACKUP"}
//}
//app.JobChan <- app.MsgType{Name: "RECOVER"}
//appG.Response(http.StatusOK, e.SUCCESS, "bityuan ready to recover")
} }
func DelBackup(c *gin.Context) { func DelBackup(c *gin.Context) {
appG := app.Gin{C: c} appG := app.Gin{C: c}
var pai pai_service.Pai util.AddValue(&app.JobID,1)
err := pai.GetDiskUseage() app.JobChan <- app.MsgType{Name: "DELETEBACKUP",JobID:app.JobID}
appG.Response(http.StatusOK, e.SUCCESS, app.JobID)
//appG := app.Gin{C: c}
//var pai pai_service.Pai
//err := pai.GetDiskUseage()
//if err != nil {
// tlog.Error("GetDiskUseage", "err", err)
// appG.Response(http.StatusOK, e.ENV_ERROR, "get diskuseage err")
// return
//}
//if len(pai.Disks) == 0 {
// tlog.Error("disk ", "err", "disk not find")
// appG.Response(http.StatusOK, e.ENV_ERROR, "disk not find")
// return
//}
//tlog.Info("disk info", "ssd", pai.Disks[0])
//app.JobChan <- app.MsgType{Name: "DELETEBACKUP"}
//appG.Response(http.StatusOK, e.ENV_ERROR, "del backup")
}
func JobStatus(c *gin.Context) {
type JReq struct {
JobID int32 `json:"job_id" binding:"required"`
}
var req JReq
appG := app.Gin{C: c}
err := appG.C.ShouldBindJSON(&req)
if err != nil { if err != nil {
tlog.Error("GetDiskUseage", "err", err) appG.Response(http.StatusOK, e.INVALID_PARAMS, nil)
appG.Response(http.StatusOK, e.ENV_ERROR, "get diskuseage err") tlog.Info("invalid params")
return return
} }
if len(pai.Disks) == 0 { if _,exists := app.JobDoneMap[req.JobID];exists {
tlog.Error("disk ", "err", "disk not find") if app.JobDoneMap[req.JobID] != "" {
appG.Response(http.StatusOK, e.ENV_ERROR, "disk not find") appG.Response(http.StatusOK, e.ERROR, app.JobDoneMap[req.JobID])
return
}
appG.Response(http.StatusOK, e.SUCCESS, app.JobDoneMap[req.JobID])
return return
} }
tlog.Info("disk info", "ssd", pai.Disks[0]) appG.Response(http.StatusOK, e.JOB_NOT_DONE, nil)
app.JobChan <- app.MsgType{Name: "DELETEBACKUP"} }
appG.Response(http.StatusOK, e.ENV_ERROR, "del backup") \ No newline at end of file
}
...@@ -67,6 +67,8 @@ func InitRouter() *gin.Engine { ...@@ -67,6 +67,8 @@ func InitRouter() *gin.Engine {
apiv1.POST("/delbackup", v1.DelBackup) apiv1.POST("/delbackup", v1.DelBackup)
//是否备份 //是否备份
apiv1.POST("/isbackup", v1.CheckBackup) apiv1.POST("/isbackup", v1.CheckBackup)
//获取任务完成情况
apiv1.POST("/jobstatus", v1.JobStatus)
return r return r
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment