mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 03:20:11 +00:00
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
This commit is contained in:
parent
53d7776d6b
commit
8948e84fe5
45 changed files with 2038 additions and 353 deletions
|
|
@ -48,3 +48,48 @@ func GetenvTrim(key string) string {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,3 +318,50 @@ func TestNormalizeVersion(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompareVersions(t *testing.T) {
|
||||
tests := []struct {
|
||||
a string
|
||||
b string
|
||||
expected int
|
||||
}{
|
||||
// Equal versions
|
||||
{"4.33.1", "4.33.1", 0},
|
||||
{"v4.33.1", "4.33.1", 0},
|
||||
{"4.33.1", "v4.33.1", 0},
|
||||
{"1.0.0", "1.0.0", 0},
|
||||
|
||||
// a > b (a is newer)
|
||||
{"4.33.2", "4.33.1", 1},
|
||||
{"4.34.0", "4.33.1", 1},
|
||||
{"5.0.0", "4.33.1", 1},
|
||||
{"4.33.10", "4.33.9", 1},
|
||||
{"4.33.1", "4.33", 1}, // Missing patch = 0
|
||||
|
||||
// a < b (b is newer)
|
||||
{"4.33.1", "4.33.2", -1},
|
||||
{"4.33.1", "4.34.0", -1},
|
||||
{"4.33.1", "5.0.0", -1},
|
||||
{"4.33.9", "4.33.10", -1},
|
||||
{"4.33", "4.33.1", -1},
|
||||
|
||||
// With v prefix
|
||||
{"v4.34.0", "v4.33.1", 1},
|
||||
{"v4.33.1", "v4.34.0", -1},
|
||||
|
||||
// Edge cases
|
||||
{"0.0.1", "0.0.0", 1},
|
||||
{"0.0.0", "0.0.1", -1},
|
||||
{"1.0", "0.9.9", 1},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
name := tc.a + "_vs_" + tc.b
|
||||
t.Run(name, func(t *testing.T) {
|
||||
result := CompareVersions(tc.a, tc.b)
|
||||
if result != tc.expected {
|
||||
t.Errorf("CompareVersions(%q, %q) = %d, want %d", tc.a, tc.b, result, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue