[agent-wdd] 基本完成Info部分的整理
This commit is contained in:
@@ -74,6 +74,27 @@ func TestCmiiEnvDeploy_JiangSuNanTongErJiPingTai(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCmiiEnvDeploy_ShenZhenGuiZiXiangMu(t *testing.T) {
|
||||||
|
|
||||||
|
// 深证规自项目 2025-02
|
||||||
|
commonEnv := &z_dep.CommonEnvironmentConfig{
|
||||||
|
WebIP: "172.31.2.7",
|
||||||
|
WebPort: "8088",
|
||||||
|
HarborIPOrCustomImagePrefix: "172.31.2.7",
|
||||||
|
HarborPort: "8033/cmii",
|
||||||
|
Namespace: "szgz",
|
||||||
|
TagVersion: "6.2.0",
|
||||||
|
TenantEnv: "",
|
||||||
|
MinioPublicIP: "172.31.2.9",
|
||||||
|
MinioInnerIP: "172.31.2.9",
|
||||||
|
NFSServerIP: "172.31.2.9",
|
||||||
|
ApplyFilePrefix: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
CmiiEnvDeployOffline(commonEnv, true, real_project.Cmii611ImageList)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestCmiiEnvDeploy_LiuXiTongGan(t *testing.T) {
|
func TestCmiiEnvDeploy_LiuXiTongGan(t *testing.T) {
|
||||||
|
|
||||||
// 刘喜通感
|
// 刘喜通感
|
||||||
@@ -405,27 +426,6 @@ func TestCmiiEnvDeploy_YunNanErJiXin(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCmiiEnvDeploy_ShenZhenGuiZiXiangMu(t *testing.T) {
|
|
||||||
|
|
||||||
// 深圳规自项目
|
|
||||||
commonEnv := &z_dep.CommonEnvironmentConfig{
|
|
||||||
WebIP: "39.129.174.66",
|
|
||||||
WebPort: "8088",
|
|
||||||
HarborIPOrCustomImagePrefix: "192.168.186.11",
|
|
||||||
HarborPort: "8033",
|
|
||||||
Namespace: "ynydapp",
|
|
||||||
TagVersion: "6.1.0",
|
|
||||||
TenantEnv: "",
|
|
||||||
MinioPublicIP: "",
|
|
||||||
MinioInnerIP: "192.168.186.15",
|
|
||||||
NFSServerIP: "192.168.186.15",
|
|
||||||
ApplyFilePrefix: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
CmiiEnvDeployOffline(commonEnv, true, real_project.Cmii611ImageList)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCmiiNewAppDeploy(t *testing.T) {
|
func TestCmiiNewAppDeploy(t *testing.T) {
|
||||||
|
|
||||||
deployNamespace := config.DevOperation
|
deployNamespace := config.DevOperation
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ func A_DownloadCompressUpload(syncEntity *ImageSyncEntity, syncResult *ImageSync
|
|||||||
// Compress
|
// Compress
|
||||||
if syncEntity.CompressCondition.ShouldCompressImageToGzip {
|
if syncEntity.CompressCondition.ShouldCompressImageToGzip {
|
||||||
|
|
||||||
// remove file
|
// 移除Gzip的txt
|
||||||
_ = os.Remove(localGzipFileListTxt)
|
_ = os.Remove(localGzipFileListTxt)
|
||||||
|
|
||||||
// 找到已经存在的压缩文件,跳过
|
// 找到已经存在的压缩文件,跳过
|
||||||
|
|||||||
@@ -51,12 +51,16 @@ func TestPullFromEntityAndSyncConditionally(t *testing.T) {
|
|||||||
sync := ImageSyncEntity{
|
sync := ImageSyncEntity{
|
||||||
DownloadCondition: &DownloadEntity{
|
DownloadCondition: &DownloadEntity{
|
||||||
ShouldDownloadImage: true,
|
ShouldDownloadImage: true,
|
||||||
ProjectName: "cmii_6.2.0",
|
ProjectName: "szgz_6.2.0",
|
||||||
ProjectVersion: "6.2.0-demo",
|
ProjectVersion: "6.2.0-szgz-arm",
|
||||||
CmiiNameTagList: []string{
|
CmiiNameTagList: []string{
|
||||||
//"cmii-uav-mqtthandler:5.4.0-bjdyt-052102",
|
//"cmii-uav-mqtthandler:5.4.0-bjdyt-052102",
|
||||||
},
|
},
|
||||||
FullNameImageList: nil,
|
FullNameImageList: []string{
|
||||||
|
"harbor.cdcyy.com.cn/cmii/cmii-uav-mission:6.2.0-szgz-arm",
|
||||||
|
"harbor.cdcyy.com.cn/cmii/cmii-uav-advanced5g:6.2.0-szgz-arm",
|
||||||
|
"harbor.cdcyy.com.cn/cmii/cmii-uav-sense-adapter:6.2.0-szgz-arm",
|
||||||
|
},
|
||||||
DownloadAuthUserName: "",
|
DownloadAuthUserName: "",
|
||||||
DownloadAuthPassword: "",
|
DownloadAuthPassword: "",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,6 +6,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func addInfoSubcommands(cmd *cobra.Command) {
|
func addInfoSubcommands(cmd *cobra.Command) {
|
||||||
|
|
||||||
|
// 操作系统
|
||||||
|
os := &cobra.Command{
|
||||||
|
Use: "os",
|
||||||
|
Short: "主机操作系统相关的信息",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
os := config.ConfigCache.Agent.OS
|
||||||
|
os.Gather()
|
||||||
|
|
||||||
|
os.SaveConfig()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// network
|
// network
|
||||||
network := &cobra.Command{
|
network := &cobra.Command{
|
||||||
Use: "network",
|
Use: "network",
|
||||||
@@ -16,5 +29,64 @@ func addInfoSubcommands(cmd *cobra.Command) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(network)
|
// cpu
|
||||||
|
cpu := &cobra.Command{
|
||||||
|
Use: "cpu",
|
||||||
|
Short: "主机cpu相关的信息",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cpu := config.ConfigCache.Agent.CPU
|
||||||
|
cpu.Gather()
|
||||||
|
cpu.Save()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory
|
||||||
|
memory := &cobra.Command{
|
||||||
|
Use: "mem",
|
||||||
|
Short: "主机memory相关的信息",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
mem := config.ConfigCache.Agent.Mem
|
||||||
|
mem.Gather()
|
||||||
|
swap := config.ConfigCache.Agent.Swap
|
||||||
|
swap.Gather()
|
||||||
|
|
||||||
|
mem.SaveConfig()
|
||||||
|
swap.SaveConfig()
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// disk
|
||||||
|
disk := &cobra.Command{
|
||||||
|
Use: "disk",
|
||||||
|
Short: "主机disk相关的信息",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
//disks := config.ConfigCache.Agent.Disks
|
||||||
|
config.DiskListGather()
|
||||||
|
|
||||||
|
config.DiskListSaveConfig()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// all全部的info
|
||||||
|
all := &cobra.Command{
|
||||||
|
Use: "all",
|
||||||
|
Short: "主机全部相关的信息",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cpu.Run(cmd, args)
|
||||||
|
os.Run(cmd, args)
|
||||||
|
memory.Run(cmd, args)
|
||||||
|
network.Run(cmd, args)
|
||||||
|
disk.Run(cmd, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
all,
|
||||||
|
os,
|
||||||
|
cpu,
|
||||||
|
memory,
|
||||||
|
network,
|
||||||
|
disk,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
177
agent-wdd/config/CPU.go
Normal file
177
agent-wdd/config/CPU.go
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
@@ -18,17 +18,28 @@ func init() {
|
|||||||
|
|
||||||
// 配置结构体定义
|
// 配置结构体定义
|
||||||
type Config struct {
|
type Config struct {
|
||||||
TimeStamp string `yaml:"timestamp"`
|
TimeStamp string `yaml:"timestamp"`
|
||||||
Agent Agent `yaml:"agent"`
|
ModifiedTimes int `yaml:"modifiedTimes"`
|
||||||
|
Agent Agent `yaml:"agent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Agent struct {
|
type Agent struct {
|
||||||
Hostname string `yaml:"hostname"`
|
OS OS `yaml:"os"`
|
||||||
Network Network `yaml:"network"`
|
Network Network `yaml:"network"`
|
||||||
CPU CPU `yaml:"cpu"`
|
CPU CPU `yaml:"cpu"`
|
||||||
Mem Memory `yaml:"mem"`
|
Mem Memory `yaml:"mem"`
|
||||||
Swap Swap `yaml:"swap"`
|
Swap Swap `yaml:"swap"`
|
||||||
Disk []Disk `yaml:"disk"`
|
Disks []Disk `yaml:"disks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OS struct {
|
||||||
|
Hostname string `yaml:"hostname"`
|
||||||
|
OsName string `yaml:"os_name"`
|
||||||
|
OsFamily string `yaml:"os_family"`
|
||||||
|
OsVersion string `yaml:"os_version"`
|
||||||
|
OsType string `yaml:"os_type"`
|
||||||
|
Kernel string `yaml:"kernel"`
|
||||||
|
Arch string `yaml:"arch"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Network struct {
|
type Network struct {
|
||||||
@@ -53,9 +64,12 @@ type Interface struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CPU struct {
|
type CPU struct {
|
||||||
Cores int `yaml:"cores"`
|
Cores int `yaml:"cores"`
|
||||||
Brand string `yaml:"brand"`
|
Brand string `yaml:"brand"`
|
||||||
Mhz int `yaml:"mhz"`
|
Mhz string `yaml:"mhz"`
|
||||||
|
Arch string `yaml:"arch"`
|
||||||
|
Virt string `yaml:"virt"`
|
||||||
|
Hypervisor string `yaml:"hypervisor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Memory struct {
|
type Memory struct {
|
||||||
@@ -65,7 +79,7 @@ type Memory struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Swap struct {
|
type Swap struct {
|
||||||
On bool `yaml:"on"`
|
Open bool `yaml:"open"`
|
||||||
Size string `yaml:"size"`
|
Size string `yaml:"size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,8 +88,6 @@ type Disk struct {
|
|||||||
Size string `yaml:"size"`
|
Size string `yaml:"size"`
|
||||||
Usage string `yaml:"usage"`
|
Usage string `yaml:"usage"`
|
||||||
Percent string `yaml:"percent"`
|
Percent string `yaml:"percent"`
|
||||||
VG string `yaml:"vg"`
|
|
||||||
LV string `yaml:"lv"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitConfig() {
|
func InitConfig() {
|
||||||
@@ -109,6 +121,9 @@ func SaveConfig() {
|
|||||||
// 每次写入新的时间
|
// 每次写入新的时间
|
||||||
ConfigCache.TimeStamp = utils.CurrentTimeString()
|
ConfigCache.TimeStamp = utils.CurrentTimeString()
|
||||||
|
|
||||||
|
// 每次增加修改文件的次数计数
|
||||||
|
ConfigCache.ModifiedTimes += 1
|
||||||
|
|
||||||
data, err := yaml.Marshal(&ConfigCache)
|
data, err := yaml.Marshal(&ConfigCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("YAML序列化失败: %w", err)
|
log.Error("YAML序列化失败: %w", err)
|
||||||
|
|||||||
133
agent-wdd/config/Disk.go
Normal file
133
agent-wdd/config/Disk.go
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"agent-wdd/log"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 of %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 = formatDiskSize(totalBytes)
|
||||||
|
disk.Usage = formatDiskSize(usedBytes)
|
||||||
|
|
||||||
|
if totalBytes == 0 {
|
||||||
|
disk.Percent = "0.00%"
|
||||||
|
} else {
|
||||||
|
percent := float64(usedBytes) / float64(totalBytes) * 100
|
||||||
|
disk.Percent = fmt.Sprintf("%.2f%%", percent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatDiskSize(bytes uint64) string {
|
||||||
|
units := []string{"B", "KB", "MB", "GB", "TB", "PB"}
|
||||||
|
var unitIndex int
|
||||||
|
size := float64(bytes)
|
||||||
|
|
||||||
|
for size >= 1000 && unitIndex < len(units)-1 {
|
||||||
|
size /= 1000
|
||||||
|
unitIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
if unitIndex == 0 {
|
||||||
|
return strconv.FormatUint(bytes, 10) + units[unitIndex]
|
||||||
|
}
|
||||||
|
return strconv.FormatFloat(size, 'f', 1, 64) + units[unitIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
func DiskListSaveConfig() {
|
||||||
|
log.Info("Saving INFO => DISK !")
|
||||||
|
|
||||||
|
SaveConfig()
|
||||||
|
}
|
||||||
155
agent-wdd/config/Memory.go
Normal file
155
agent-wdd/config/Memory.go
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"agent-wdd/log"
|
||||||
|
"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 = formatSize(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 = formatSize(totalKB * 1024)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatSize(bytes uint64) string {
|
||||||
|
units := []string{"B", "KB", "MB", "GB", "TB", "PB"}
|
||||||
|
var unitIndex int
|
||||||
|
size := float64(bytes)
|
||||||
|
|
||||||
|
for size >= 1024 && unitIndex < len(units)-1 {
|
||||||
|
size /= 1024
|
||||||
|
unitIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
if unitIndex == 0 {
|
||||||
|
return strconv.FormatUint(bytes, 10) + units[unitIndex]
|
||||||
|
}
|
||||||
|
return strconv.FormatFloat(size, 'f', 1, 64) + units[unitIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (swap *Swap) SaveConfig() {
|
||||||
|
log.Info("Saving INFO => SWAP !")
|
||||||
|
|
||||||
|
ConfigCache.Agent.Swap = *swap
|
||||||
|
SaveConfig()
|
||||||
|
}
|
||||||
@@ -25,6 +25,8 @@ type IPInfo struct {
|
|||||||
|
|
||||||
// Gather 获取网络相关的信息
|
// Gather 获取网络相关的信息
|
||||||
func (network *Network) Gather() {
|
func (network *Network) Gather() {
|
||||||
|
|
||||||
|
log.Info("Gathering INFO => NETWORK !")
|
||||||
// 能够联网
|
// 能够联网
|
||||||
network.Internet = CanConnectInternet()
|
network.Internet = CanConnectInternet()
|
||||||
|
|
||||||
|
|||||||
82
agent-wdd/config/OS.go
Normal file
82
agent-wdd/config/OS.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
// 解析系统信息
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取系统版本
|
||||||
|
if version, ok := osInfo["VERSION_ID"]; ok {
|
||||||
|
o.OsVersion = version
|
||||||
|
} else {
|
||||||
|
// 针对RedHat系特殊处理
|
||||||
|
if o.OsFamily == "centos" || o.OsFamily == "rhel" {
|
||||||
|
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
|
||||||
|
}
|
||||||
28
agent-wdd/one-build-and-run.ps1
Normal file
28
agent-wdd/one-build-and-run.ps1
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
Write-Host "1. Building binary exec file..." -ForegroundColor Cyan
|
||||||
|
& "C:\Users\wdd\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 info os"
|
||||||
|
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
|
||||||
|
}
|
||||||
55
agent-wdd/utils/PrintUtils.go
Normal file
55
agent-wdd/utils/PrintUtils.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"agent-wdd/log"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BeautifulPrint(object interface{}) {
|
||||||
|
|
||||||
|
bytes, err := json.MarshalIndent(object, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[BeautifulPrint] - json marshal error ! => %v", object)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(string(bytes))
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func BeautifulPrintToString(object interface{}) string {
|
||||||
|
|
||||||
|
bytes, err := json.MarshalIndent(object, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[BeautifulPrint] - json marshal error ! => %v", object)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BeautifulPrintWithTitle(contend any, title string) {
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("content tile is => %s", title))
|
||||||
|
bytes, _ := json.MarshalIndent(contend, "", " ")
|
||||||
|
fmt.Println(string(bytes))
|
||||||
|
fmt.Println("---------- end -----------")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BeautifulPrintListWithTitle(contend []string, title string) {
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(fmt.Sprintf("content tile is => %s", title))
|
||||||
|
for _, line := range contend {
|
||||||
|
fmt.Println(line)
|
||||||
|
}
|
||||||
|
fmt.Println("---------- end -----------")
|
||||||
|
}
|
||||||
|
|
||||||
|
func SplitLinePrint() {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ type Client struct {
|
|||||||
Server string
|
Server string
|
||||||
UserName string
|
UserName string
|
||||||
Password string
|
Password string
|
||||||
// On cmd UDP, let server control the tcp and udp connection relationship
|
// Open cmd UDP, let server control the tcp and udp connection relationship
|
||||||
TCPConn net.Conn
|
TCPConn net.Conn
|
||||||
UDPConn net.Conn
|
UDPConn net.Conn
|
||||||
RemoteAddress net.Addr
|
RemoteAddress net.Addr
|
||||||
|
|||||||
Reference in New Issue
Block a user