删除多个不再使用的配置文件和脚本,更新工作区配置,优化构建和上传脚本,增强项目结构的清晰度和可维护性。

This commit is contained in:
zeaslity
2025-03-27 23:26:39 +08:00
parent 7dabce3fa5
commit c2ca7eb6d7
25 changed files with 157 additions and 1414 deletions

View File

@@ -8,20 +8,25 @@ set HTTPS_PROXY=http://127.0.0.1:7899
# mc.exe ls oracle-osaka-1/osaka
# 设置 韩国oss
mc.exe alias set oracle-seoul-2 https://cncvl8ro2rbf.compat.objectstorage.ap-seoul-1.oraclecloud.com 9e413c6e66269bc65d7ec951d93ba9c6a9781f6e dkXD7PysjrhsTKfNIbKupUmtxdfOvYCyLXf0MXa4hnU=
mc.exe ls oracle-seoul-2/seoul-2
#mc.exe alias set oracle-seoul-2 https://cncvl8ro2rbf.compat.objectstorage.ap-seoul-1.oraclecloud.com 9e413c6e66269bc65d7ec951d93ba9c6a9781f6e dkXD7PysjrhsTKfNIbKupUmtxdfOvYCyLXf0MXa4hnU=
#mc.exe ls oracle-seoul-2/seoul-2
# 重新build项目
Set-Location "C:\Users\wddsh\Documents\IdeaProjects\WddSuperAgent\agent-wdd\"
& "C:\Users\wddsh\go\bin\gox.exe" -osarch="linux/amd64" -output "../build/agent-wdd_{{.OS}}_{{.Arch}}"
Set-Location "C:\\Users\\wddsh\\Documents\\IdeaProjects\\WddSuperAgent\\agent-wdd\"
& "C:\Users\wddsh\go\bin\gox.exe" -osarch="linux/amd64" -output "./build/agent-wdd_{{.OS}}_{{.Arch}}"
Set-Location "C:\Users\wddsh\Documents\IdeaProjects\WddSuperAgent\agent-wdd\a_run"
Write-Host "build项目成功"
Write-Host ""
# 删除上面存在的旧的内容
mc.exe rm oracle-seoul-2/seoul-2/agent-wdd_linux_amd64
Write-Host "删除旧的内容成功"
Write-Host ""
# 上传文件
mc.exe cp C:\Users\wddsh\Documents\IdeaProjects\WddSuperAgent\agent-wdd\a_run\build\agent-wdd_linux_amd64 oracle-seoul-2/seoul-2/
mc.exe cp C:\Users\wddsh\Documents\IdeaProjects\WddSuperAgent\agent-wdd\build\agent-wdd_linux_amd64 oracle-seoul-2/seoul-2/
Write-Host "上传文件成功"
Write-Host ""

View File

