添加脚本调试
This commit is contained in:
parent
0366c23d26
commit
d7c362d1cb
|
@ -4,3 +4,4 @@
|
||||||
*.exe
|
*.exe
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
|
/dist/
|
||||||
|
|
|
@ -20,8 +20,25 @@ func Api(group *gin.RouterGroup) {
|
||||||
group.PUT("/pin", pin())
|
group.PUT("/pin", pin())
|
||||||
group.PUT("/unpin", unpin())
|
group.PUT("/unpin", unpin())
|
||||||
group.GET("/:id/log", log1())
|
group.GET("/:id/log", log1())
|
||||||
|
group.GET("/:id", getById())
|
||||||
group.PUT("/run", run())
|
group.PUT("/run", run())
|
||||||
group.PUT("/stop", stop())
|
group.PUT("/stop", stop())
|
||||||
|
group.GET("/views", views())
|
||||||
|
}
|
||||||
|
|
||||||
|
func views() gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
ctx.JSON(200, res.Ok([]string{}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getById() gin.HandlerFunc {
|
||||||
|
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
id, _ := strconv.Atoi(ctx.Param("id"))
|
||||||
|
c := cron.GetCron(id)
|
||||||
|
ctx.JSON(200, res.Ok(c))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get() gin.HandlerFunc {
|
func get() gin.HandlerFunc {
|
||||||
|
|
|
@ -14,9 +14,18 @@ func Api(group *gin.RouterGroup) {
|
||||||
group.GET("/:id", getDep())
|
group.GET("/:id", getDep())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
typMap = map[string]int{
|
||||||
|
"nodejs": 0,
|
||||||
|
"python3": 1,
|
||||||
|
"linux": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func get() gin.HandlerFunc {
|
func get() gin.HandlerFunc {
|
||||||
return func(ctx *gin.Context) {
|
return func(ctx *gin.Context) {
|
||||||
dependences, err := models.QueryDependences(ctx.Query("searchValue"))
|
|
||||||
|
dependences, err := models.QueryDependences(ctx.Query("searchValue"), typMap[ctx.Query("type")])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(503, res.Err(503, err))
|
ctx.JSON(503, res.Err(503, err))
|
||||||
return
|
return
|
||||||
|
|
|
@ -43,7 +43,7 @@ func post() gin.HandlerFunc {
|
||||||
e.Createdat = time.Now()
|
e.Createdat = time.Now()
|
||||||
e.Updatedat = time.Now()
|
e.Updatedat = time.Now()
|
||||||
e.Timestamp = time.Now().Format("Mon Jan 02 2006 15:04:05 MST")
|
e.Timestamp = time.Now().Format("Mon Jan 02 2006 15:04:05 MST")
|
||||||
e.Status = &status
|
e.Status = status
|
||||||
id, err := env.AddEnv(e)
|
id, err := env.AddEnv(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(200, res.Err(503, err))
|
ctx.JSON(200, res.Err(503, err))
|
||||||
|
@ -142,7 +142,7 @@ func upload() gin.HandlerFunc {
|
||||||
e.Createdat = time.Now()
|
e.Createdat = time.Now()
|
||||||
e.Updatedat = time.Now()
|
e.Updatedat = time.Now()
|
||||||
e.Timestamp = time.Now().Format("Mon Jan 02 2006 15:04:05 MST")
|
e.Timestamp = time.Now().Format("Mon Jan 02 2006 15:04:05 MST")
|
||||||
e.Status = &status
|
e.Status = status
|
||||||
id, err := env.AddEnv(e)
|
id, err := env.AddEnv(e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(200, res.Err(503, err))
|
ctx.JSON(200, res.Err(503, err))
|
||||||
|
|
|
@ -15,8 +15,36 @@ func Api(group *gin.RouterGroup) {
|
||||||
group.POST("", post())
|
group.POST("", post())
|
||||||
group.DELETE("", del())
|
group.DELETE("", del())
|
||||||
group.GET("/:name", getFile())
|
group.GET("/:name", getFile())
|
||||||
|
group.GET("/log", log())
|
||||||
|
|
||||||
group.PUT("/run", run())
|
group.PUT("/run", run())
|
||||||
|
group.PUT("/stop", stop())
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
type Req struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
FileName string `json:"filename"`
|
||||||
|
Pid string `json:"pid"`
|
||||||
|
}
|
||||||
|
r := new(Req)
|
||||||
|
err := ctx.ShouldBindJSON(r)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(503, res.Err(503, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
scripts.Stop(r.Pid)
|
||||||
|
ctx.JSON(200, res.Ok(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func log() gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
pid := ctx.Query("pid")
|
||||||
|
value := scripts.Log(pid)
|
||||||
|
ctx.JSON(200, res.Ok(value))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() gin.HandlerFunc {
|
func run() gin.HandlerFunc {
|
||||||
|
@ -32,12 +60,12 @@ func run() gin.HandlerFunc {
|
||||||
ctx.JSON(503, res.Err(503, err))
|
ctx.JSON(503, res.Err(503, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = scripts.Run(path2.Join(r.Path, "_"+r.FileName), r.Content)
|
id, err := scripts.Run(path2.Join(r.Path, "_"+r.FileName), r.Content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(503, res.Err(503, err))
|
ctx.JSON(503, res.Err(503, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.JSON(200, res.Ok(true))
|
ctx.JSON(200, res.Ok(id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@ func get() gin.HandlerFunc {
|
||||||
ctx.JSON(200, res.Ok(subs))
|
ctx.JSON(200, res.Ok(subs))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func post() gin.HandlerFunc {
|
func post() gin.HandlerFunc {
|
||||||
|
|
|
@ -22,7 +22,7 @@ func get() gin.HandlerFunc {
|
||||||
Version: config.GetVersion(),
|
Version: config.GetVersion(),
|
||||||
LastCommitTime: "",
|
LastCommitTime: "",
|
||||||
LastCommitId: "",
|
LastCommitId: "",
|
||||||
Branch: "Main",
|
Branch: "qinglong-go",
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,9 @@ TsCmd="ts-node-transpile-only"
|
||||||
# 运行以.sh结尾的文件时的命令
|
# 运行以.sh结尾的文件时的命令
|
||||||
ShCmd="bash"
|
ShCmd="bash"
|
||||||
|
|
||||||
|
# 运行以python依赖的命令
|
||||||
|
PipCmd="pip"
|
||||||
|
|
||||||
## 通知环境变量
|
## 通知环境变量
|
||||||
## 1. Server酱
|
## 1. Server酱
|
||||||
## https://sct.ftqq.com
|
## https://sct.ftqq.com
|
||||||
|
|
|
@ -57,6 +57,7 @@ func appInit() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = os.MkdirAll(path.Join("data", "config"), 0666)
|
_ = os.MkdirAll(path.Join("data", "config"), 0666)
|
||||||
|
_ = os.MkdirAll(path.Join("data", "deps"), 0666)
|
||||||
_ = os.MkdirAll(path.Join("data", "log"), 0666)
|
_ = os.MkdirAll(path.Join("data", "log"), 0666)
|
||||||
_ = os.MkdirAll(path.Join("data", "repo"), 0666)
|
_ = os.MkdirAll(path.Join("data", "repo"), 0666)
|
||||||
_ = os.MkdirAll(path.Join("data", "scripts"), 0666)
|
_ = os.MkdirAll(path.Join("data", "scripts"), 0666)
|
||||||
|
|
32
api/ws/ws.go
32
api/ws/ws.go
|
@ -1,10 +1,13 @@
|
||||||
package ws
|
package ws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gobwas/ws"
|
|
||||||
"github.com/huoxue1/qinglong-go/service/client"
|
"github.com/huoxue1/qinglong-go/service/client"
|
||||||
"github.com/huoxue1/qinglong-go/utils/res"
|
"github.com/huoxue1/qinglong-go/utils/res"
|
||||||
|
"nhooyr.io/websocket"
|
||||||
|
"nhooyr.io/websocket/wsjson"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Api(group *gin.RouterGroup) {
|
func Api(group *gin.RouterGroup) {
|
||||||
|
@ -20,12 +23,35 @@ func info() gin.HandlerFunc {
|
||||||
|
|
||||||
func wsHandle() gin.HandlerFunc {
|
func wsHandle() gin.HandlerFunc {
|
||||||
return func(ctx *gin.Context) {
|
return func(ctx *gin.Context) {
|
||||||
conn, _, _, err := ws.UpgradeHTTP(ctx.Request, ctx.Writer)
|
conn, err := websocket.Accept(ctx.Writer, ctx.Request, &websocket.AcceptOptions{
|
||||||
|
Subprotocols: nil,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
OriginPatterns: []string{"*"},
|
||||||
|
CompressionMode: 0,
|
||||||
|
CompressionThreshold: 0,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(502, res.Err(502, err))
|
ctx.JSON(502, res.Err(502, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client.AddWs(ctx.Param("id")+"_"+ctx.Param("name"), conn)
|
wsjson.Write(context.Background(), conn, map[string]string{"123": "11"})
|
||||||
|
wsjson.Write(context.Background(), conn, map[string]string{"123": "11"})
|
||||||
|
wsjson.Write(context.Background(), conn, map[string]string{"123": "11"})
|
||||||
|
|
||||||
|
c := make(chan any, 100)
|
||||||
|
client.AddChan(c)
|
||||||
|
|
||||||
|
for true {
|
||||||
|
wsjson.Write(context.Background(), conn, map[string]string{"123": "11"})
|
||||||
|
time.Sleep(1000)
|
||||||
|
wsjson.Write(context.Background(), conn, map[string]string{"123": "11"})
|
||||||
|
data := <-c
|
||||||
|
err := wsjson.Write(context.Background(), conn, data)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ import (
|
||||||
"github.com/gin-contrib/static"
|
"github.com/gin-contrib/static"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/huoxue1/qinglong-go/api"
|
"github.com/huoxue1/qinglong-go/api"
|
||||||
"net/http"
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Router() *gin.Engine {
|
func Router() *gin.Engine {
|
||||||
|
@ -15,11 +16,20 @@ func Router() *gin.Engine {
|
||||||
engine.Use(gzip.Gzip(gzip.DefaultCompression))
|
engine.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||||
engine.Use(static.Serve("/", static.LocalFile("static/dist/", false)))
|
engine.Use(static.Serve("/", static.LocalFile("static/dist/", false)))
|
||||||
engine.NoRoute(func(ctx *gin.Context) {
|
engine.NoRoute(func(ctx *gin.Context) {
|
||||||
if ctx.Request.Method == http.MethodGet {
|
accept := ctx.Request.Header.Get("Accept")
|
||||||
ctx.Redirect(301, "/")
|
flag := strings.Contains(accept, "text/html")
|
||||||
return
|
if flag {
|
||||||
|
content, err := ioutil.ReadFile("static/dist/index.html")
|
||||||
|
if (err) != nil {
|
||||||
|
ctx.Writer.WriteHeader(404)
|
||||||
|
_, _ = ctx.Writer.WriteString("Not Found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Writer.WriteHeader(200)
|
||||||
|
ctx.Writer.Header().Add("Accept", "text/html")
|
||||||
|
_, _ = ctx.Writer.Write(content)
|
||||||
|
ctx.Writer.Flush()
|
||||||
}
|
}
|
||||||
ctx.Next()
|
|
||||||
})
|
})
|
||||||
api.Api(engine.Group("/api", api.Jwt()))
|
api.Api(engine.Group("/api", api.Jwt()))
|
||||||
api.Open(engine.Group("/open", api.OpenJwt()))
|
api.Open(engine.Group("/open", api.OpenJwt()))
|
||||||
|
|
8
go.mod
8
go.mod
|
@ -4,13 +4,16 @@ go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Lyrics-you/sail-logrus-formatter v1.3.1
|
github.com/Lyrics-you/sail-logrus-formatter v1.3.1
|
||||||
|
github.com/dablelv/go-huge-util v0.0.31
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
|
github.com/gin-contrib/gzip v0.0.6
|
||||||
github.com/gin-contrib/static v0.0.1
|
github.com/gin-contrib/static v0.0.1
|
||||||
github.com/gin-gonic/gin v1.8.1
|
github.com/gin-gonic/gin v1.8.1
|
||||||
github.com/gobwas/ws v1.1.0
|
github.com/gobwas/ws v1.1.0
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/imroc/req/v3 v3.26.5
|
github.com/imroc/req/v3 v3.26.5
|
||||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||||
|
github.com/panjf2000/ants/v2 v2.7.1
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.0
|
||||||
github.com/tidwall/gjson v1.14.4
|
github.com/tidwall/gjson v1.14.4
|
||||||
|
@ -21,9 +24,7 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cheekybits/genny v1.0.0 // indirect
|
github.com/cheekybits/genny v1.0.0 // indirect
|
||||||
github.com/dablelv/go-huge-util v0.0.31 // indirect
|
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
github.com/gin-contrib/gzip v0.0.6 // indirect
|
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.0 // indirect
|
github.com/go-playground/locales v0.14.0 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||||
|
@ -37,6 +38,7 @@ require (
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
|
github.com/klauspost/compress v1.10.3 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||||
github.com/lucas-clemente/quic-go v0.28.1 // indirect
|
github.com/lucas-clemente/quic-go v0.28.1 // indirect
|
||||||
|
@ -53,7 +55,6 @@ require (
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||||
github.com/stretchr/testify v1.8.1 // indirect
|
|
||||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
|
@ -76,4 +77,5 @@ require (
|
||||||
modernc.org/opt v0.1.3 // indirect
|
modernc.org/opt v0.1.3 // indirect
|
||||||
modernc.org/strutil v1.1.3 // indirect
|
modernc.org/strutil v1.1.3 // indirect
|
||||||
modernc.org/token v1.0.1 // indirect
|
modernc.org/token v1.0.1 // indirect
|
||||||
|
nhooyr.io/websocket v1.8.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
13
go.sum
13
go.sum
|
@ -122,10 +122,13 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
|
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||||
|
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||||
|
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
@ -151,6 +154,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
|
@ -189,6 +193,7 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51
|
||||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
@ -288,6 +293,8 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
|
||||||
|
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
|
@ -407,6 +414,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
|
||||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
|
github.com/panjf2000/ants/v2 v2.7.1 h1:qBy5lfSdbxvrR0yUnZfaEDjf0FlCw4ufsbcsxmE7r+M=
|
||||||
|
github.com/panjf2000/ants/v2 v2.7.1/go.mod h1:KIBmYG9QQX5U2qzFP/yQJaq/nSb6rahS9iEHkrCMgM8=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||||
|
@ -644,6 +653,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -965,6 +976,8 @@ modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
|
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
|
||||||
modernc.org/z v1.3.2 h1:4GWBVMa48UDC7KQ9tnaggN/yTlXg+CdCX9bhgHPQ9AM=
|
modernc.org/z v1.3.2 h1:4GWBVMa48UDC7KQ9tnaggN/yTlXg+CdCX9bhgHPQ9AM=
|
||||||
modernc.org/z v1.3.2/go.mod h1:PEU2oK2OEA1CfzDTd+8E908qEXhC9s0MfyKp5LZsd+k=
|
modernc.org/z v1.3.2/go.mod h1:PEU2oK2OEA1CfzDTd+8E908qEXhC9s0MfyKp5LZsd+k=
|
||||||
|
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||||
|
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||||
|
|
10
main.go
10
main.go
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
nested "github.com/Lyrics-you/sail-logrus-formatter/sailor"
|
nested "github.com/Lyrics-you/sail-logrus-formatter/sailor"
|
||||||
"github.com/dablelv/go-huge-util/zip"
|
"github.com/dablelv/go-huge-util/zip"
|
||||||
|
@ -17,6 +18,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
address string
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
w, err := rotates.New(path.Join("data", "log", "qinglong-go", "%Y-%m-%d.log"), rotates.WithRotationTime(time.Hour*24))
|
w, err := rotates.New(path.Join("data", "log", "qinglong-go", "%Y-%m-%d.log"), rotates.WithRotationTime(time.Hour*24))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -39,13 +44,16 @@ func init() {
|
||||||
CallerFirst: false,
|
CallerFirst: false,
|
||||||
CustomCallerFormatter: nil,
|
CustomCallerFormatter: nil,
|
||||||
})
|
})
|
||||||
|
flag.StringVar(&address, "add", "0.0.0.0:5700", "the ql listen address!")
|
||||||
|
flag.Parse()
|
||||||
|
config.SetAddress(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
checkStatic()
|
checkStatic()
|
||||||
service.AppInit()
|
service.AppInit()
|
||||||
engine := controller.Router()
|
engine := controller.Router()
|
||||||
_ = engine.Run(":5700")
|
_ = engine.Run(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkStatic() {
|
func checkStatic() {
|
||||||
|
|
|
@ -11,7 +11,7 @@ type Crontabs struct {
|
||||||
Command string `xorm:"VARCHAR(255)" json:"command"`
|
Command string `xorm:"VARCHAR(255)" json:"command"`
|
||||||
Schedule string `xorm:"VARCHAR(255)" json:"schedule"`
|
Schedule string `xorm:"VARCHAR(255)" json:"schedule"`
|
||||||
Timestamp string `xorm:"VARCHAR(255)" json:"timestamp"`
|
Timestamp string `xorm:"VARCHAR(255)" json:"timestamp"`
|
||||||
Saved int `xorm:"TINYINT(1)" json:"saved"`
|
Saved bool `xorm:"TINYINT(1)" json:"saved"`
|
||||||
Status int `xorm:"TINYINT(1)" json:"status"`
|
Status int `xorm:"TINYINT(1)" json:"status"`
|
||||||
Issystem int `xorm:"TINYINT(1)" json:"isSystem"`
|
Issystem int `xorm:"TINYINT(1)" json:"isSystem"`
|
||||||
Pid int `xorm:"TINYINT(1)" json:"pid"`
|
Pid int `xorm:"TINYINT(1)" json:"pid"`
|
||||||
|
|
|
@ -23,17 +23,16 @@ type Dependences struct {
|
||||||
Updatedat time.Time `xorm:"not null DATETIME updated" json:"updatedAt"`
|
Updatedat time.Time `xorm:"not null DATETIME updated" json:"updatedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func QueryDependences(searchValue string) ([]*Dependences, error) {
|
func QueryDependences(searchValue string, typ int) ([]*Dependences, error) {
|
||||||
dep := make([]*Dependences, 0)
|
dep := make([]*Dependences, 0)
|
||||||
session := engine.Table(new(Dependences)).
|
session := engine.Table(new(Dependences)).
|
||||||
Where(
|
Where(
|
||||||
builder.Like{"name", "%" + searchValue + "%"})
|
builder.Like{"name", "%" + searchValue + "%"})
|
||||||
err := session.Find(&dep)
|
err := session.And("type=?", typ).Find(&dep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return dep, err
|
return dep, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddDependences(dep *Dependences) (int, error) {
|
func AddDependences(dep *Dependences) (int, error) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ type Envs struct {
|
||||||
Id int `xorm:"pk autoincr INTEGER" json:"id,omitempty"`
|
Id int `xorm:"pk autoincr INTEGER" json:"id,omitempty"`
|
||||||
Value string `xorm:"TEXT" json:"value,omitempty"`
|
Value string `xorm:"TEXT" json:"value,omitempty"`
|
||||||
Timestamp string `xorm:"TEXT" json:"timestamp,omitempty"`
|
Timestamp string `xorm:"TEXT" json:"timestamp,omitempty"`
|
||||||
Status *int `xorm:"TINYINT(1)" json:"status,omitempty"`
|
Status int `xorm:"TINYINT(1)" json:"status,omitempty"`
|
||||||
Position string `xorm:"TINYINT(1)" json:"position,omitempty"`
|
Position string `xorm:"TINYINT(1)" json:"position,omitempty"`
|
||||||
Name string `xorm:"TEXT" json:"name,omitempty"`
|
Name string `xorm:"TEXT" json:"name,omitempty"`
|
||||||
Remarks string `xorm:"TEXT" json:"remarks,omitempty"`
|
Remarks string `xorm:"TEXT" json:"remarks,omitempty"`
|
||||||
|
|
|
@ -1,57 +1,30 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
type client struct {
|
||||||
"encoding/json"
|
channels []chan any
|
||||||
"github.com/gobwas/ws"
|
|
||||||
"github.com/gobwas/ws/wsutil"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Clients struct {
|
|
||||||
sync.Map
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Clients) Write(p []byte) (n int, err error) {
|
func (c *client) Write(p []byte) (n int, err error) {
|
||||||
data := map[string]string{"type": "manuallyRunScript", "message": string(p)}
|
data := map[string]string{"type": "manuallyRunScript", "message": string(p)}
|
||||||
content, _ := json.Marshal(data)
|
for _, channel := range c.channels {
|
||||||
var deleSlince []string
|
select {
|
||||||
c.Range(func(key, value any) bool {
|
case channel <- data:
|
||||||
conn := value.(*Client).conn
|
default:
|
||||||
writer := wsutil.NewWriter(conn, ws.StateServerSide, ws.OpText)
|
|
||||||
_, err := writer.Write(content)
|
|
||||||
if err != nil {
|
|
||||||
deleSlince = append(deleSlince, key.(string))
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
err = writer.Flush()
|
|
||||||
if err != nil {
|
|
||||||
deleSlince = append(deleSlince, key.(string))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
for _, s := range deleSlince {
|
|
||||||
c.Delete(s)
|
|
||||||
}
|
}
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
MyClient *Clients
|
MyClient *client
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
MyClient = new(Clients)
|
MyClient = new(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
func AddChan(c chan any) {
|
||||||
conn net.Conn
|
MyClient.channels = append(MyClient.channels, c)
|
||||||
}
|
|
||||||
|
|
||||||
func AddWs(id string, conn net.Conn) {
|
|
||||||
MyClient.Store(id, &Client{
|
|
||||||
conn: conn,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var VERSION = "v1.0.0"
|
var VERSION = "v1.0.0"
|
||||||
|
@ -24,3 +26,15 @@ func GetKey(key, defaultValue string) string {
|
||||||
func GetVersion() string {
|
func GetVersion() string {
|
||||||
return VERSION
|
return VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var address string
|
||||||
|
|
||||||
|
func SetAddress(add string) {
|
||||||
|
address = add
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListenPort() int {
|
||||||
|
split := strings.Split(address, ":")
|
||||||
|
port, _ := strconv.Atoi(split[1])
|
||||||
|
return port
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package cron
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/huoxue1/qinglong-go/models"
|
"github.com/huoxue1/qinglong-go/models"
|
||||||
"github.com/robfig/cron/v3"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,17 +11,17 @@ func GetCrons(page, size int, searchValue string, sorter map[string]string, filt
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddCron(cron *models.Crontabs) (int, error) {
|
func AddCron(cron *models.Crontabs) (int, error) {
|
||||||
AddTask(cron)
|
err := AddTask(cron)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
return models.AddCron(cron)
|
return models.AddCron(cron)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteCron(ids []int) error {
|
func DeleteCron(ids []int) error {
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
|
||||||
c, _ := manager.Load(id)
|
DeleteTask(id)
|
||||||
if c != nil {
|
|
||||||
c.(*cron.Cron).Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
err := models.DeleteCron(id)
|
err := models.DeleteCron(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -40,10 +39,7 @@ func UpdateCron(c1 *models.Crontabs) error {
|
||||||
crontabs.Schedule = c1.Schedule
|
crontabs.Schedule = c1.Schedule
|
||||||
crontabs.Updatedat = time.Now().Format(time.RFC3339)
|
crontabs.Updatedat = time.Now().Format(time.RFC3339)
|
||||||
|
|
||||||
c, _ := manager.Load(c1.Id)
|
DeleteTask(c1.Id)
|
||||||
if c != nil {
|
|
||||||
c.(*cron.Cron).Stop()
|
|
||||||
}
|
|
||||||
AddTask(c1)
|
AddTask(c1)
|
||||||
|
|
||||||
return models.UpdateCron(crontabs)
|
return models.UpdateCron(crontabs)
|
||||||
|
@ -52,8 +48,7 @@ func UpdateCron(c1 *models.Crontabs) error {
|
||||||
func DisableCron(ids []int) error {
|
func DisableCron(ids []int) error {
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
|
||||||
c, _ := manager.Load(id)
|
DeleteTask(id)
|
||||||
c.(*cron.Cron).Stop()
|
|
||||||
|
|
||||||
cron, err := models.GetCron(id)
|
cron, err := models.GetCron(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -120,7 +115,7 @@ func RunCron(ids []int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
runCron(crontab)
|
runCron(crontab, true)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/huoxue1/qinglong-go/service/config"
|
"github.com/huoxue1/qinglong-go/service/config"
|
||||||
"github.com/huoxue1/qinglong-go/service/env"
|
"github.com/huoxue1/qinglong-go/service/env"
|
||||||
"github.com/huoxue1/qinglong-go/utils"
|
"github.com/huoxue1/qinglong-go/utils"
|
||||||
"github.com/robfig/cron/v3"
|
cron_manager "github.com/huoxue1/qinglong-go/utils/cron-manager"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -22,7 +22,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
manager sync.Map
|
|
||||||
execManager sync.Map
|
execManager sync.Map
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,7 +57,7 @@ func stopCron(crontabs *models.Crontabs) {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCron(crontabs *models.Crontabs) {
|
func runCron(crontabs *models.Crontabs, isNow bool) {
|
||||||
envFromDb := env.LoadEnvFromDb()
|
envFromDb := env.LoadEnvFromDb()
|
||||||
envfromFile := env.LoadEnvFromFile("data/config/config.sh")
|
envfromFile := env.LoadEnvFromFile("data/config/config.sh")
|
||||||
for s, s2 := range envfromFile {
|
for s, s2 := range envfromFile {
|
||||||
|
@ -119,7 +118,8 @@ func runCron(crontabs *models.Crontabs) {
|
||||||
if strings.HasPrefix(ta.cmd, "go") {
|
if strings.HasPrefix(ta.cmd, "go") {
|
||||||
cmdDir = ta.dir
|
cmdDir = ta.dir
|
||||||
}
|
}
|
||||||
go utils.RunWithOption(ctx, &utils.RunOption{
|
option := &utils.RunOption{
|
||||||
|
Ctx: ctx,
|
||||||
Command: ta.cmd,
|
Command: ta.cmd,
|
||||||
Env: envFromDb,
|
Env: envFromDb,
|
||||||
OnStart: func(ctx context.Context) {
|
OnStart: func(ctx context.Context) {
|
||||||
|
@ -138,33 +138,29 @@ func runCron(crontabs *models.Crontabs) {
|
||||||
},
|
},
|
||||||
LogFile: file,
|
LogFile: file,
|
||||||
CmdDir: cmdDir,
|
CmdDir: cmdDir,
|
||||||
})
|
}
|
||||||
|
if isNow {
|
||||||
|
go utils.RunWithOption(ctx, option)
|
||||||
|
} else {
|
||||||
|
_ = run(option)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddTask(crontabs *models.Crontabs) {
|
func AddTask(crontabs *models.Crontabs) error {
|
||||||
crons := strings.Split(crontabs.Schedule, " ")
|
err := cron_manager.AddCron(fmt.Sprintf("cron_%d", crontabs.Id), crontabs.Schedule, func() {
|
||||||
var c *cron.Cron
|
runCron(crontabs, false)
|
||||||
if len(crons) == 5 {
|
|
||||||
c = cron.New()
|
|
||||||
|
|
||||||
} else if len(crons) == 6 {
|
|
||||||
c = cron.New(cron.WithParser(
|
|
||||||
cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)))
|
|
||||||
} else {
|
|
||||||
log.Errorf("the task %s cron %s is error", crontabs.Name, crontabs.Command)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err := c.AddFunc(crontabs.Schedule, func() {
|
|
||||||
runCron(crontabs)
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("添加task错误" + crontabs.Schedule + err.Error())
|
log.Errorln("添加定时任务错误" + err.Error())
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
c.Start()
|
return nil
|
||||||
manager.Store(crontabs.Id, c)
|
}
|
||||||
|
|
||||||
|
func DeleteTask(id int) error {
|
||||||
|
return cron_manager.DeleteCron(fmt.Sprintf("cron_%d", id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handCommand(command string) *task {
|
func handCommand(command string) *task {
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cron
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/huoxue1/qinglong-go/utils"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/panjf2000/ants/v2"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
initPool()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pool *ants.PoolWithFunc
|
||||||
|
)
|
||||||
|
|
||||||
|
func run(task *utils.RunOption) error {
|
||||||
|
return pool.Invoke(task)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initPool() {
|
||||||
|
|
||||||
|
pool1, err := ants.NewPoolWithFunc(5, func(i2 interface{}) {
|
||||||
|
option := i2.(*utils.RunOption)
|
||||||
|
utils.RunWithOption(option.Ctx, option)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("创建定时任务协程池失败" + err.Error())
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
pool = pool1
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/huoxue1/qinglong-go/models"
|
"github.com/huoxue1/qinglong-go/models"
|
||||||
|
"github.com/huoxue1/qinglong-go/service/config"
|
||||||
"github.com/huoxue1/qinglong-go/utils"
|
"github.com/huoxue1/qinglong-go/utils"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -47,7 +48,8 @@ func addPythonDep(dep *models.Dependences) {
|
||||||
buffer := bytes.NewBufferString(log)
|
buffer := bytes.NewBufferString(log)
|
||||||
ctx := context.WithValue(context.Background(), "cancel", make(chan int, 1))
|
ctx := context.WithValue(context.Background(), "cancel", make(chan int, 1))
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
utils.RunTask(ctx, fmt.Sprintf("pip install %s", dep.Name), map[string]string{}, func(ctx context.Context) {
|
pip := config.GetKey("PipCmd", "pip")
|
||||||
|
utils.RunTask(ctx, fmt.Sprintf(pip+" install %s", dep.Name), map[string]string{}, func(ctx context.Context) {
|
||||||
writer := ctx.Value("log").(io.Writer)
|
writer := ctx.Value("log").(io.Writer)
|
||||||
writer.Write([]byte(fmt.Sprintf("##开始执行.. %s\n\n", now.Format("2006-01-02 15:04:05"))))
|
writer.Write([]byte(fmt.Sprintf("##开始执行.. %s\n\n", now.Format("2006-01-02 15:04:05"))))
|
||||||
}, func(ctx context.Context) {
|
}, func(ctx context.Context) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ func DisableEnv(ids []int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
env.Status = &DISABLESTATUS
|
env.Status = DISABLESTATUS
|
||||||
err = models.UpdateEnv(env)
|
err = models.UpdateEnv(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -59,7 +59,7 @@ func EnableEnv(ids []int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
env.Status = &ENABLESTATUS
|
env.Status = ENABLESTATUS
|
||||||
err = models.UpdateEnv(env)
|
err = models.UpdateEnv(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -86,6 +86,9 @@ func LoadEnvFromDb() map[string]string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for _, env := range envs {
|
for _, env := range envs {
|
||||||
|
if env.Status == 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if _, ok := result[env.Name]; ok {
|
if _, ok := result[env.Name]; ok {
|
||||||
result[env.Name] = result[env.Name] + "&" + env.Value
|
result[env.Name] = result[env.Name] + "&" + env.Value
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/huoxue1/qinglong-go/service/client"
|
"github.com/google/uuid"
|
||||||
"github.com/huoxue1/qinglong-go/service/env"
|
"github.com/huoxue1/qinglong-go/service/env"
|
||||||
"github.com/huoxue1/qinglong-go/utils"
|
"github.com/huoxue1/qinglong-go/utils"
|
||||||
"io"
|
"io"
|
||||||
|
@ -13,6 +13,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,26 +31,71 @@ var (
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"__pycache__",
|
"__pycache__",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scriptRunPidMap sync.Map
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run(filePath, content string) error {
|
type task struct {
|
||||||
|
id string
|
||||||
|
c chan int
|
||||||
|
logPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Stop(id string) {
|
||||||
|
value, loaded := scriptRunPidMap.Load(id)
|
||||||
|
if !loaded || value == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t := value.(*task)
|
||||||
|
t.c <- 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func Log(id string) string {
|
||||||
|
value, ok := scriptRunPidMap.Load(id)
|
||||||
|
if !ok || value == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
t := value.(*task)
|
||||||
|
file, err := os.ReadFile(t.logPath)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(file)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run(filePath, content string) (string, error) {
|
||||||
err := os.WriteFile(path.Join("data", "scripts", filePath), []byte(content), 0666)
|
err := os.WriteFile(path.Join("data", "scripts", filePath), []byte(content), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
id := uuid.New().String()
|
||||||
|
logPath := "data/log/" + time.Now().Format("2006-01-02") + "/" + filepath.Base(filePath) + "_" + id + ".log"
|
||||||
cmd := getCmd(filePath)
|
cmd := getCmd(filePath)
|
||||||
cancelChan := make(chan int, 1)
|
cancelChan := make(chan int, 1)
|
||||||
ctx := context.WithValue(context.Background(), "cancel", cancelChan)
|
ctx := context.WithValue(context.Background(), "cancel", cancelChan)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
utils.RunTask(ctx, cmd, env.GetALlEnv(), func(ctx context.Context) {
|
file, _ := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE, 0666)
|
||||||
|
go utils.RunTask(ctx, cmd, env.GetALlEnv(), func(ctx context.Context) {
|
||||||
writer := ctx.Value("log").(io.Writer)
|
writer := ctx.Value("log").(io.Writer)
|
||||||
_, _ = writer.Write([]byte(fmt.Sprintf("##开始执行.. %s\n\n", now.Format("2006-01-02 15:04:05"))))
|
_, _ = writer.Write([]byte(fmt.Sprintf("##开始执行.. %s\n\n", now.Format("2006-01-02 15:04:05"))))
|
||||||
}, func(ctx context.Context) {
|
}, func(ctx context.Context) {
|
||||||
writer := ctx.Value("log").(io.Writer)
|
writer := ctx.Value("log").(io.Writer)
|
||||||
_, _ = writer.Write([]byte(fmt.Sprintf("\n##执行结束.. %s,耗时%.1f秒\n\n", time.Now().Format("2006-01-02 15:04:05"), time.Now().Sub(now).Seconds())))
|
_, _ = writer.Write([]byte(fmt.Sprintf("\n##执行结束.. %s,耗时%.1f秒\n\n", time.Now().Format("2006-01-02 15:04:05"), time.Now().Sub(now).Seconds())))
|
||||||
_ = os.Remove(filePath)
|
_ = os.Remove(filePath)
|
||||||
}, client.MyClient)
|
// 等待结束三分钟后再删除
|
||||||
return nil
|
go func() {
|
||||||
|
time.Sleep(time.Minute * 3)
|
||||||
|
scriptRunPidMap.LoadAndDelete(id)
|
||||||
|
}()
|
||||||
|
|
||||||
|
}, file)
|
||||||
|
scriptRunPidMap.Store(id, &task{
|
||||||
|
id: id,
|
||||||
|
c: cancelChan,
|
||||||
|
logPath: logPath,
|
||||||
|
})
|
||||||
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCmd(filePath string) string {
|
func getCmd(filePath string) string {
|
||||||
|
@ -59,7 +105,8 @@ func getCmd(filePath string) string {
|
||||||
return fmt.Sprintf("%s %s", "node", filePath)
|
return fmt.Sprintf("%s %s", "node", filePath)
|
||||||
case ".py":
|
case ".py":
|
||||||
return fmt.Sprintf("%s %s", "python", filePath)
|
return fmt.Sprintf("%s %s", "python", filePath)
|
||||||
|
case ".go":
|
||||||
|
return fmt.Sprintf("go run %s", filePath)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/huoxue1/qinglong-go/service/config"
|
"github.com/huoxue1/qinglong-go/service/config"
|
||||||
"github.com/huoxue1/qinglong-go/service/cron"
|
"github.com/huoxue1/qinglong-go/service/cron"
|
||||||
"github.com/huoxue1/qinglong-go/utils"
|
"github.com/huoxue1/qinglong-go/utils"
|
||||||
|
cron_manager "github.com/huoxue1/qinglong-go/utils/cron-manager"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -25,6 +26,34 @@ var (
|
||||||
manager sync.Map
|
manager sync.Map
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.Infoln("开始初始化订阅任务定时!")
|
||||||
|
subscriptions, err := models.QuerySubscription("")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, subscription := range subscriptions {
|
||||||
|
cron_manager.AddCron(fmt.Sprintf("sub_%d", subscription.Id), subscription.GetCron(), func() {
|
||||||
|
downloadFiles(subscription)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDepFiles() []string {
|
||||||
|
var files []string
|
||||||
|
dir, err := os.ReadDir(path.Join("data", "deps"))
|
||||||
|
if err != nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
for _, entry := range dir {
|
||||||
|
if !entry.IsDir() {
|
||||||
|
files = append(files, entry.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
func stopSubscription(sub *models.Subscriptions) {
|
func stopSubscription(sub *models.Subscriptions) {
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = recover()
|
_ = recover()
|
||||||
|
@ -41,12 +70,13 @@ func stopSubscription(sub *models.Subscriptions) {
|
||||||
|
|
||||||
func downloadFiles(subscriptions *models.Subscriptions) {
|
func downloadFiles(subscriptions *models.Subscriptions) {
|
||||||
if subscriptions.Type == "public-repo" {
|
if subscriptions.Type == "public-repo" {
|
||||||
os.RemoveAll(path.Join("data", "scripts", subscriptions.Alias))
|
|
||||||
os.RemoveAll(path.Join("data", "repo", subscriptions.Alias))
|
os.RemoveAll(path.Join("data", "repo", subscriptions.Alias))
|
||||||
err := downloadPublicRepo(subscriptions)
|
err := downloadPublicRepo(subscriptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
os.RemoveAll(path.Join("data", "scripts", subscriptions.Alias))
|
||||||
if config.GetKey("AutoAddCron", "true") == "true" {
|
if config.GetKey("AutoAddCron", "true") == "true" {
|
||||||
addScripts(subscriptions)
|
addScripts(subscriptions)
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,6 +88,7 @@ func downloadFiles(subscriptions *models.Subscriptions) {
|
||||||
_ = file.Close()
|
_ = file.Close()
|
||||||
subscriptions.Status = 1
|
subscriptions.Status = 1
|
||||||
models.UpdateSubscription(subscriptions)
|
models.UpdateSubscription(subscriptions)
|
||||||
|
manager.LoadAndDelete(subscriptions.Id)
|
||||||
} else if subscriptions.Type == "file" {
|
} else if subscriptions.Type == "file" {
|
||||||
addRawFiles(subscriptions)
|
addRawFiles(subscriptions)
|
||||||
}
|
}
|
||||||
|
@ -128,7 +159,7 @@ func downloadPublicRepo(subscriptions *models.Subscriptions) error {
|
||||||
manager.Store(subscriptions.Id, func() {
|
manager.Store(subscriptions.Id, func() {
|
||||||
command.Process.Kill()
|
command.Process.Kill()
|
||||||
})
|
})
|
||||||
defer manager.LoadAndDelete(subscriptions.Id)
|
|
||||||
go io.Copy(io.MultiWriter(file, os.Stdout), pipe)
|
go io.Copy(io.MultiWriter(file, os.Stdout), pipe)
|
||||||
go io.Copy(file, stderrPipe)
|
go io.Copy(file, stderrPipe)
|
||||||
command.Wait()
|
command.Wait()
|
||||||
|
@ -136,6 +167,7 @@ func downloadPublicRepo(subscriptions *models.Subscriptions) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func addScripts(subscriptions *models.Subscriptions) {
|
func addScripts(subscriptions *models.Subscriptions) {
|
||||||
|
depFiles := getDepFiles()
|
||||||
file, _ := os.OpenFile(subscriptions.LogPath, os.O_RDWR|os.O_APPEND, 0666)
|
file, _ := os.OpenFile(subscriptions.LogPath, os.O_RDWR|os.O_APPEND, 0666)
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
var extensions []string
|
var extensions []string
|
||||||
|
@ -175,8 +207,7 @@ func addScripts(subscriptions *models.Subscriptions) {
|
||||||
if c != "" {
|
if c != "" {
|
||||||
command, err := models.GetCronByCommand(fmt.Sprintf("task %s", path.Join(subscriptions.Alias, entry.Name())))
|
command, err := models.GetCronByCommand(fmt.Sprintf("task %s", path.Join(subscriptions.Alias, entry.Name())))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
file.WriteString("已添加新的定时任务 " + name + "\n")
|
_, err1 := cron.AddCron(&models.Crontabs{
|
||||||
_, _ = cron.AddCron(&models.Crontabs{
|
|
||||||
Name: name,
|
Name: name,
|
||||||
Command: fmt.Sprintf("task %s", path.Join(subscriptions.Alias, entry.Name())),
|
Command: fmt.Sprintf("task %s", path.Join(subscriptions.Alias, entry.Name())),
|
||||||
Schedule: c,
|
Schedule: c,
|
||||||
|
@ -184,6 +215,12 @@ func addScripts(subscriptions *models.Subscriptions) {
|
||||||
Status: 1,
|
Status: 1,
|
||||||
Labels: []string{},
|
Labels: []string{},
|
||||||
})
|
})
|
||||||
|
if err1 != nil {
|
||||||
|
file.WriteString("定时任务添加失败: " + name + " " + err1.Error())
|
||||||
|
err1 = nil
|
||||||
|
} else {
|
||||||
|
file.WriteString("已添加新的定时任务 " + name + "\n")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
command.Name = name
|
command.Name = name
|
||||||
command.Schedule = c
|
command.Schedule = c
|
||||||
|
@ -199,6 +236,10 @@ func addScripts(subscriptions *models.Subscriptions) {
|
||||||
utils.Copy(path.Join("data", "repo", subscriptions.Alias, entry.Name()), path.Join("data", "scripts", subscriptions.Alias, entry.Name()))
|
utils.Copy(path.Join("data", "repo", subscriptions.Alias, entry.Name()), path.Join("data", "scripts", subscriptions.Alias, entry.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if utils.In(entry.Name(), depFiles) {
|
||||||
|
file.WriteString("已替换依赖文件: " + entry.Name() + "\n")
|
||||||
|
utils.Copy(path.Join("data", "deps", entry.Name()), path.Join("data", "scripts", subscriptions.Alias, entry.Name()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if config.GetKey("AutoDelCron", "true") == "true" {
|
if config.GetKey("AutoDelCron", "true") == "true" {
|
||||||
for _, m := range cronMap {
|
for _, m := range cronMap {
|
||||||
|
@ -223,6 +264,10 @@ func addScripts(subscriptions *models.Subscriptions) {
|
||||||
CmdDir: path.Join("data", "scripts", subscriptions.Alias),
|
CmdDir: path.Join("data", "scripts", subscriptions.Alias),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
for _, depFile := range depFiles {
|
||||||
|
utils.Copy(path.Join("data", "deps", depFile), path.Join("data", "scripts", subscriptions.Alias, depFile))
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSubCron(filePath string) (name string, cron string, err error) {
|
func getSubCron(filePath string) (name string, cron string, err error) {
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package cron_manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/huoxue1/qinglong-go/utils/log"
|
||||||
|
"github.com/robfig/cron/v3"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
manager sync.Map
|
||||||
|
defaultCron *cron.Cron
|
||||||
|
SixCron *cron.Cron
|
||||||
|
)
|
||||||
|
|
||||||
|
type mapValue struct {
|
||||||
|
en cron.EntryID
|
||||||
|
c *cron.Cron
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
defaultCron = cron.New(cron.WithChain(cron.Recover(&log.CronLog{})))
|
||||||
|
SixCron = cron.New(cron.WithChain(cron.Recover(&log.CronLog{})), cron.WithParser(
|
||||||
|
cron.NewParser(cron.Second|cron.Minute|cron.Hour|cron.Dom|cron.Month|cron.Dow|cron.Descriptor)))
|
||||||
|
defaultCron.Start()
|
||||||
|
SixCron.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddCron(id string, value string, task func()) error {
|
||||||
|
if value == "7 7 7 7 7" {
|
||||||
|
value = "7 7 7 7 6"
|
||||||
|
}
|
||||||
|
crons := strings.Split(value, " ")
|
||||||
|
cronCmd := defaultCron
|
||||||
|
if len(crons) == 6 {
|
||||||
|
cronCmd = SixCron
|
||||||
|
}
|
||||||
|
en, err := cronCmd.AddFunc(value, task)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
manager.Store(id, &mapValue{en, cronCmd})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteCron(id string) error {
|
||||||
|
value, loaded := manager.LoadAndDelete(id)
|
||||||
|
if !loaded {
|
||||||
|
return errors.New("the cron " + id + " not found!")
|
||||||
|
}
|
||||||
|
v := value.(*mapValue)
|
||||||
|
v.c.Remove(v.en)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package cron_manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAddCron(t *testing.T) {
|
||||||
|
_ = AddCron("test1", "*/5 * * * * ?", func() {
|
||||||
|
fmt.Println(time.Now().Format("15:04:05"))
|
||||||
|
})
|
||||||
|
time.Sleep(time.Minute)
|
||||||
|
DeleteCron("test1")
|
||||||
|
fmt.Println("已停止")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
}
|
|
@ -74,3 +74,14 @@ func (l *LogWriter) Write(p []byte) (n int, err error) {
|
||||||
log.Debugln(string(p))
|
log.Debugln(string(p))
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CronLog struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CronLog) Info(msg string, keysAndValues ...interface{}) {
|
||||||
|
log.Infoln(msg, " ", keysAndValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CronLog) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||||
|
log.Errorln(err)
|
||||||
|
}
|
||||||
|
|
19
utils/run.go
19
utils/run.go
|
@ -2,6 +2,9 @@ package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/huoxue1/qinglong-go/service/config"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -17,6 +20,10 @@ func RunTask(ctx context.Context, command string, env map[string]string, onStart
|
||||||
for s, s2 := range env {
|
for s, s2 := range env {
|
||||||
cmd.Env = append(cmd.Env, s+"="+s2)
|
cmd.Env = append(cmd.Env, s+"="+s2)
|
||||||
}
|
}
|
||||||
|
environ := os.Environ()
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
port := config.ListenPort()
|
||||||
|
cmd.Env = append(append(cmd.Env, environ...), "QL_DIR="+dir, fmt.Sprintf("QL_PORT=%d", port))
|
||||||
stdoutPipe, _ := cmd.StdoutPipe()
|
stdoutPipe, _ := cmd.StdoutPipe()
|
||||||
stderrPipe, _ := cmd.StderrPipe()
|
stderrPipe, _ := cmd.StderrPipe()
|
||||||
cmd.Dir = "./data/scripts/"
|
cmd.Dir = "./data/scripts/"
|
||||||
|
@ -53,6 +60,7 @@ func RunTask(ctx context.Context, command string, env map[string]string, onStart
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunOption struct {
|
type RunOption struct {
|
||||||
|
Ctx context.Context
|
||||||
Command string
|
Command string
|
||||||
Env map[string]string
|
Env map[string]string
|
||||||
OnStart func(ctx context.Context)
|
OnStart func(ctx context.Context)
|
||||||
|
@ -62,12 +70,21 @@ type RunOption struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunWithOption(ctx context.Context, option *RunOption) {
|
func RunWithOption(ctx context.Context, option *RunOption) {
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorln("执行command出现异常")
|
||||||
|
log.Errorln(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
cmd := exec.Command(strings.Split(option.Command, " ")[0], strings.Split(option.Command, " ")[1:]...)
|
cmd := exec.Command(strings.Split(option.Command, " ")[0], strings.Split(option.Command, " ")[1:]...)
|
||||||
for s, s2 := range option.Env {
|
for s, s2 := range option.Env {
|
||||||
cmd.Env = append(cmd.Env, s+"="+s2)
|
cmd.Env = append(cmd.Env, s+"="+s2)
|
||||||
}
|
}
|
||||||
environ := os.Environ()
|
environ := os.Environ()
|
||||||
cmd.Env = append(cmd.Env, environ...)
|
dir, _ := os.Getwd()
|
||||||
|
port := config.ListenPort()
|
||||||
|
cmd.Env = append(append(cmd.Env, environ...), "QL_DIR="+dir, fmt.Sprintf("QL_PORT=%d", port))
|
||||||
stdoutPipe, _ := cmd.StdoutPipe()
|
stdoutPipe, _ := cmd.StdoutPipe()
|
||||||
stderrPipe, _ := cmd.StderrPipe()
|
stderrPipe, _ := cmd.StderrPipe()
|
||||||
cmd.Dir = option.CmdDir
|
cmd.Dir = option.CmdDir
|
||||||
|
|
Loading…
Reference in New Issue