You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.0 KiB
144 lines
4.0 KiB
package vTool
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
"github.com/mark3labs/mcp-go/server"
|
|
"golang.org/x/crypto/ssh"
|
|
"mcp-go-db/vConfig"
|
|
)
|
|
|
|
// WarDeployTool 创建war包部署工具
|
|
func WarDeployTool(config *vConfig.Config, name string) mcp.Tool {
|
|
return mcp.NewTool(name,
|
|
mcp.WithDescription("部署war包到服务器"),
|
|
mcp.WithString("warPath",
|
|
mcp.Required(),
|
|
mcp.Description("war包路径"),
|
|
mcp.DefaultString("/path/to/default.war"),
|
|
),
|
|
mcp.WithString("server",
|
|
mcp.Required(),
|
|
mcp.Description("服务器地址"),
|
|
mcp.DefaultString("user@example.com:22"),
|
|
),
|
|
mcp.WithString("targetPath",
|
|
mcp.Required(),
|
|
mcp.Description("目标部署路径"),
|
|
mcp.DefaultString("/opt/tomcat/webapps/"),
|
|
),
|
|
mcp.WithString("startCmd",
|
|
mcp.Required(),
|
|
mcp.Description("启动服务命令"),
|
|
mcp.DefaultString("/opt/tomcat/bin/startup.sh"),
|
|
),
|
|
mcp.WithString("appName",
|
|
mcp.Required(),
|
|
mcp.Description("应用名称(用于进程过滤)"),
|
|
),
|
|
)
|
|
}
|
|
|
|
// deployWar 部署war包到服务器
|
|
func deployWar(ctx context.Context, request mcp.CallToolRequest, config *vConfig.Config) (*mcp.CallToolResult, error) {
|
|
args := request.Params.Arguments
|
|
|
|
// 获取密码
|
|
pwd := os.Getenv("pwd")
|
|
if pwd == "" {
|
|
return mcp.NewToolResultError("环境变量pwd未设置"), nil
|
|
}
|
|
|
|
// 解析服务器地址
|
|
serverParts := strings.Split(args["server"].(string), "@")
|
|
if len(serverParts) != 2 {
|
|
return mcp.NewToolResultError("服务器地址格式错误,应为user@host:port"), nil
|
|
}
|
|
hostParts := strings.Split(serverParts[1], ":")
|
|
if len(hostParts) != 2 {
|
|
return mcp.NewToolResultError("服务器地址格式错误,应为user@host:port"), nil
|
|
}
|
|
|
|
// 创建SSH配置
|
|
sshConfig := &ssh.ClientConfig{
|
|
User: serverParts[0],
|
|
Auth: []ssh.AuthMethod{
|
|
ssh.Password(pwd),
|
|
},
|
|
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
|
}
|
|
|
|
// 连接服务器
|
|
client, err := ssh.Dial("tcp", hostParts[0]+":"+hostParts[1], sshConfig)
|
|
if err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("SSH连接失败: %v", err)), nil
|
|
}
|
|
defer client.Close()
|
|
|
|
// 检查并杀死进程
|
|
session, err := client.NewSession()
|
|
if err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("创建会话失败: %v", err)), nil
|
|
}
|
|
defer session.Close()
|
|
|
|
// 查找并杀死进程
|
|
killCmd := fmt.Sprintf("ps -ef | grep %s | grep -v grep | awk '{print $2}' | xargs kill -9", args["appName"].(string))
|
|
if err := session.Run(killCmd); err != nil {
|
|
// 忽略错误,可能没有进程运行
|
|
}
|
|
|
|
// 上传war包
|
|
warData, err := ioutil.ReadFile(args["warPath"].(string))
|
|
if err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("读取war包失败: %v", err)), nil
|
|
}
|
|
|
|
targetFile := args["targetPath"].(string) + "/" + strings.Split(args["warPath"].(string), "/")[len(strings.Split(args["warPath"].(string), "/"))-1]
|
|
if err := scpUpload(client, warData, targetFile); err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("上传war包失败: %v", err)), nil
|
|
}
|
|
|
|
// 启动服务
|
|
if err := session.Run(args["startCmd"].(string)); err != nil {
|
|
return mcp.NewToolResultError(fmt.Sprintf("启动服务失败: %v", err)), nil
|
|
}
|
|
|
|
return &mcp.CallToolResult{
|
|
Content: []mcp.Content{
|
|
mcp.NewTextContent("war包部署成功"),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// scpUpload 通过SCP上传文件
|
|
func scpUpload(client *ssh.Client, data []byte, remotePath string) error {
|
|
session, err := client.NewSession()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer session.Close()
|
|
|
|
go func() {
|
|
w, _ := session.StdinPipe()
|
|
defer w.Close()
|
|
fmt.Fprintf(w, "C0644 %d %s\n", len(data), remotePath)
|
|
w.Write(data)
|
|
fmt.Fprint(w, "\x00")
|
|
}()
|
|
|
|
return session.Run("/usr/bin/scp -tr ./")
|
|
}
|
|
|
|
// RegisterWarTools 注册war包相关工具
|
|
func RegisterWarTools(s *server.MCPServer, config *vConfig.Config) {
|
|
tool := WarDeployTool(config, "部署war包")
|
|
s.AddTool(tool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
return deployWar(ctx, request, config)
|
|
})
|
|
}
|
|
|