@@ -29,7 +29,7 @@ func addAcmeSubcommands(cmd *cobra.Command) {
log.Info("安装acme")
// 检查是否安装acme
if utils.FileExistAndNotNull("/usr/local/bin/acme.sh") {
if utils.FileExistAndNotNull("/root/.acme.sh/acme.sh") {
log.Info("acme已安装")
return
}
@@ -37,7 +37,7 @@ func addAcmeSubcommands(cmd *cobra.Command) {
// 下载 这个文件到 /usr/local/bin/acme.sh
ok, err := utils.DownloadFile(
acmeShUrl,
"/usr/local/bin/acme.sh",
"/tmp/acme.sh",
)
if !ok {
log.Error("下载acme.sh失败", err)
@@ -45,11 +45,11 @@ func addAcmeSubcommands(cmd *cobra.Command) {
}
// 设置权限
utils.PermissionFileExecute("/usr/local/bin/acme.sh")
utils.PermissionFileExecute("/tmp/acme.sh")
// 执行安装命令
op.RealTimeCommandExecutor([]string{
"/usr/local/bin/acme.sh",
"/tmp/acme.sh",
"--install-online",
"ice@gmail.com",
})

View File

@@ -1,30 +1,30 @@
package cmd
import (
"agent-wdd/config"
"agent-wdd/log"
"agent-wdd/utils"
"github.com/spf13/cobra"
"agent-wdd/host_info"
"agent-wdd/log"
"agent-wdd/utils"
"github.com/spf13/cobra"
)
func addConfigSubcommands(cmd *cobra.Command) {
showConfigCmd := &cobra.Command{
Use: "show",
Short: "显示agent运行配置",
Run: func(cmd *cobra.Command, args []string) {
log.Info("显示agent运行配置")
content := utils.ReadAllContentFromFile(config.WddConfigFilePath)
utils.BeautifulPrintListWithTitle(content, "agent运行配置")
log.Info("显示agent运行配置完成")
},
}
cmd.AddCommand(showConfigCmd)
showConfigCmd := &cobra.Command{
Use: "show",
Short: "显示agent运行配置",
Run: func(cmd *cobra.Command, args []string) {
log.Info("显示agent运行配置")
content := utils.ReadAllContentFromFile(host_info.WddConfigFilePath)
utils.BeautifulPrintListWithTitle(content, "agent运行配置")
log.Info("显示agent运行配置完成")
},
}
cmd.AddCommand(showConfigCmd)
}

View File

@@ -285,10 +285,10 @@ func installXray() {
}
// 添加执行权限
os.Chmod("/tmp/install-release.sh", 0777)
utils.PermissionFileExecute("/tmp/install-release.sh")
// 执行安装脚本
ok, resultLog := op.SingleLineCommandExecutor([]string{"/bin/bash", "/tmp/install-release.sh", "-u", "root", "install"})
ok, resultLog := op.RealTimeCommandExecutor([]string{"/bin/bash", "/tmp/install-release.sh", "-u", "root", "install"})
if !ok {
log.Error("Install Xray failed ! error is %s", resultLog)
return

View File

@@ -1,177 +0,0 @@
package config
import (
"agent-wdd/log"
"bufio"
"bytes"
"io/ioutil"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
)
// Gather 获取CPU相关的信息
func (cpu *CPU) Gather() {
log.Info("Gathering INFO => CPU !")
cpu.getBasicInfo()
cpu.getVirtualizationInfo()
}
func (cpu *CPU) Save() {
log.Info("Saving INFO => CPU !")
ConfigCache.Agent.CPU = *cpu
SaveConfig()
}
func (cpu *CPU) getBasicInfo() {
switch runtime.GOOS {
case "linux":
cpu.getLinuxCPUInfo()
case "windows":
cpu.getWindowsCPUInfo()
case "darwin":
cpu.getDarwinCPUInfo()
default:
// 其他平台处理
}
}
func (cpu *CPU) getLinuxCPUInfo() {
data, err := os.ReadFile("/proc/cpuinfo")
if err != nil {
return
}
contents := string(data)
cpu.Cores = strings.Count(contents, "processor\t:")
// 创建带缓冲的扫描器
scanner := bufio.NewScanner(bytes.NewReader(data))
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, "model name") {
cpu.Brand = strings.TrimSpace(strings.SplitN(line, ":", 2)[1])
}
if strings.Contains(line, "cpu MHz") {
cpu.Mhz = strings.TrimSpace(strings.Split(line, ":")[1])
}
}
cpu.Arch = runtime.GOARCH
}
func (cpu *CPU) getWindowsCPUInfo() {
cmd := exec.Command("wmic", "cpu", "get", "Name,NumberOfCores,CurrentClockSpeed", "/VALUE")
output, err := cmd.Output()
if err != nil {
return
}
info := string(output)
lines := strings.Split(info, "\n")
for _, line := range lines {
if strings.HasPrefix(line, "Name=") {
cpu.Brand = strings.TrimSpace(strings.SplitN(line, "=", 2)[1])
}
if strings.HasPrefix(line, "NumberOfCores=") {
cores, _ := strconv.Atoi(strings.SplitN(line, "=", 2)[1])
cpu.Cores = cores
}
if strings.HasPrefix(line, "CurrentClockSpeed=") {
cpu.Mhz = strings.SplitN(line, "=", 2)[1]
}
}
// 架构处理
switch runtime.GOARCH {
case "amd64":
cpu.Arch = "x86_64"
default:
cpu.Arch = runtime.GOARCH
}
}
func (cpu *CPU) getVirtualizationInfo() {
switch runtime.GOOS {
case "linux":
cpu.getLinuxVirtualization()
case "windows":
cpu.getWindowsVirtualization()
}
}
func (cpu *CPU) getLinuxVirtualization() {
// 检查CPU虚拟化支持
data, err := ioutil.ReadFile("/proc/cpuinfo")
if err == nil {
if strings.Contains(string(data), "vmx") || strings.Contains(string(data), "svm") {
cpu.Virt = "supported"
}
}
// 检测是否在虚拟机中
if _, err := os.Stat("/sys/hypervisor/uid"); !os.IsNotExist(err) {
cpu.Virt = "virtualized"
if data, err := ioutil.ReadFile("/sys/hypervisor/type"); err == nil {
cpu.Hypervisor = strings.TrimSpace(string(data))
}
return
}
// 使用systemd-detect-virt
cmd := exec.Command("systemd-detect-virt")
if output, err := cmd.Output(); err == nil {
result := strings.TrimSpace(string(output))
if result != "none" {
cpu.Virt = "virtualized"
cpu.Hypervisor = result
}
}
}
func (cpu *CPU) getWindowsVirtualization() {
cmd := exec.Command("wmic", "computersystem", "get", "model", "/VALUE")
output, err := cmd.Output()
if err != nil {
return
}
model := strings.ToLower(string(output))
switch {
case strings.Contains(model, "virtualbox"):
cpu.Hypervisor = "VirtualBox"
case strings.Contains(model, "vmware"):
cpu.Hypervisor = "VMware"
case strings.Contains(model, "kvm"):
cpu.Hypervisor = "KVM"
case strings.Contains(model, "hyper-v"):
cpu.Hypervisor = "Hyper-V"
case strings.Contains(model, "xen"):
cpu.Hypervisor = "Xen"
}
if cpu.Hypervisor != "" {
cpu.Virt = "virtualized"
}
}
func (cpu *CPU) getDarwinCPUInfo() {
// macOS实现
cmd := exec.Command("sysctl", "-n", "machdep.cpu.brand_string")
if output, err := cmd.Output(); err == nil {
cpu.Brand = strings.TrimSpace(string(output))
}
cmd = exec.Command("sysctl", "-n", "hw.ncpu")
if output, err := cmd.Output(); err == nil {
if cores, err := strconv.Atoi(strings.TrimSpace(string(output))); err == nil {
cpu.Cores = cores
}
}
cpu.Arch = runtime.GOARCH
}

View File

@@ -1,206 +0,0 @@
package config
import (
"agent-wdd/log"
"agent-wdd/utils"
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
)
var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml"
// ConfigCache 配置缓存
var ConfigCache = &Config{
TimeStamp: "",
ModifiedTimes: 0,
Agent: Agent{
OS: OS{},
Network: Network{},
CPU: CPU{},
Mem: Memory{},
Swap: Swap{},
Disks: []Disk{},
},
}
func init() {
// 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置
if runtime.GOOS == "windows" {
homedir, _ := os.UserHomeDir()
WddConfigFilePath = homedir + "\\agent-wdd\\agent-wdd-config.yaml"
}
}
type Config struct {
TimeStamp string `yaml:"timestamp"`
ModifiedTimes int `yaml:"modifiedTimes"`
Agent Agent `yaml:"agent"`
}
type Agent struct {
OS OS `yaml:"os"`
Network Network `yaml:"network"`
CPU CPU `yaml:"cpu"`
Mem Memory `yaml:"mem"`
Swap Swap `yaml:"swap"`
Disks []Disk `yaml:"disks"`
}
type OS struct {
Hostname string `mapstructure:"hostname" yaml:"hostname" comment:"主机名"`
OsName string `mapstructure:"os_name" yaml:"os_name" comment:"操作系统名称"`
OsFamily string `mapstructure:"os_family" yaml:"os_family" comment:"操作系统家族"`
OsVersion string `mapstructure:"os_version" yaml:"os_version" comment:"操作系统版本"`
OsType string `mapstructure:"os_type" yaml:"os_type" comment:"操作系统类型"`
Kernel string `mapstructure:"kernel" yaml:"kernel" comment:"内核版本"`
Arch string `mapstructure:"arch" yaml:"arch" comment:"架构"`
IsUbuntuType bool `mapstructure:"is_ubuntu_type" yaml:"is_ubuntu_type" comment:"是否是ubuntu类型的操作系统"`
PackInit bool `mapstructure:"pack_init" yaml:"pack_init" comment:"是否初始化ubuntu需要"`
OSReleaseCode string `mapstructure:"os_release_code" yaml:"os_release_code" comment:"主机操作系统的发行版代号, focal之类的"`
}
type Network struct {
Internet int `yaml:"internet" comment:"是否能够上网 外网为9 国内为7 不能上网为1"`
Public PublicInfo `yaml:"public"`
Interfaces []Interface `yaml:"interfaces"`
}
type PublicInfo struct {
IPv4 string `yaml:"ipv4"`
IPv6 string `yaml:"ipv6"`
Country string `yaml:"country"`
City string `yaml:"city"`
ASN string `yaml:"asn"`
Timezone string `yaml:"timezone"`
}
type Interface struct {
Name string `yaml:"name"`
IPv4 string `yaml:"ipv4"`
IPv6 string `yaml:"ipv6"`
MAC string `yaml:"mac"`
MTU int `yaml:"mtu"`
}
type CPU struct {
Cores int `yaml:"cores"`
Brand string `yaml:"brand"`
Mhz string `yaml:"mhz"`
Arch string `yaml:"arch"`
Virt string `yaml:"virt"`
Hypervisor string `yaml:"hypervisor"`
}
type Memory struct {
Size string `yaml:"size"`
Type string `yaml:"type"`
Speed int `yaml:"speed"`
}
type Swap struct {
Open bool `yaml:"open"`
Size string `yaml:"size"`
}
type Disk struct {
Path string `yaml:"path"`
Size string `yaml:"size"`
Usage string `yaml:"usage"`
Percent string `yaml:"percent"`
}
func InitConfig() {
// 检查配置文件是否存在
if !utils.FileOrFolderExists(WddConfigFilePath) {
utils.AppendContentToFile("", WddConfigFilePath)
}
v := viper.New()
v.SetConfigFile(WddConfigFilePath)
v.SetConfigType("yaml")
if err := v.ReadInConfig(); err != nil {
log.Error("读取配置文件失败: %w", err)
panic(err)
}
if err := v.Unmarshal(&ConfigCache); err != nil {
log.Error("解析配置失败: %w", err)
panic(err)
}
}
// 写入配置文件
func SaveConfig() {
// 每次写入新的时间
ConfigCache.TimeStamp = utils.CurrentTimeString()
// 每次增加修改文件的次数计数
ConfigCache.ModifiedTimes += 1
data, err := yaml.Marshal(&ConfigCache)
if err != nil {
log.Error("YAML序列化失败: %w", err)
}
if err := os.WriteFile(WddConfigFilePath, data, 0644); err != nil {
log.Error("写入文件失败: %w", err)
}
}
// 归一化配置-重命名主机名
func (c *Config) NormalizeConfig() {
// 重命名主机名
log.Info("归一化主机配置")
// 重新读取配置
InitConfig()
// 主机名称应该为 City(格式为首字母大写)-amd64-内网IP的最后一段(格式化为2位)-公网IPv4(如果公网IPv4为空则使用内网IPv4; ip的格式为127-0-0-1)
// 获取城市(格式为首字母大写)
city := strings.Title(ConfigCache.Agent.Network.Public.City)
// 获取公网IPv4 ip的格式为127-0-0-1
ipInfo := ConfigCache.Agent.Network.Public.IPv4
if ipInfo == "" {
ipInfo = ConfigCache.Agent.Network.Interfaces[0].IPv4
} else {
// 可以获取到公网IPv4, 修改IP的格式
innerIpv4 := ConfigCache.Agent.Network.Interfaces[0].IPv4
ipSegments := strings.Split(innerIpv4, ".")
prefix := fmt.Sprintf("%02s", ipSegments[len(ipSegments)-1])
ipInfo = prefix + "." + ipInfo
}
ipInfo = strings.ReplaceAll(ipInfo, ".", "-")
// 获取架构
arch := ConfigCache.Agent.CPU.Arch
uniformHostname := city + "-" + arch + "-" + ipInfo
// 重命名主机名
log.Info("重命名主机名: %s", uniformHostname)
cmd := exec.Command("hostnamectl", "set-hostname", uniformHostname)
// 执行命令
cmd.Run()
// 更新配置
ConfigCache.Agent.OS.Hostname = uniformHostname
// 更新配置
SaveConfig()
}

View File

@@ -1,114 +0,0 @@
package config
import (
"agent-wdd/log"
"bufio"
"os"
"path/filepath"
"strings"
)
var CommonDiskPath = []string{
"/",
"/var",
"/var/lib/docker",
"/home",
"/user",
"var/log",
}
func CheckCommonMounts() (map[string]bool, error) {
// 读取/proc/mounts获取所有挂载点
file, err := os.Open("/proc/mounts")
if err != nil {
return nil, err
}
defer file.Close()
mountPoints := make(map[string]bool)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
fields := strings.Fields(line)
if len(fields) < 2 {
continue
}
mountPoint := filepath.Clean(fields[1])
mountPoints[mountPoint] = true
}
if err := scanner.Err(); err != nil {
return nil, err
}
return mountPoints, err
}
func DiskListGather() {
log.Info("Gathering INFO => DISK !")
var diskList []Disk
// 拿到所有挂载点
mountPoints, _ := CheckCommonMounts()
// 常用目录
for _, diskPath := range CommonDiskPath {
// 转换为绝对路径并标准化
absPath, err := filepath.Abs(diskPath)
if err != nil {
// 处理错误,例如路径无效,这里选择跳过
continue
}
cleanPath := filepath.Clean(absPath)
if mountPoints[cleanPath] {
// 挂载点存在,计算使用情况
disk := Disk{Path: cleanPath}
disk.calculateDiskUsage()
diskList = append(diskList, disk)
}
}
// 赋值回去
ConfigCache.Agent.Disks = diskList
//utils.BeautifulPrint(diskList)
}
// 计算磁盘使用情况
func (disk *Disk) calculateDiskUsage() {
// var stat syscall.Statfs_t
// err := syscall.Statfs(disk.Path, &stat)
// if err != nil {
// log.Error("disk syscall error: %v", err)
// disk.Size = "0B"
// disk.Usage = "0B"
// disk.Percent = "0.00%"
// return
// }
// // 计算存储空间大小
// totalBytes := stat.Blocks * uint64(stat.Bsize)
// availBytes := stat.Bavail * uint64(stat.Bsize)
// usedBytes := totalBytes - availBytes
// // 格式化输出
// disk.Size = utils.HumanDiskSize(totalBytes)
// disk.Usage = utils.HumanDiskSize(usedBytes)
// if totalBytes == 0 {
// disk.Percent = "0.00%"
// } else {
// percent := float64(usedBytes) / float64(totalBytes) * 100
// disk.Percent = fmt.Sprintf("%.2f%%", percent)
// }
}
func DiskListSaveConfig() {
log.Info("Saving INFO => DISK !")
SaveConfig()
}

View File

@@ -1,140 +0,0 @@
package config
import (
"agent-wdd/log"
"agent-wdd/utils"
"os"
"os/exec"
"strconv"
"strings"
)
func (mem *Memory) Gather() {
// 获取内存总大小
data, err := os.ReadFile("/proc/meminfo")
if err != nil {
mem.Size = "0B"
mem.Type = ""
mem.Speed = 0
return
}
lines := strings.Split(string(data), "\n")
//var totalKB uint64
for _, line := range lines {
if strings.HasPrefix(line, "MemTotal:") {
fields := strings.Fields(line)
if len(fields) >= 3 {
kb, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
mem.Size = "0B"
} else {
mem.Size = utils.HumanSize(kb * 1024)
}
break
}
}
}
// 获取Type和Speed
mem.Type, mem.Speed = getMemoryTypeAndSpeed()
}
func getMemoryTypeAndSpeed() (string, int) {
cmd := exec.Command("dmidecode", "-t", "memory")
output, err := cmd.CombinedOutput()
if err != nil {
return "", 0
}
var memType string
var speed int
lines := strings.Split(string(output), "\n")
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "Type:") {
parts := strings.SplitN(trimmed, ":", 2)
if len(parts) == 2 {
memType = strings.TrimSpace(parts[1])
// 可能dmidecode返回的类型中有更多细节例如"DDR4"或其他
// 例如,如果类型是"Unknown",可能需要处理
if memType == "Unknown" || memType == "Other" {
memType = ""
}
}
} else if strings.HasPrefix(trimmed, "Speed:") {
parts := strings.SplitN(trimmed, ":", 2)
if len(parts) == 2 {
speedStr := strings.TrimSpace(parts[1])
// 可能的格式如 "2667 MHz" 或 "Unknown"
if speedStr == "Unknown" {
continue
}
speedStr = strings.TrimSuffix(speedStr, " MHz")
s, err := strconv.Atoi(speedStr)
if err == nil {
speed = s
}
}
}
}
return memType, speed
}
func (mem *Memory) SaveConfig() {
log.Info("Saving INFO => MEM !")
ConfigCache.Agent.Mem = *mem
SaveConfig()
}
func (swap *Swap) Gather() {
log.Info("Gathering INFO => SWAP !")
const swapsFile = "/proc/swaps"
data, err := os.ReadFile(swapsFile)
if err != nil {
swap.Open = false
swap.Size = "0B"
return
}
lines := strings.Split(strings.TrimSpace(string(data)), "\n")
if len(lines) < 2 { // 空文件或只有标题行
swap.Open = false
swap.Size = "0B"
return
}
var totalKB uint64
for _, line := range lines[1:] {
line = strings.TrimSpace(line)
if line == "" {
continue
}
fields := strings.Fields(line)
if len(fields) < 3 {
continue
}
sizeKB, err := strconv.ParseUint(fields[2], 10, 64)
if err != nil {
continue
}
totalKB += sizeKB
}
if totalKB == 0 {
swap.Open = false
swap.Size = "0B"
} else {
swap.Open = true
swap.Size = utils.HumanSize(totalKB * 1024)
}
}
func (swap *Swap) SaveConfig() {
log.Info("Saving INFO => SWAP !")
ConfigCache.Agent.Swap = *swap
SaveConfig()
}

