[agent-go] 开始使用GO重构Agent部分
This commit is contained in:
@@ -1,38 +1,3 @@
|
|||||||
module agent-go
|
module agent-go
|
||||||
|
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/gin-gonic/gin v1.9.0
|
|
||||||
github.com/go-playground/validator/v10 v10.11.2
|
|
||||||
gorm.io/driver/mysql v1.4.7
|
|
||||||
gorm.io/gorm v1.24.6
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/bytedance/sonic v1.8.0 // indirect
|
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
|
||||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
|
||||||
github.com/goccy/go-json v0.10.0 // indirect
|
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
|
||||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
|
||||||
golang.org/x/crypto v0.5.0 // indirect
|
|
||||||
golang.org/x/net v0.7.0 // indirect
|
|
||||||
golang.org/x/sys v0.5.0 // indirect
|
|
||||||
golang.org/x/text v0.7.0 // indirect
|
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
)
|
|
||||||
|
|||||||
120
agent-go/main.go
120
agent-go/main.go
@@ -1,125 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"agent-go/router"
|
|
||||||
"agent-go/service"
|
|
||||||
"fmt"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/gin-gonic/gin/binding"
|
|
||||||
"github.com/go-playground/validator/v10"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func myValidate(fl validator.FieldLevel) bool {
|
|
||||||
fmt.Println(fl.Field().Interface().(int))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// init the db connection
|
|
||||||
service.InitDB()
|
|
||||||
|
|
||||||
// all the route
|
|
||||||
engine := router.Routers()
|
|
||||||
|
|
||||||
// Get方法
|
|
||||||
engine.GET("/ping", func(c *gin.Context) {
|
|
||||||
|
|
||||||
statusOK := http.StatusOK
|
|
||||||
c.JSON(
|
|
||||||
statusOK,
|
|
||||||
gin.H{})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Post方法,接收request body的形式
|
|
||||||
engine.POST("/jsonPost", func(c *gin.Context) {
|
|
||||||
|
|
||||||
// 自定义 请求规则验证器
|
|
||||||
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
|
||||||
v.RegisterValidation("myValidation", myValidate)
|
|
||||||
}
|
|
||||||
|
|
||||||
var p string
|
|
||||||
err := c.ShouldBindJSON(&p)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 上传文件的操作 前端上传文件使用的是form-data的形式
|
|
||||||
// 单个文件上传
|
|
||||||
engine.POST("/upload", func(c *gin.Context) {
|
|
||||||
file, err := c.FormFile("file") // 获取上传的文件
|
|
||||||
if err != nil {
|
|
||||||
c.String(400, fmt.Sprintf("get form err: %s", err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 如果有其他的表单信息
|
|
||||||
c.DefaultPostForm("name", "default-file-name")
|
|
||||||
|
|
||||||
// 打印文件信息
|
|
||||||
fmt.Printf("File Name: %s\n", file.Filename)
|
|
||||||
fmt.Printf("File Size: %d bytes\n", file.Size)
|
|
||||||
fmt.Printf("MIME Type: %s\n", file.Header.Get("Content-Type"))
|
|
||||||
|
|
||||||
// 保存文件到本地
|
|
||||||
err = c.SaveUploadedFile(file, "./"+file.Filename)
|
|
||||||
if err != nil {
|
|
||||||
c.String(500, fmt.Sprintf("upload file err: %s", err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.String(200, fmt.Sprintf("%s uploaded successfully!", file.Filename))
|
|
||||||
})
|
|
||||||
|
|
||||||
// 多个文件上传
|
|
||||||
engine.POST("/multi-upload", func(c *gin.Context) {
|
|
||||||
form, err := c.MultipartForm() // 获取多个文件上传表单
|
|
||||||
if err != nil {
|
|
||||||
c.String(400, fmt.Sprintf("get form err: %s", err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 遍历所有上传的文件
|
|
||||||
files := form.File["files"]
|
|
||||||
for _, file := range files {
|
|
||||||
// 打印文件信息
|
|
||||||
fmt.Printf("File Name: %s\n", file.Filename)
|
|
||||||
fmt.Printf("File Size: %d bytes\n", file.Size)
|
|
||||||
fmt.Printf("MIME Type: %s\n", file.Header.Get("Content-Type"))
|
|
||||||
|
|
||||||
// 保存文件到本地
|
|
||||||
err = c.SaveUploadedFile(file, "./"+file.Filename)
|
|
||||||
if err != nil {
|
|
||||||
c.String(500, fmt.Sprintf("upload file err: %s", err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.String(200, fmt.Sprintf("%d files uploaded successfully!", len(files)))
|
|
||||||
})
|
|
||||||
|
|
||||||
// 返回静态文件
|
|
||||||
engine.GET("/file", func(c *gin.Context) {
|
|
||||||
c.File("./example.txt") // 返回指定路径的文件
|
|
||||||
})
|
|
||||||
|
|
||||||
// 返回动态生成的文件
|
|
||||||
engine.GET("/download", func(c *gin.Context) {
|
|
||||||
content := "Hello, world!"
|
|
||||||
fileName := "example.txt"
|
|
||||||
|
|
||||||
// 设置响应头,使浏览器可以下载文件
|
|
||||||
c.Header("Content-Disposition", "attachment; filename="+fileName)
|
|
||||||
c.Header("Content-Type", "application/octet-stream")
|
|
||||||
c.Header("Content-Transfer-Encoding", "binary")
|
|
||||||
c.Header("Cache-Control", "no-cache")
|
|
||||||
|
|
||||||
// 将内容写入响应体中
|
|
||||||
c.String(http.StatusOK, content)
|
|
||||||
})
|
|
||||||
|
|
||||||
engine.Run(":9090")
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
31
agent-go/readme.md
Normal file
31
agent-go/readme.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
使用GO语言重构Octopus-Agent项目
|
||||||
|
---
|
||||||
|
|
||||||
|
## Message
|
||||||
|
|
||||||
|
1. Agent注册与离线机制
|
||||||
|
2. 从环境变量中获取信息
|
||||||
|
|
||||||
|
## Executor
|
||||||
|
|
||||||
|
1. 利用协程池
|
||||||
|
1. 实现任务超时控制-可控,可不控
|
||||||
|
2. 任务异步非阻塞式执行
|
||||||
|
|
||||||
|
2. 执行Shell命令
|
||||||
|
1. 简单的命令 -- 单行命令
|
||||||
|
2. 管道命令 -- 管道式命令-复杂单行命令
|
||||||
|
3. 完整体命令 -- 多行命令
|
||||||
|
4. shell脚本 -- 执行shell脚本
|
||||||
|
|
||||||
|
3. 执行结果上报
|
||||||
|
1. 执行日志合并收集,统一上报
|
||||||
|
2. 执行结果上报
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
1. 版本信息汇报
|
||||||
|
2. 收集Agent自身的服务器信息
|
||||||
|
3. 上报Agent的版本信息
|
||||||
|
|
||||||
|
##
|
||||||
38
server-go/go.mod
Normal file
38
server-go/go.mod
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
module server-go
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gin-gonic/gin v1.9.0
|
||||||
|
github.com/go-playground/validator/v10 v10.11.2
|
||||||
|
gorm.io/driver/mysql v1.4.7
|
||||||
|
gorm.io/gorm v1.24.6
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/bytedance/sonic v1.8.0 // indirect
|
||||||
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.0 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||||
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||||
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||||
|
golang.org/x/crypto v0.5.0 // indirect
|
||||||
|
golang.org/x/net v0.7.0 // indirect
|
||||||
|
golang.org/x/sys v0.5.0 // indirect
|
||||||
|
golang.org/x/text v0.7.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
125
server-go/main.go
Normal file
125
server-go/main.go
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"net/http"
|
||||||
|
"server-go/router"
|
||||||
|
"server-go/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
func myValidate(fl validator.FieldLevel) bool {
|
||||||
|
fmt.Println(fl.Field().Interface().(int))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// init the db connection
|
||||||
|
service.InitDB()
|
||||||
|
|
||||||
|
// all the route
|
||||||
|
engine := router.Routers()
|
||||||
|
|
||||||
|
// Get方法
|
||||||
|
engine.GET("/ping", func(c *gin.Context) {
|
||||||
|
|
||||||
|
statusOK := http.StatusOK
|
||||||
|
c.JSON(
|
||||||
|
statusOK,
|
||||||
|
gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Post方法,接收request body的形式
|
||||||
|
engine.POST("/jsonPost", func(c *gin.Context) {
|
||||||
|
|
||||||
|
// 自定义 请求规则验证器
|
||||||
|
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
||||||
|
v.RegisterValidation("myValidation", myValidate)
|
||||||
|
}
|
||||||
|
|
||||||
|
var p string
|
||||||
|
err := c.ShouldBindJSON(&p)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 上传文件的操作 前端上传文件使用的是form-data的形式
|
||||||
|
// 单个文件上传
|
||||||
|
engine.POST("/upload", func(c *gin.Context) {
|
||||||
|
file, err := c.FormFile("file") // 获取上传的文件
|
||||||
|
if err != nil {
|
||||||
|
c.String(400, fmt.Sprintf("get form err: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 如果有其他的表单信息
|
||||||
|
c.DefaultPostForm("name", "default-file-name")
|
||||||
|
|
||||||
|
// 打印文件信息
|
||||||
|
fmt.Printf("File Name: %s\n", file.Filename)
|
||||||
|
fmt.Printf("File Size: %d bytes\n", file.Size)
|
||||||
|
fmt.Printf("MIME Type: %s\n", file.Header.Get("Content-Type"))
|
||||||
|
|
||||||
|
// 保存文件到本地
|
||||||
|
err = c.SaveUploadedFile(file, "./"+file.Filename)
|
||||||
|
if err != nil {
|
||||||
|
c.String(500, fmt.Sprintf("upload file err: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.String(200, fmt.Sprintf("%s uploaded successfully!", file.Filename))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 多个文件上传
|
||||||
|
engine.POST("/multi-upload", func(c *gin.Context) {
|
||||||
|
form, err := c.MultipartForm() // 获取多个文件上传表单
|
||||||
|
if err != nil {
|
||||||
|
c.String(400, fmt.Sprintf("get form err: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历所有上传的文件
|
||||||
|
files := form.File["files"]
|
||||||
|
for _, file := range files {
|
||||||
|
// 打印文件信息
|
||||||
|
fmt.Printf("File Name: %s\n", file.Filename)
|
||||||
|
fmt.Printf("File Size: %d bytes\n", file.Size)
|
||||||
|
fmt.Printf("MIME Type: %s\n", file.Header.Get("Content-Type"))
|
||||||
|
|
||||||
|
// 保存文件到本地
|
||||||
|
err = c.SaveUploadedFile(file, "./"+file.Filename)
|
||||||
|
if err != nil {
|
||||||
|
c.String(500, fmt.Sprintf("upload file err: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.String(200, fmt.Sprintf("%d files uploaded successfully!", len(files)))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 返回静态文件
|
||||||
|
engine.GET("/file", func(c *gin.Context) {
|
||||||
|
c.File("./example.txt") // 返回指定路径的文件
|
||||||
|
})
|
||||||
|
|
||||||
|
// 返回动态生成的文件
|
||||||
|
engine.GET("/download", func(c *gin.Context) {
|
||||||
|
content := "Hello, world!"
|
||||||
|
fileName := "example.txt"
|
||||||
|
|
||||||
|
// 设置响应头,使浏览器可以下载文件
|
||||||
|
c.Header("Content-Disposition", "attachment; filename="+fileName)
|
||||||
|
c.Header("Content-Type", "application/octet-stream")
|
||||||
|
c.Header("Content-Transfer-Encoding", "binary")
|
||||||
|
c.Header("Cache-Control", "no-cache")
|
||||||
|
|
||||||
|
// 将内容写入响应体中
|
||||||
|
c.String(http.StatusOK, content)
|
||||||
|
})
|
||||||
|
|
||||||
|
engine.Run(":9090")
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"agent-go/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"server-go/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerRouter struct {
|
type ServerRouter struct {
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "agent-go/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"agent-go/entity"
|
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"server-go/entity"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitDB() *gorm.DB {
|
func InitDB() *gorm.DB {
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"agent-go/entity"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"server-go/entity"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerAPI struct {
|
type ServerAPI struct {
|
||||||
Reference in New Issue
Block a user