videoplayer/service/shellService.go

143 lines
4.5 KiB
Go
Raw Permalink Normal View History

2025-02-22 14:44:26 +08:00
package service
import (
"bytes"
"errors"
"log"
"os/exec"
"strings"
"time"
2025-02-22 14:44:26 +08:00
"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)
}
2025-06-06 14:16:44 +08:00
func DeleteShellByID(id, authId uint) bool {
user := GetUserByIDFromUserCenter(int(authId))
if user.Role == "admin" {
return dao.DeleteShellByIDV2(id)
}
2025-06-06 14:16:44 +08:00
return dao.DeleteShellByID(id, authId)
}
2025-02-22 14:44:26 +08:00
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)
2025-02-22 14:44:26 +08:00
}
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) //将状态设置为执行中
2025-02-22 14:44:26 +08:00
}
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()
2025-02-22 14:44:26 +08:00
res, err2 := RunShell(v.ShellContent)
//执行时间,转成秒
shellRuntime := time.Since(start).Seconds()
2025-02-22 14:44:26 +08:00
if err2 != "" {
2025-08-07 20:28:32 +08:00
resp = append(resp, proto.UpdateShellReq{ID: v.ID, Server: v.Server, Status: 3, ShellResult: "err:" + err2 + "\nresult:" + res, ShellRuntime: shellRuntime}) //执行出错
2025-02-22 14:44:26 +08:00
} else {
2025-08-07 20:01:01 +08:00
resp = append(resp, proto.UpdateShellReq{ID: v.ID, Server: v.Server, Status: 2, ShellResult: res, ShellRuntime: shellRuntime}) //执行成功
2025-02-22 14:44:26 +08:00
}
}
2025-03-05 19:33:07 +08:00
if len(resp) == 0 {
return
}
2025-02-22 14:44:26 +08:00
//返回执行结果
2025-03-11 15:32:44 +08:00
url := "https://" + proto.Config.MASTER_SERVER_DOMAIN + "/shell/update?super_id=1"
2025-02-22 14:44:26 +08:00
var req proto.SyncUserShellResp
2025-03-11 15:24:47 +08:00
req.Token = worker.GetRedisSetMembers("super_permission_tokens")[0]
2025-02-22 14:44:26 +08:00
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
2025-03-05 19:33:07 +08:00
url := "https://" + master + "/shell/server_will_run_list?super_id=1"
2025-02-22 14:44:26 +08:00
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]
2025-02-22 14:44:26 +08:00
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
}