View File

@@ -1,273 +0,0 @@
package config
import (
"agent-wdd/log"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"regexp"
"time"
)
// 能够联网,就大于这个数字 外网9 国内7 不能联网1 未知0
const InternetBaseLine = 1
// 定义响应数据结构体
type IPInfo struct {
IP string `json:"ip"`
City string `json:"city"`
Region string `json:"region"`
Country string `json:"country"`
Loc string `json:"loc"`
Org string `json:"org"`
Postal string `json:"postal"`
Timezone string `json:"timezone"`
}
// Gather 获取网络相关的信息
func (network *Network) Gather() {
log.Info("Gathering INFO => NETWORK !")
// 能够联网
network.Internet = CanConnectInternet()
// 获取公网的相关信息
network.Public = network.Public.GetPublicInfo()
//获取本机网卡相关的内容
network.Interfaces = GetInterfaces()
}
// GetInterfaces 获取本机网卡相关的内容
func GetInterfaces() []Interface {
interfaces := []Interface{}
// 获取所有网卡信息
netInterfaces, err := net.Interfaces()
// log.Info("all network interfaces: %v", netInterfaces)
if err != nil {
log.Error("获取网卡信息失败: %v", err)
return interfaces
}
for _, netInterface := range netInterfaces {
// 过滤掉没有地址的网卡
addrs, err := netInterface.Addrs()
if err != nil || len(addrs) == 0 {
continue
}
// 检查网卡名称是否有效
if !isValidNICName(netInterface.Name) {
continue
}
// 创建 Interface 对象
iface := Interface{
Name: netInterface.Name,
MAC: netInterface.HardwareAddr.String(),
MTU: netInterface.MTU,
}
// 获取 IPv4 和 IPv6 地址
for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet)
if !ok {
continue
}
if ipNet.IP.To4() != nil {
iface.IPv4 = ipNet.IP.String()
} else if ipNet.IP.To16() != nil {
iface.IPv6 = ipNet.IP.String()
}
}
interfaces = append(interfaces, iface)
}
return interfaces
}
func (network *Network) SaveConfig() {
ConfigCache.Agent.Network = *network
SaveConfig()
}
// CanConnectInternet 判定主机能够上网 外网为9 国内为7 不能上网为1
func CanConnectInternet() int {
// 读取 config 文件,判定能否上网
internetCode := ConfigCache.Agent.Network.Internet
if internetCode == 0 {
// 没有相关的信息,需要重新判定
internetCode = judgeCanConnectInternet()
// 持久化保存
ConfigCache.Agent.Network.Internet = internetCode
}
return internetCode
}
// judgeCanConnectInternet 请求网址判定主机能否上网 请求 www.google.com 如果请求正常 返回9 如果超时三秒 请求baidu.com如果没有错误返回7 如果错误返回1
func judgeCanConnectInternet() int {
client := http.Client{
Timeout: 3 * time.Second,
}
results := make(chan int, 2)
go func() {
_, err := client.Get("https://www.google.com")
if err == nil {
results <- 9
} else {
results <- 1
}
}()
go func() {
_, err := client.Get("https://www.baidu.com")
if err == nil {
results <- 7
} else {
results <- 1
}
}()
maxResult := 1
for i := 0; i < 2; i++ {
result := <-results
if result > maxResult {
maxResult = result
}
}
return maxResult
}
// GetPublicInfo 获取服务器的公网信息
func (p PublicInfo) GetPublicInfo() PublicInfo {
// 无法联网, 假信息
fakePublicInfo := PublicInfo{
IPv4: "1.1.1.1",
IPv6: "2400::1",
Country: "CN",
City: "Shanghai",
ASN: "Wdd Inc",
Timezone: "Asia/Shanghai",
}
if CanConnectInternet() == InternetBaseLine {
// 持久化保存
ConfigCache.Agent.Network.Public = fakePublicInfo
return fakePublicInfo
}
// 可以联网
// 创建带有超时的HTTP客户端
client := &http.Client{
Timeout: 3 * time.Second,
}
// 创建新的请求对象
req, err := http.NewRequest("GET", "https://ipinfo.io", nil)
if err != nil {
log.Error("创建请求失败: %v", err)
return fakePublicInfo
}
// 设置请求头
req.Header.Add("Authorization", "Bearer 6ecb0db9bd8f19")
req.Header.Add("Accept", "application/json")
// 发送请求
resp, err := client.Do(req)
if err != nil {
log.Error("请求PublicInfo失败: %s", err.Error())
return fakePublicInfo
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode != http.StatusOK {
log.Error("非200状态码: %d", resp.StatusCode)
}
// 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Error("读取响应失败: %v", err)
}
// 解析JSON数据
var info IPInfo
if err := json.Unmarshal(body, &info); err != nil {
log.Error("JSON解析失败: %v", err)
}
// 打印解析结果
// log.Info("IP信息:\n%+v\n", info)
// 保存信息
p.IPv4 = info.IP
p.ASN = info.Org
p.Country = info.Country
p.City = info.City
p.Timezone = info.Timezone
ConfigCache.Agent.Network.Public = p
return p
}
func isValidNICName(name string) bool {
// 定义传统命名规则正则表达式
// eth0, eth1, wlan0, wlan1 等
traditionalPattern := `^(eth|wlan)[0-9]+$`
// 定义现代命名规则正则表达式
// 支持 eno1, ens3, enp0s3, enx<MAC>, wlp2s0 等格式
modernPattern := `^(en|wl)(o[0-9]+|s[0-9]+|p[0-9]+s[0-9]+|x[0-9a-fA-F]{12})$`
// 编译正则表达式
traditionalRegex := regexp.MustCompile(traditionalPattern)
modernRegex := regexp.MustCompile(modernPattern)
// 检查是否匹配传统命名或现代命名规则
return traditionalRegex.MatchString(name) || modernRegex.MatchString(name)
}
func main() {
// 测试用例
testCases := []string{
"eth0", // 传统以太网命名
"wlan1", // 传统无线网卡命名
"eno1", // 板载网卡
"ens3", // 插槽网卡
"enp0s3", // PCI网卡
"enx0a1b2c3d4e5f", // 基于MAC地址的命名
"wlp2s0", // 无线PCI网卡
"eth", // 无效:缺少数字
"enp0", // 无效:不符合现代规则
"abc123", // 无效:完全不匹配
}
for _, tc := range testCases {
if isValidNICName(tc) {
fmt.Printf("%s: 有效网卡名称\n", tc)
} else {
fmt.Printf("%s: 无效网卡名称\n", tc)
}
}
}

View File

@@ -1,117 +0,0 @@
package config
import (
"agent-wdd/log"
"bufio"
"os"
"os/exec"
"regexp"
"runtime"
"strings"
)
func (os *OS) SaveConfig() {
log.Info("Saving INFO => OS !")
ConfigCache.Agent.OS = *os
SaveConfig()
}
func (o *OS) Gather() {
log.Info("Gathering INFO => OS !")
// 获取主机名
if hostname, err := os.Hostname(); err == nil {
o.Hostname = hostname
}
o.OsType = "linux" // 固定为linux
o.IsUbuntuType = true // 默认为ubuntu
// 解析系统信息
file, err := os.Open("/etc/os-release")
if err == nil {
defer file.Close()
scanner := bufio.NewScanner(file)
osInfo := make(map[string]string)
for scanner.Scan() {
line := scanner.Text()
if parts := strings.SplitN(line, "=", 2); len(parts) == 2 {
key := parts[0]
value := strings.Trim(parts[1], `"`)
osInfo[key] = value
}
}
//utils.BeautifulPrint(osInfo)
// 获取操作系统名称
if name, ok := osInfo["PRETTY_NAME"]; ok {
o.OsName = name
}
// 获取系统家族
if id, ok := osInfo["ID"]; ok {
o.OsFamily = id
}
// 判定系统是否是ubuntu类型
if o.OsFamily == "ubuntu" || o.OsFamily == "debian" || o.OsFamily == "linuxmint" || o.OsFamily == "elementary" || o.OsFamily == "pop" || o.OsFamily == "mint" || o.OsFamily == "kali" || o.OsFamily == "deepin" || o.OsFamily == "zorin" {
o.IsUbuntuType = true
} else {
// 设置系统为非ubuntus
o.IsUbuntuType = false
}
// 获取系统版本
if version, ok := osInfo["VERSION_ID"]; ok {
o.OsVersion = version
} else {
// 针对RedHat系特殊处理
if o.OsFamily == "centos" || o.OsFamily == "rhel" {
// 针对RedHat系特殊处理
if data, err := os.ReadFile("/etc/redhat-release"); err == nil {
re := regexp.MustCompile(`\d+(\.\d+)+`)
if match := re.FindString(string(data)); match != "" {
o.OsVersion = match
}
}
}
}
}
// 获取内核版本
if out, err := exec.Command("uname", "-r").Output(); err == nil {
o.Kernel = strings.TrimSpace(string(out))
}
// 获取系统架构
o.Arch = runtime.GOARCH
// 获取系统发行版代号
if o.IsUbuntuType {
o.OSReleaseCode = judgeUbuntuReleaseFromOsVersion(o.OsVersion)
} else {
o.OSReleaseCode = "non-ubuntu"
}
}
func judgeUbuntuReleaseFromOsVersion(osVersion string) string {
switch osVersion {
case "16.04":
return "xenial"
case "18.04":
return "bionic"
case "20.04":
return "focal"
case "22.04":
return "jammy"
default:
return "ubuntu-unknown"
}
}

