videoplayer/service/shellService.go

143 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"bytes"
"errors"
"log"
"os/exec"
"strings"
"time"
"videoplayer/dao"
"videoplayer/proto"
"videoplayer/worker"
)
func CreateShell(shellName, shellContent, server string, uid int) uint {
id := dao.CreateShell(shellName, shellContent, server, uint(uid))
return id
}
func FindShellByAuthID(id int) []dao.Shell {
return dao.FindShellByAuthID(id)
}
func DeleteShellByID(id, authId uint) bool {
user := GetUserByIDFromUserCenter(int(authId))
if user.Role == "admin" {
return dao.DeleteShellByIDV2(id)
}
return dao.DeleteShellByID(id, authId)
}
func UpdateShellByID(id, authId uint, shellName, shellContent, server string, status int, shellResult string) bool {
return dao.UpdateShellByID(id, authId, shellName, shellContent, status, shellResult, 0, 0)
}
func UpdateShellByIDV2(id, authId uint, shellName, shellContent, server string, status int, shellResult string, shellRuntime float64) bool {
//查看shell是否存在
pd := dao.FindShellByID(id, authId)
if len(pd) < 1 && pd[0].ID == 0 {
return false
}
shell := pd[0]
//如果状态为2,3转为0,1是不允许的为了防止出现1确认包阻塞问题
if (shell.Status == 2 || shell.Status == 3) && (status == 0 || status == 1) {
log.Println("UpdateShellByIDV2: status change from 2/3 to 0/1 is not allowed, shell id:", id)
return false
}
var elapsed float64 //持续时间
if (shell.Status == 0 || shell.Status == 1) && (status == 2 || status == 3) { //如果状态为执行中且新更新时间状态为2或3则获取持续时间
elapsed = time.Since(shell.CreatedAt).Seconds()
}
return dao.UpdateShellByID(id, authId, shellName, shellContent, status, shellResult, shellRuntime, elapsed)
}
func FindShellWillRunByServer(server string, uid int) ([]dao.Shell, error) {
var shells []dao.Shell
var err error
if server == "" {
//err设置为server为空
err = errors.New("server is empty")
return shells, err
}
shells = dao.FindShellWillRunByServer(server, uint(uid))
//设置状态为执行中
for _, v := range shells {
dao.UpdateShellByID(v.ID, uint(uid), v.ShellName, v.ShellContent, v.Status+1, v.ShellResult, 0, 0) //将状态设置为执行中
}
return shells, err
}
// 从服务器定时获取shell、执行并返回结果
func ShellWillRunFromServer() {
shells, err := GetShellWillRunFromMaster(proto.Config.SERVER_NAME)
if err != nil {
return
}
var resp []proto.UpdateShellReq
for _, v := range shells {
//执行shell脚本,go执行命令
start := time.Now()
res, err2 := RunShell(v.ShellContent)
//执行时间,转成秒
shellRuntime := time.Since(start).Seconds()
if err2 != "" {
resp = append(resp, proto.UpdateShellReq{ID: v.ID, Server: v.Server, Status: 3, ShellResult: "err:" + err2 + "\nresult:" + res, ShellRuntime: shellRuntime}) //执行出错
} else {
resp = append(resp, proto.UpdateShellReq{ID: v.ID, Server: v.Server, Status: 2, ShellResult: res, ShellRuntime: shellRuntime}) //执行成功
}
}
if len(resp) == 0 {
return
}
//返回执行结果
url := "https://" + proto.Config.MASTER_SERVER_DOMAIN + "/shell/update?super_id=1"
var req proto.SyncUserShellResp
req.Token = worker.GetRedisSetMembers("super_permission_tokens")[0]
req.Shells = resp
resp_data, err := worker.SyncDataFromMasterShellReq3(url, req)
if err != nil {
return
}
//更新执行结果
for _, v := range resp_data {
if v.Status < 0 {
log.Fatalln("update shell failed:", v.ID, v.Status)
}
}
}
// 从服务器从主服务器获取待执行的shell
func GetShellWillRunFromMaster(server string) ([]dao.Shell, error) {
master := proto.Config.MASTER_SERVER_DOMAIN
//发起请求获取待执行的shell
url := "https://" + master + "/shell/server_will_run_list?super_id=1"
var req proto.SyncUserShellReq
req.Server = server
superPermissions := worker.GetRedisSetMembers("super_permission_tokens")
if len(superPermissions) == 0 {
log.Println("get shell will run from master error: no super permission tokens found, please check the configuration or redis!")
return nil, errors.New("no super permission tokens found")
}
req.Token = superPermissions[0]
shells, err := worker.SyncDataFromMasterShellReq2(url, req)
if err != nil {
return nil, err
}
return shells, nil
}
func RunShell(script string) (res, err string) {
cmd := exec.Command("/bin/bash", "-c", script)
// 使用bytes.Buffer捕获输出
var out bytes.Buffer
cmd.Stdout = &out
err3 := cmd.Run()
err3_info := ""
if err3 != nil {
err3_info = err3.Error()
}
return strings.TrimSpace(out.String()), err3_info
}