大量的更新

This commit is contained in:
zeaslity
2025-02-26 17:44:03 +08:00
parent b8170e00d4
commit c751c21871
8 changed files with 323 additions and 42 deletions

View File

@@ -1,9 +1,9 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv) # Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
./agent-deploy/ agent-deploy/
./message_pusher/ message_pusher/
./port_forwarding/ port_forwarding/
./server/ server/
./server-go/ server-go/
./socks_txthinking/ socks_txthinking/
./source/ source/

View File

@@ -208,4 +208,116 @@ func addDockerSubcommands(cmd *cobra.Command) {
func addDockerComposeSubcommands(cmd *cobra.Command) { func addDockerComposeSubcommands(cmd *cobra.Command) {
installCmd := &cobra.Command{
Use: "online [version]",
Short: "安装Docker Compose",
Run: func(cmd *cobra.Command, args []string) {
log.Info("Installing Docker Compose...")
// 检查参数
if len(args) > 0 {
fmt.Printf("Installing Docker Compose version: %s\n", args[0])
}
// 默认安装最新版本
version := "latest"
if len(args) > 0 {
version = args[0]
}
// 如果是最新版本则通过GitHub API查询
if version == "latest" {
latestVersion, err := op.GetLatestGithubReleaseVersion("docker", "compose")
if err != nil {
log.Error("获取Docker Compose最新版本失败: %s", err)
} else {
version = latestVersion
log.Info("获取到Docker Compose最新版本: %s", version)
}
}
log.Info("安装 Docker Compose 版本: %s", version)
// 检查是否可以连接互联网
if config.CanConnectInternet() <= 1 {
log.Error("服务器无法连接互联网,无法在线安装 Docker Compose")
return
}
// 检查 Docker 是否已安装
dockerExists := op.CommandExistsByPath("docker")
if !dockerExists {
log.Error("Docker 未安装,请先安装 Docker")
return
}
// 根据架构选择合适的下载链接
arch := runtime.GOARCH
downloadURL := fmt.Sprintf("https://github.com/docker/compose/releases/download/%s/docker-compose-linux-%s", version, arch)
log.Info("Downloading Docker Compose from: %s", downloadURL)
// 下载 Docker Compose
ok, ccc := op.DownloadFile(downloadURL, "/usr/local/bin/docker-compose")
if !ok {
log.Error("下载 Docker Compose 失败: %s", ccc)
return
}
// 设置执行权限
chmodCmd := []string{"chmod", "+x", "/usr/local/bin/docker-compose"}
ok, resultLog := op.SingleLineCommandExecutor(chmodCmd)
if !ok {
log.Error("设置 Docker Compose 权限失败: %s", resultLog)
return
}
// 创建软链接
linkCmd := []string{"ln", "-sf", "/usr/local/bin/docker-compose", "/usr/bin/docker-compose"}
op.SingleLineCommandExecutor(linkCmd)
// 验证安装
verifyCmd := []string{"docker-compose", "--version"}
ok, resultLog = op.SingleLineCommandExecutor(verifyCmd)
if !ok {
log.Error("Docker Compose 安装验证失败: %s", resultLog)
return
}
log.Info("Docker Compose 安装成功: %s", resultLog)
},
}
removeCmd := &cobra.Command{
Use: "remove",
Short: "卸载Docker Compose",
Run: func(cmd *cobra.Command, args []string) {
log.Info("Removing Docker Compose...")
},
}
localCmd := &cobra.Command{
Use: "local [path]",
Short: "本地安装Docker Compose",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
log.Info("Installing Docker Compose from local file...")
},
}
versionCmd := &cobra.Command{
Use: "version",
Short: "查看Docker Compose版本",
Run: func(cmd *cobra.Command, args []string) {
log.Info("Docker Compose version...")
},
}
cmd.AddCommand(
installCmd,
removeCmd,
localCmd,
versionCmd,
)
} }

View File