View File

@@ -1,29 +0,0 @@
try {
$ErrorActionPreference = "Stop"
Write-Host "1. Building binary exec file..." -ForegroundColor Cyan
& "C:\Users\wddsh\go\bin\gox.exe" -osarch="linux/amd64" -output "build/agent-wdd_{{.OS}}_{{.Arch}}"
# 执行远程ssh命令 ssh root@192.168.35.71 "rm /root/agent-wdd_linux_amd64"
Write-Host "2. Cleaning old binary file..." -ForegroundColor Yellow
ssh root@192.168.35.71 "rm -f /root/agent-wdd_linux_amd64 && rm /usr/local/etc/wdd/agent-wdd-config.yaml"
Write-Host "3. Uploading binary exec..." -ForegroundColor Green
scp build/agent-wdd_linux_amd64 root@192.168.35.71:/root/
Write-Host "4. Exec the command ..." -ForegroundColor Blue
Write-Host ""
Write-Host ""
ssh root@192.168.35.71 "chmod +x agent-wdd_linux_amd64 && ./agent-wdd_linux_amd64 help"
Write-Host ""
Write-Host ""
Write-Host "5. Cheak Info Result ..." -ForegroundColor Blue
ssh root@192.168.35.71 "cat /usr/local/etc/wdd/agent-wdd-config.yaml"
} catch {
Write-Host "操作失败: $_" -ForegroundColor Red
exit 1
}

