mirror of
https://github.com/henrygd/beszel.git
synced 2026-03-27 16:06:16 +01:00
update
This commit is contained in:
157
agent/pve.go
157
agent/pve.go
@@ -20,88 +20,6 @@ type pveManager struct {
|
|||||||
nodeStatsMap map[string]*container.PveNodeStats // Keeps track of pve node stats
|
nodeStatsMap map[string]*container.PveNodeStats // Keeps track of pve node stats
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns stats for all running VMs/LXCs
|
|
||||||
func (pm *pveManager) getPVEStats() ([]*container.PveNodeStats, error) {
|
|
||||||
if pm.client == nil {
|
|
||||||
return nil, errors.New("PVE client not configured")
|
|
||||||
}
|
|
||||||
cluster, err := pm.client.Cluster(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Error getting cluster", "err", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resources, err := cluster.Resources(context.Background(), "vm")
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Error getting resources", "err", err, "resources", resources)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
containersLength := len(resources)
|
|
||||||
containerIds := make(map[string]struct{}, containersLength)
|
|
||||||
|
|
||||||
// only include running vms and lxcs on selected node
|
|
||||||
for _, resource := range resources {
|
|
||||||
if resource.Node == pm.nodeName && resource.Status == "running" {
|
|
||||||
containerIds[resource.ID] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// remove invalid container stats
|
|
||||||
for id := range pm.nodeStatsMap {
|
|
||||||
if _, exists := containerIds[id]; !exists {
|
|
||||||
delete(pm.nodeStatsMap, id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate stats
|
|
||||||
stats := make([]*container.PveNodeStats, 0, len(containerIds))
|
|
||||||
for _, resource := range resources {
|
|
||||||
if _, exists := containerIds[resource.ID]; !exists {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
resourceStats, initialized := pm.nodeStatsMap[resource.ID]
|
|
||||||
if !initialized {
|
|
||||||
resourceStats = &container.PveNodeStats{}
|
|
||||||
pm.nodeStatsMap[resource.ID] = resourceStats
|
|
||||||
}
|
|
||||||
// reset current stats
|
|
||||||
resourceStats.Cpu = 0
|
|
||||||
resourceStats.Mem = 0
|
|
||||||
resourceStats.Bandwidth = [2]uint64{0, 0}
|
|
||||||
// Store clean name (no type suffix)
|
|
||||||
resourceStats.Name = resource.Name
|
|
||||||
// Store resource ID (e.g. "qemu/100") in .Id (cbor key 7, json:"-")
|
|
||||||
resourceStats.Id = resource.ID
|
|
||||||
// Store type (e.g. "qemu" or "lxc") in .Image (cbor key 8, json:"-")
|
|
||||||
resourceStats.Type = resource.Type
|
|
||||||
// PVE limits (cbor-only, for pve_vms table)
|
|
||||||
resourceStats.MaxCPU = resource.MaxCPU
|
|
||||||
resourceStats.MaxMem = resource.MaxMem
|
|
||||||
resourceStats.Uptime = resource.Uptime
|
|
||||||
// prevent first run from sending all prev sent/recv bytes
|
|
||||||
total_sent := uint64(resource.NetOut)
|
|
||||||
total_recv := uint64(resource.NetIn)
|
|
||||||
var sent_delta, recv_delta float64
|
|
||||||
if initialized {
|
|
||||||
secondsElapsed := time.Since(resourceStats.PrevReadTime).Seconds()
|
|
||||||
if secondsElapsed > 0 {
|
|
||||||
sent_delta = float64(total_sent-resourceStats.PrevNet.Sent) / secondsElapsed
|
|
||||||
recv_delta = float64(total_recv-resourceStats.PrevNet.Recv) / secondsElapsed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resourceStats.PrevNet.Sent = total_sent
|
|
||||||
resourceStats.PrevNet.Recv = total_recv
|
|
||||||
resourceStats.PrevReadTime = time.Now()
|
|
||||||
|
|
||||||
// Update final stats values
|
|
||||||
resourceStats.Cpu = twoDecimals(100.0 * resource.CPU * float64(resource.MaxCPU) / float64(pm.cpuCount))
|
|
||||||
resourceStats.Mem = bytesToMegabytes(float64(resource.Mem))
|
|
||||||
resourceStats.Bandwidth = [2]uint64{uint64(sent_delta), uint64(recv_delta)}
|
|
||||||
|
|
||||||
stats = append(stats, resourceStats)
|
|
||||||
}
|
|
||||||
|
|
||||||
return stats, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a new PVE manager - may return nil if required environment variables are not set or if there is an error connecting to the API
|
// Creates a new PVE manager - may return nil if required environment variables are not set or if there is an error connecting to the API
|
||||||
func newPVEManager() *pveManager {
|
func newPVEManager() *pveManager {
|
||||||
url, exists := GetEnv("PROXMOX_URL")
|
url, exists := GetEnv("PROXMOX_URL")
|
||||||
@@ -156,3 +74,78 @@ func newPVEManager() *pveManager {
|
|||||||
|
|
||||||
return &pveManager
|
return &pveManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns stats for all running VMs/LXCs
|
||||||
|
func (pm *pveManager) getPVEStats() ([]*container.PveNodeStats, error) {
|
||||||
|
if pm.client == nil {
|
||||||
|
return nil, errors.New("PVE client not configured")
|
||||||
|
}
|
||||||
|
cluster, err := pm.client.Cluster(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Error getting cluster", "err", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resources, err := cluster.Resources(context.Background(), "vm")
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Error getting resources", "err", err, "resources", resources)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
containersLength := len(resources)
|
||||||
|
resourceIds := make(map[string]struct{}, containersLength)
|
||||||
|
|
||||||
|
// only include running vms and lxcs on selected node
|
||||||
|
for _, resource := range resources {
|
||||||
|
if resource.Node == pm.nodeName && resource.Status == "running" {
|
||||||
|
resourceIds[resource.ID] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove invalid container stats
|
||||||
|
for id := range pm.nodeStatsMap {
|
||||||
|
if _, exists := resourceIds[id]; !exists {
|
||||||
|
delete(pm.nodeStatsMap, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate stats
|
||||||
|
stats := make([]*container.PveNodeStats, 0, len(resourceIds))
|
||||||
|
for _, resource := range resources {
|
||||||
|
if _, exists := resourceIds[resource.ID]; !exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resourceStats, initialized := pm.nodeStatsMap[resource.ID]
|
||||||
|
if !initialized {
|
||||||
|
resourceStats = &container.PveNodeStats{}
|
||||||
|
pm.nodeStatsMap[resource.ID] = resourceStats
|
||||||
|
}
|
||||||
|
resourceStats.Name = resource.Name
|
||||||
|
resourceStats.Id = resource.ID
|
||||||
|
resourceStats.Type = resource.Type
|
||||||
|
resourceStats.MaxCPU = resource.MaxCPU
|
||||||
|
resourceStats.MaxMem = resource.MaxMem
|
||||||
|
resourceStats.Uptime = resource.Uptime
|
||||||
|
|
||||||
|
// prevent first run from sending all prev sent/recv bytes
|
||||||
|
total_sent := resource.NetOut
|
||||||
|
total_recv := resource.NetIn
|
||||||
|
var sent_delta, recv_delta float64
|
||||||
|
if initialized {
|
||||||
|
secondsElapsed := time.Since(resourceStats.PrevReadTime).Seconds()
|
||||||
|
if secondsElapsed > 0 {
|
||||||
|
sent_delta = float64(total_sent-resourceStats.PrevNet.Sent) / secondsElapsed
|
||||||
|
recv_delta = float64(total_recv-resourceStats.PrevNet.Recv) / secondsElapsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resourceStats.PrevNet.Sent = total_sent
|
||||||
|
resourceStats.PrevNet.Recv = total_recv
|
||||||
|
resourceStats.PrevReadTime = time.Now()
|
||||||
|
|
||||||
|
// Update final stats values
|
||||||
|
resourceStats.Cpu = twoDecimals(100.0 * resource.CPU * float64(resource.MaxCPU) / float64(pm.cpuCount))
|
||||||
|
resourceStats.Mem = bytesToMegabytes(float64(resource.Mem))
|
||||||
|
resourceStats.Bandwidth = [2]uint64{uint64(sent_delta), uint64(recv_delta)}
|
||||||
|
|
||||||
|
stats = append(stats, resourceStats)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user