@@ -3,9 +3,11 @@ package config
import ( import (
"agent-wdd/log" "agent-wdd/log"
"agent-wdd/utils" "agent-wdd/utils"
"os"
"runtime"
"github.com/spf13/viper" "github.com/spf13/viper"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"os"
) )
var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml" var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml"
@@ -14,9 +16,12 @@ var ConfigCache *Config
func init() { func init() {
// 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置 // 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置
if runtime.GOOS == "windows" {
homedir, _ := os.UserHomeDir()
WddConfigFilePath = homedir + "\\agent-wdd\\agent-wdd-config.yaml"
}
} }
// 配置结构体定义
type Config struct { type Config struct {
TimeStamp string `yaml:"timestamp"` TimeStamp string `yaml:"timestamp"`
ModifiedTimes int `yaml:"modifiedTimes"` ModifiedTimes int `yaml:"modifiedTimes"`

View File

@@ -3,12 +3,10 @@ package config
import ( import (
"agent-wdd/log" "agent-wdd/log"
"bufio" "bufio"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"syscall"
) )
var CommonDiskPath = []string{ var CommonDiskPath = []string{
@@ -82,32 +80,31 @@ func DiskListGather() {
} }
func (disk *Disk) calculateDiskUsage() { func (disk *Disk) calculateDiskUsage() {
var stat syscall.Statfs_t // var stat unix.Statfs_t
err := syscall.Statfs(disk.Path, &stat) // err := unix.Statfs(disk.Path, &stat)
if err != nil { // if err != nil {
log.Error("disk syscall error of %v", err) // log.Error("disk syscall error: %v", err)
// disk.Size = "0B"
// disk.Usage = "0B"
// disk.Percent = "0.00%"
// return
// }
disk.Size = "0B" // // 计算存储空间大小
disk.Usage = "0B" // totalBytes := stat.Blocks * uint64(stat.Bsize)
disk.Percent = "0.00%" // availBytes := stat.Bavail * uint64(stat.Bsize)
return // usedBytes := totalBytes - availBytes
}
// 计算存储空间大小 // // 格式化输出
totalBytes := stat.Blocks * uint64(stat.Bsize) // disk.Size = formatDiskSize(totalBytes)
availBytes := stat.Bavail * uint64(stat.Bsize) // disk.Usage = formatDiskSize(usedBytes)
usedBytes := totalBytes - availBytes
// 格式化输出 // if totalBytes == 0 {
disk.Size = formatDiskSize(totalBytes) // disk.Percent = "0.00%"
disk.Usage = formatDiskSize(usedBytes) // } else {
// percent := float64(usedBytes) / float64(totalBytes) * 100
if totalBytes == 0 { // disk.Percent = fmt.Sprintf("%.2f%%", percent)
disk.Percent = "0.00%" // }
} else {
percent := float64(usedBytes) / float64(totalBytes) * 100
disk.Percent = fmt.Sprintf("%.2f%%", percent)
}
} }
func formatDiskSize(bytes uint64) string { func formatDiskSize(bytes uint64) string {

View File

@@ -41,6 +41,23 @@ func (network *Network) Gather() {
// CanConnectInternet 判定主机能够上网 // CanConnectInternet 判定主机能够上网
func CanConnectInternet() int { func CanConnectInternet() int {
// 初始化 ConfigCache
if ConfigCache == nil {
ConfigCache = &Config{
TimeStamp: "",
ModifiedTimes: 0,
Agent: Agent{
OS: OS{},
Network: Network{},
CPU: CPU{},
Mem: Memory{},
Swap: Swap{},
Disks: []Disk{},
},
}
}
// 读取 config 文件,判定能否上网 // 读取 config 文件,判定能否上网
internetCode := ConfigCache.Agent.Network.Internet internetCode := ConfigCache.Agent.Network.Internet

View File

@@ -0,0 +1,43 @@
package op
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func DownloadFile(url string, path string) (bool, string) {
// 创建HTTP客户端
client := &http.Client{
Timeout: 5 * time.Second,
}
// 发送GET请求
resp, err := client.Get(url)
if err != nil {
return false, fmt.Sprintf("下载文件失败: %v", err)
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode != http.StatusOK {
return false, fmt.Sprintf("下载文件失败HTTP状态码: %d", resp.StatusCode)
}
// 创建目标文件
out, err := os.Create(path)
if err != nil {
return false, fmt.Sprintf("创建文件失败: %v", err)
}
defer out.Close()
// 将响应内容写入文件
_, err = io.Copy(out, resp.Body)
if err != nil {
return false, fmt.Sprintf("写入文件失败: %v", err)
}
return true, fmt.Sprintf("文件下载成功: %s", path)
}

View File

@@ -4,7 +4,12 @@ import (
"agent-wdd/config" "agent-wdd/config"
"agent-wdd/log" "agent-wdd/log"
"agent-wdd/utils" "agent-wdd/utils"
"encoding/json"
"fmt"
"io"
"net/http"
"strings" "strings"
"time"
) )
type PackageOperator struct { type PackageOperator struct {
@@ -36,12 +41,19 @@ var (
"yum", "remove", "-y", "yum", "remove", "-y",
}, },
upgradePrefix: []string{}, upgradePrefix: []string{},
initCommand: []string{
"yum", "makecache",
},
} }
) )
func (op *PackageOperator) Install(tools []string) { func (op *PackageOperator) Install(tools []string) bool {
// 判定本机的包管理Operator // 判定本机的包管理Operator
generatePackageOperator() ok := generatePackageOperator()
if !ok {
log.Error("PackageOperator init failed! 无法执行安装操作 %s", tools)
return false
}
// install seperately // install seperately
for _, tool := range tools { for _, tool := range tools {
@@ -51,14 +63,19 @@ func (op *PackageOperator) Install(tools []string) {
utils.BeautifulPrint(result) utils.BeautifulPrint(result)
} }
} }
return true
} }
// PackageInit 初始化包管理器, 如果本机是ubuntu或者debian, 则使用apt, 否则使用yum // PackageInit 初始化包管理器, 同样会判定主机是否可以联网,如果本机是ubuntu或者debian, 则使用apt, 否则使用yum
func (op *PackageOperator) PackageInit() { func (op *PackageOperator) PackageInit() bool {
log.Info("PackageInit !") log.Info("PackageInit !")
// 判定本机的包管理Operator // 判定本机的包管理Operator
generatePackageOperator() ok := generatePackageOperator()
if !ok {
return false
}
// package init // package init
os := config.ConfigCache.Agent.OS os := config.ConfigCache.Agent.OS
@@ -72,6 +89,8 @@ func (op *PackageOperator) PackageInit() {
} }
} }
return true
} }
func (op *PackageOperator) Remove(tools []string) { func (op *PackageOperator) Remove(tools []string) {
@@ -89,13 +108,20 @@ func (op *PackageOperator) Remove(tools []string) {
} }
func generatePackageOperator() { func generatePackageOperator() bool {
// cache return // cache return
if AgentPackOperator.initCommand != nil { if AgentPackOperator.initCommand != nil {
return return true
} }
// 检查本机是否存在Os的信息
// 检查是否可以连接互联网
if config.CanConnectInternet() <= 1 {
log.Error("服务器无法连接互联网,无法初始化包管理器")
return false
}
// 检查本机是否存在OS的信息
os := config.ConfigCache.Agent.OS os := config.ConfigCache.Agent.OS
if os.Hostname == "" { if os.Hostname == "" {
os.Gather() os.Gather()
@@ -108,4 +134,64 @@ func generatePackageOperator() {
} else { } else {
AgentPackOperator = yumPackageOperator AgentPackOperator = yumPackageOperator
} }
return true
}
// GetLatestGithubReleaseVersion 获取GitHub仓库的最新版本
func GetLatestGithubReleaseVersion(repoOwner, repoName string) (string, error) {
// 检查是否可以连接互联网
if config.CanConnectInternet() <= 1 {
return "", fmt.Errorf("服务器无法连接互联网无法获取GitHub最新版本")
}
// 设置超时时间为10秒的HTTP客户端
client := &http.Client{
Timeout: 10 * time.Second,
}
// 构建GitHub API URL
apiURL := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", repoOwner, repoName)
// 发送GET请求
resp, err := client.Get(apiURL)
if err != nil {
return "", fmt.Errorf("请求GitHub API失败: %v", err)
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("GitHub API返回非200状态码: %d", resp.StatusCode)
}
// 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取响应内容失败: %v", err)
}
// 解析JSON响应
var release struct {
TagName string `json:"tag_name"`
}
if err := json.Unmarshal(body, &release); err != nil {
return "", fmt.Errorf("解析JSON响应失败: %v", err)
}
return release.TagName, nil
}
// CommandExists 判定命令是否存在
func CommandExists(command string) bool {
ok, _ := SingleLineCommandExecutor([]string{"command", "-v", command})
return ok
}
func CommandExistsByPath(command string) bool {
// 查询 /usr/bin /usr/local/bin中是否有可执行文件
ok, _ := SingleLineCommandExecutor([]string{"find", "/usr/bin", "/usr/local/bin", "-name", command})
return ok
} }

View File

@@ -0,0 +1,21 @@
package op
import (
"testing"
)
func TestGetLatestGithubReleaseVersion(t *testing.T) {
repoOwner := "docker"
repoName := "compose"
version, err := GetLatestGithubReleaseVersion(repoOwner, repoName)
if err != nil {
t.Fatalf("获取最新版本失败: %v", err)
}
if version == "" {
t.Error("获取的版本号为空")
}
t.Logf("获取到的最新版本号: %s", version)
}