View File

@@ -1,38 +0,0 @@
set HTTP_PROXY=http://127.0.0.1:7899
set HTTPS_PROXY=http://127.0.0.1:7899
# 设置
# mc.exe alias set oracle-osaka-1 https://axzsapxffbbn.compat.objectstorage.ap-osaka-1.oraclecloud.com b0696c316f87b644b4a13bcb020f095cd147be0b GAIaM/064epLzQcXsRbj2gwlFOrVepjCR23wj2tfJ+A=
# mc.exe ls oracle-osaka-1/osaka
# 设置 韩国oss
# mc.exe alias set oracle-seoul-2 https://cncvl8ro2rbf.compat.objectstorage.ap-seoul-1.oraclecloud.com 9e413c6e66269bc65d7ec951d93ba9c6a9781f6e dkXD7PysjrhsTKfNIbKupUmtxdfOvYCyLXf0MXa4hnU=
# mc.exe ls oracle-seoul-2/seoul-2
# 重新build项目
Set-Location "C:\Users\wddsh\Documents\IdeaProjects\ProjectOctopus\agent-wdd"
& "C:\Users\wddsh\go\bin\gox.exe" -osarch="linux/amd64" -output "build/agent-wdd_{{.OS}}_{{.Arch}}"
Set-Location "C:\Users\wddsh\Documents\IdeaProjects\ProjectOctopus\agent-wdd\test"
# 删除上面存在的旧的内容
mc.exe rm oracle-seoul-2/seoul-2/agent-wdd_linux_amd64
# mc.exe rm oracle-seoul-2/seoul-2/test-shell.sh
# 上传文件
mc.exe cp C:\Users\wddsh\Documents\IdeaProjects\ProjectOctopus\agent-wdd\build\agent-wdd_linux_amd64 oracle-seoul-2/seoul-2/
# mc.exe cp C:\Users\wddsh\Documents\IdeaProjects\ProjectOctopus\agent-wdd\test\test-shell.sh oracle-seoul-2/seoul-2/

