mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 21:50:28 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			178 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
 | 
						|
 | 
						|
package dashboardutils
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"encoding/json"
 | 
						|
	teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
 | 
						|
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
						|
	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
						|
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						|
	"github.com/iwind/TeaGo/lists"
 | 
						|
	"github.com/iwind/TeaGo/maps"
 | 
						|
	stringutil "github.com/iwind/TeaGo/utils/string"
 | 
						|
	"github.com/shirou/gopsutil/v3/disk"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"regexp"
 | 
						|
	"runtime"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
// CheckDiskPartitions 检查服务器硬盘空间
 | 
						|
func CheckDiskPartitions(thresholdPercent float64) (path string, usage uint64, usagePercent float64, shouldWarning bool) {
 | 
						|
	partitions, err := disk.Partitions(false)
 | 
						|
	if err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if !lists.ContainsString([]string{"darwin", "linux", "freebsd"}, runtime.GOOS) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	var rootFS = ""
 | 
						|
 | 
						|
	for _, p := range partitions {
 | 
						|
		if p.Mountpoint == "/" {
 | 
						|
			rootFS = p.Fstype
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	for _, p := range partitions {
 | 
						|
		if p.Mountpoint == "/boot" {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if p.Fstype != rootFS {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// skip some specified partitions on macOS
 | 
						|
		if runtime.GOOS == "darwin" {
 | 
						|
			if strings.Contains(p.Mountpoint, "/Developer/") {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		stat, _ := disk.Usage(p.Mountpoint)
 | 
						|
		if stat != nil {
 | 
						|
			if stat.Used < (5<<30) || stat.Free > (100<<30) {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			if stat.UsedPercent > thresholdPercent {
 | 
						|
				path = stat.Path
 | 
						|
				usage = stat.Used
 | 
						|
				usagePercent = stat.UsedPercent
 | 
						|
				shouldWarning = true
 | 
						|
				break
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// CheckLocalAPINode 检查本地的API节点
 | 
						|
func CheckLocalAPINode(rpcClient *rpc.RPCClient, ctx context.Context) (exePath string, runtimeVersion string, fileVersion string, ok bool) {
 | 
						|
	resp, err := rpcClient.APINodeRPC().FindCurrentAPINode(ctx, &pb.FindCurrentAPINodeRequest{})
 | 
						|
	if err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if resp.ApiNode == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	var instanceCode = resp.ApiNode.InstanceCode
 | 
						|
	if len(instanceCode) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	var statusJSON = resp.ApiNode.StatusJSON
 | 
						|
	if len(statusJSON) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	var status = &nodeconfigs.NodeStatus{}
 | 
						|
	err = json.Unmarshal(statusJSON, status)
 | 
						|
	if err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	runtimeVersion = status.BuildVersion
 | 
						|
 | 
						|
	if len(runtimeVersion) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	if stringutil.VersionCompare(runtimeVersion, teaconst.APINodeVersion) >= 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	exePath = status.ExePath
 | 
						|
	if len(exePath) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	stat, err := os.Stat(exePath)
 | 
						|
	if err != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if stat.IsDir() {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// 实例信息
 | 
						|
	{
 | 
						|
		var outputBuffer = &bytes.Buffer{}
 | 
						|
		var cmd = exec.Command(exePath, "instance")
 | 
						|
		cmd.Stdout = outputBuffer
 | 
						|
		err = cmd.Run()
 | 
						|
		if err != nil {
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		var outputBytes = outputBuffer.Bytes()
 | 
						|
		if len(outputBytes) == 0 {
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		var instanceMap = maps.Map{}
 | 
						|
		err = json.Unmarshal(bytes.TrimSpace(outputBytes), &instanceMap)
 | 
						|
		if err != nil {
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		if instanceMap.GetString("code") != instanceCode {
 | 
						|
			return
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// 文件版本
 | 
						|
	{
 | 
						|
		var outputBuffer = &bytes.Buffer{}
 | 
						|
		var cmd = exec.Command(exePath, "-v")
 | 
						|
		cmd.Stdout = outputBuffer
 | 
						|
		err = cmd.Run()
 | 
						|
		if err != nil {
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		var outputString = outputBuffer.String()
 | 
						|
		if len(outputString) == 0 {
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		var subMatch = regexp.MustCompile(`\s+v([\d.]+)\s+`).FindStringSubmatch(outputString)
 | 
						|
		if len(subMatch) == 0 {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		fileVersion = subMatch[1]
 | 
						|
 | 
						|
		// 文件版本是否为最新
 | 
						|
		if fileVersion != teaconst.APINodeVersion {
 | 
						|
			fileVersion = runtimeVersion
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	ok = true
 | 
						|
	return
 | 
						|
}
 |