Pulse/internal/utils/helpers.go
rcourtman cc3c0187a0 feat: AI features, agent improvements, and host monitoring enhancements
AI Chat Integration:
- Multi-provider support (Anthropic, OpenAI, Ollama)
- Streaming responses with markdown rendering
- Agent command execution for remote troubleshooting
- Context-aware conversations with host/container metadata

Agent Updates:
- Add --enable-proxmox flag for automatic PVE/PBS token setup
- Improve auto-update with semver comparison (prevents downgrades)
- Add updatedFrom tracking to report previous version after update
- Reduce initial update check delay from 30s to 5s
- Add agent version column to Hosts page table

Host Metrics:
- Add DiskIO stats collection (read/write bytes, ops, time)
- Improve disk filtering to exclude Docker overlay mounts
- Add RAID array monitoring via mdadm
- Enhanced temperature sensor parsing

Frontend:
- New Agent Version column on Hosts overview table
- Improved node modal with agent-first installation flow
- Add DiskIO display in host drawer
- Better responsive handling for metric bars
2025-12-05 10:37:02 +00:00

95 lines
2.2 KiB
Go

package utils
import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"github.com/google/uuid"
)
// GenerateID generates a unique ID with the given prefix
func GenerateID(prefix string) string {
return fmt.Sprintf("%s-%s", prefix, uuid.NewString())
}
// WriteJSONResponse writes a JSON response to the http.ResponseWriter
func WriteJSONResponse(w http.ResponseWriter, data interface{}) error {
w.Header().Set("Content-Type", "application/json")
// Use Marshal instead of Encoder for better performance with large payloads
jsonData, err := json.Marshal(data)
if err != nil {
return err
}
_, err = w.Write(jsonData)
return err
}
// ParseBool interprets common boolean strings, returning true for typical truthy values.
func ParseBool(value string) bool {
switch strings.ToLower(strings.TrimSpace(value)) {
case "1", "true", "yes", "y", "on":
return true
default:
return false
}
}
// GetenvTrim returns the environment variable value with surrounding whitespace removed.
func GetenvTrim(key string) string {
return strings.TrimSpace(os.Getenv(key))
}
// NormalizeVersion strips the "v" prefix from version strings for comparison.
// This normalizes versions like "v4.33.1" to "4.33.1" so that version strings
// from different sources (agent vs server) can be compared consistently.
func NormalizeVersion(version string) string {
return strings.TrimPrefix(strings.TrimSpace(version), "v")
}
// CompareVersions compares two semver-like version strings.
// Returns:
//
// 1 if a > b (a is newer)
// 0 if a == b
//
// -1 if a < b (b is newer)
//
// Handles versions like "4.33.1", "v4.33.1", "4.33" gracefully.
func CompareVersions(a, b string) int {
// Normalize both versions
a = NormalizeVersion(a)
b = NormalizeVersion(b)
// Split into parts
partsA := strings.Split(a, ".")
partsB := strings.Split(b, ".")
// Compare each part numerically
maxLen := len(partsA)
if len(partsB) > maxLen {
maxLen = len(partsB)
}
for i := 0; i < maxLen; i++ {
var numA, numB int
if i < len(partsA) {
fmt.Sscanf(partsA[i], "%d", &numA)
}
if i < len(partsB) {
fmt.Sscanf(partsB[i], "%d", &numB)
}
if numA > numB {
return 1
}
if numA < numB {
return -1
}
}
return 0
}