Pulse/internal/monitoring/monitor_previous_state.go
2026-04-01 19:31:50 +01:00

185 lines
5 KiB
Go

package monitoring
import (
"strings"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
)
type previousGuestContext struct {
vms []models.VM
vmsByID map[string]models.VM
containers []models.Container
containerOCIByVMID map[int]bool
hostAgentsByVMID map[string]models.Host
}
func (m *Monitor) previousGuestContextForInstance(instanceName string) previousGuestContext {
ctx := previousGuestContext{
vms: make([]models.VM, 0),
vmsByID: make(map[string]models.VM),
containers: make([]models.Container, 0),
containerOCIByVMID: make(map[int]bool),
hostAgentsByVMID: make(map[string]models.Host),
}
readState := m.GetUnifiedReadStateOrSnapshot()
if readState == nil {
return ctx
}
for _, vm := range readState.VMs() {
if vm == nil || vm.Instance() != instanceName {
continue
}
modelVM := previousVMFromView(vm)
ctx.vms = append(ctx.vms, modelVM)
if modelVM.ID != "" {
ctx.vmsByID[modelVM.ID] = modelVM
}
guestID := makeGuestID(modelVM.Instance, modelVM.Node, modelVM.VMID)
if guestID != "" {
ctx.vmsByID[guestID] = modelVM
}
}
for _, ct := range readState.Containers() {
if ct == nil || ct.Instance() != instanceName {
continue
}
container := previousContainerFromView(ct)
ctx.containers = append(ctx.containers, container)
if container.VMID > 0 && (strings.EqualFold(strings.TrimSpace(container.Type), "oci") || container.IsOCI) {
ctx.containerOCIByVMID[container.VMID] = true
}
}
for _, host := range readState.Hosts() {
if host == nil {
continue
}
modelHost := previousHostFromView(host)
if modelHost.LinkedVMID == "" || modelHost.Status != "online" {
continue
}
ctx.hostAgentsByVMID[modelHost.LinkedVMID] = modelHost
}
return ctx
}
func (m *Monitor) previousNodesForInstance(instanceName string) (map[string]models.Memory, []models.Node) {
prevNodeMemory := make(map[string]models.Memory)
prevInstanceNodes := make([]models.Node, 0)
readState := m.GetUnifiedReadStateOrSnapshot()
if readState == nil {
return prevNodeMemory, prevInstanceNodes
}
for _, existingNode := range readState.Nodes() {
if existingNode == nil || existingNode.Instance() != instanceName {
continue
}
modelNode := previousNodeFromView(existingNode)
prevNodeMemory[modelNode.ID] = modelNode.Memory
prevInstanceNodes = append(prevInstanceNodes, modelNode)
}
return prevNodeMemory, prevInstanceNodes
}
func previousVMFromView(vm *unifiedresources.VMView) models.VM {
if vm == nil {
return models.VM{}
}
return models.VM{
ID: vm.ID(),
Instance: vm.Instance(),
Node: vm.Node(),
VMID: vm.VMID(),
Name: vm.Name(),
Type: "qemu",
Status: string(vm.Status()),
IPAddresses: vm.IPAddresses(),
OSName: vm.OSName(),
OSVersion: vm.OSVersion(),
AgentVersion: vm.AgentVersion(),
Disk: models.Disk{
Used: vm.DiskUsed(),
Total: vm.DiskTotal(),
Free: max(0, vm.DiskTotal()-vm.DiskUsed()),
Usage: vm.DiskPercent(),
},
NetworkInterfaces: guestNetworkInterfacesFromReadStateView(vm.NetworkInterfaces()),
Disks: guestDisksFromReadStateView(vm.Disks()),
DiskStatusReason: vm.DiskStatusReason(),
LastSeen: vm.LastSeen(),
}
}
func previousContainerFromView(ct *unifiedresources.ContainerView) models.Container {
if ct == nil {
return models.Container{}
}
return models.Container{
ID: ct.ID(),
Instance: ct.Instance(),
Node: ct.Node(),
VMID: ct.VMID(),
Name: ct.Name(),
Status: string(ct.Status()),
Type: ct.ContainerType(),
IsOCI: ct.IsOCI(),
LastSeen: ct.LastSeen(),
Memory: models.Memory{
Used: ct.MemoryUsed(),
Total: ct.MemoryTotal(),
Usage: ct.MemoryPercent() / 100,
},
}
}
func previousHostFromView(host *unifiedresources.HostView) models.Host {
if host == nil {
return models.Host{}
}
return models.Host{
ID: host.ID(),
Hostname: host.Hostname(),
Status: string(host.Status()),
LinkedVMID: host.LinkedVMID(),
LastSeen: host.LastSeen(),
Disks: guestDisksFromReadStateView(host.Disks()),
Memory: models.Memory{
Used: host.MemoryUsed(),
Total: host.MemoryTotal(),
Usage: host.MemoryPercent() / 100,
},
}
}
func previousNodeFromView(node *unifiedresources.NodeView) models.Node {
if node == nil {
return models.Node{}
}
return models.Node{
ID: node.ID(),
Name: node.NodeName(),
DisplayName: node.Name(),
Instance: node.Instance(),
Host: node.HostURL(),
Status: string(node.Status()),
Uptime: node.Uptime(),
IsClusterMember: node.IsClusterMember(),
LastSeen: node.LastSeen(),
LoadAverage: node.LoadAverage(),
PVEVersion: node.PVEVersion(),
KernelVersion: node.KernelVersion(),
Memory: models.Memory{
Used: node.MemoryUsed(),
Total: node.MemoryTotal(),
Usage: node.MemoryPercent() / 100,
},
}
}