View File

@@ -1,43 +0,0 @@
Available commands:
acme acme相关的内容
base 服务器基础操作
docker Docker相关操作
local 本地安装Docker
online 网络安装Docker
remove 卸载Docker
dockercompose Docker Compose相关操作
local 本地安装Docker Compose
online 安装Docker Compose
remove 卸载Docker Compose
version 查看Docker Compose版本
firewall 关闭防火墙
selinux 关闭selinux
ssh 修改ssh配置
config 修改ssh配置 为wdd默认配置!
key 安装默认的ssh-key
port 修改ssh端口
swap 关闭系统的Swap
sysconfig 修改系统的sysconfig
tools 通用工具安装 利用本机的yumapt等从网络安装常用的软件
config 配置文件管理
show 显示agent运行配置
download 文件下载,直接下载 [url] [dest_path]
proxy 使用代理下载 socks5://[username]:[password]@ip:port http://[username]:[password]@ip:port
help 帮助信息
help Help about any command
info 打印主机详细信息
all 主机全部相关的信息
cpu 主机cpu相关的信息
disk 主机disk相关的信息
mem 主机memory相关的信息
network 主机Network相关的信息
os 主机操作系统相关的信息
proxy 主机代理相关的内容
vmess 设置VMESS代理
xray Xray相关操作
install 安装Xray
security 安全相关操作
version 打印版本信息
wdd WDD相关操作
zsh zsh相关的内容

