大量的更新
This commit is contained in:
@@ -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/
|
||||||
|
|||||||
@@ -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,
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"`
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
43
agent-wdd/op/DownloadExecutor.go
Normal file
43
agent-wdd/op/DownloadExecutor.go
Normal 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)
|
||||||
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
21
agent-wdd/op/PackageOperator_test.go
Normal file
21
agent-wdd/op/PackageOperator_test.go
Normal 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user