View File

@@ -1,67 +0,0 @@
#!/bin/bash
rm -f /usr/local/bin/agent-wdd
rm -f /usr/local/bin/test-shell.sh
wget https://pan.107421.xyz/d/oracle-seoul-2/agent-wdd_linux_amd64 -qO /usr/local/bin/agent-wdd
chmod +x /usr/local/bin/agent-wdd
/usr/local/bin/agent-wdd info all
cat /usr/local/etc/wdd/agent-wdd-config.yaml
/usr/local/bin/agent-wdd base firewall
/usr/local/bin/agent-wdd base ssh config
/usr/local/bin/agent-wdd base ssh key
/usr/local/bin/agent-wdd proxy xray install
/usr/local/bin/agent-wdd proxy vmess 22443
#bash /usr/local/bin/test-shell.sh
/usr/local/bin/agent-wdd info network
/usr/local/bin/agent-wdd info cpu
/usr/local/bin/agent-wdd info mem
/usr/local/bin/agent-wdd info swap
/usr/local/bin/agent-wdd info disks
/usr/local/bin/agent-wdd base docker local
/usr/local/bin/agent-wdd info os
/usr/local/bin/agent-wdd base docker online
/usr/local/bin/agent-wdd info os
/usr/local/bin/agent-wdd zsh
/usr/local/bin/agent-wdd base tools
/usr/local/bin/agent-wdd base swap
/usr/local/bin/agent-wdd base firewall
/usr/local/bin/agent-wdd base selinux
/usr/local/bin/agent-wdd base sysconfig
/usr/local/bin/agent-wdd download https://pan.107421.xyz/d/oracle-osaka-1/docker-amd64-20.10.15.tgz /root/wdd
/usr/local/bin/agent-wdd proxy xray install
/usr/local/bin/agent-wdd proxy vmess 22443
wget https://pan.107421.xyz/d/oracle-seoul-2/test-shell.sh -qO /usr/local/bin/test-shell.sh
chmod +x /usr/local/bin/test-shell.sh

View File

@@ -1,135 +0,0 @@
#!/bin/bash
# set -eo pipefail
# 测试配置
TEST_REPEATS=2
AGENT_BIN="/usr/local/bin/agent-wdd" # 修正路径拼写错误
# 输出颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'
# 测试统计
declare -i TOTAL_TESTS=0 PASSED_TESTS=0 FAILED_TESTS=0
# 实用函数
log() {
echo -e "${YELLOW}[INFO] $* ${NC}"
}
pass() {
echo -e "${GREEN}PASS: $* ${NC}"
((PASSED_TESTS++))
((TOTAL_TESTS++))
}
fail() {
echo -e "${RED}FAIL: $* ${NC}"
((FAILED_TESTS++))
((TOTAL_TESTS++))
}
test_command() {
local cmd="$1"
local expected="${2:-0}"
if ! eval "$cmd"; then
local exit_code=$?
[[ $exit_code -eq "$expected" ]] || {
fail "$cmd (exit $exit_code)"
return 1
}
fi
pass "$cmd"
return 0
}
repeat_test() {
local times=$1
local cmd="$2"
local expected="${3:-0}"
for ((i=1; i<=times; i++)); do
test_command "$cmd" "$expected"
done
}
test_base_docker() {
log "\nTesting Docker commands..."
test_command "$AGENT_BIN base docker remove" 0
test_command "$AGENT_BIN base docker online" 0
repeat_test $TEST_REPEATS "$AGENT_BIN base docker local" 0
if docker --version >/dev/null 2>&1; then
pass "docker installation"
else
fail "docker installation"
fi
}
test_base_ssh() {
log "\nTesting SSH commands..."
repeat_test $TEST_REPEATS "$AGENT_BIN base ssh port 2222" 0
test_command "$AGENT_BIN base ssh config" 0
}
test_tools() {
log "\nTesting tools installation..."
local tools=("htop" "tmux" "nano")
for tool in "${tools[@]}"; do
if command -v "$tool" >/dev/null 2>&1; then
pass "$tool already installed"
else
test_command "$AGENT_BIN base tools $tool" 0
fi
done
}
test_info_commands() {
log "\nTesting info commands..."
local commands=(
"$AGENT_BIN info all"
"$AGENT_BIN info cpu"
"$AGENT_BIN info disk"
"$AGENT_BIN info mem"
"$AGENT_BIN info network"
"$AGENT_BIN info os"
)
for cmd in "${commands[@]}"; do
repeat_test $TEST_REPEATS "$cmd" 0
done
}
main() {
# 前置检查
[[ -x "$AGENT_BIN" ]] || {
log "Error: Agent binary not found or not executable: $AGENT_BIN"
exit 1
}
log "Starting tests with $AGENT_BIN..."
# 基本信息测试
test_command "$AGENT_BIN version" 0
test_command "$AGENT_BIN help" 0
# 基础模块测试
test_base_docker
test_base_ssh
test_tools
# 信息模块测试
test_info_commands
log "\nTest Summary:"
echo -e "Total Tests: $TOTAL_TESTS"
echo -e "${GREEN}Passed: $PASSED_TESTS ${NC}"
echo -e "${RED}Failed: $FAILED_TESTS ${NC}"
exit "$FAILED_TESTS"
}
main