mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
Let explicit disk temperature overrides beat per-type defaults
DiskTempByType unconditionally replaced the resolved host threshold, so a host-level (or inherited linked-resource) diskTemperature override never applied to nvme/sas/sata disks. Explicit overrides now win; the per-type map still beats the global agent default. Refs #1540
This commit is contained in:
parent
f8e5642ae7
commit
b6fd06c63d
2 changed files with 67 additions and 6 deletions
|
|
@ -69,31 +69,42 @@ func hostInstanceName(host models.Host) string {
|
|||
func (m *Manager) resolveHostThresholdsNoLock(hostID, linkedNodeID, linkedVMID, linkedContainerID string) ThresholdConfig {
|
||||
base := m.defaultThresholdsForResourceType("agent")
|
||||
|
||||
if override, exists := m.hostThresholdOverrideNoLock(hostID, linkedNodeID, linkedVMID, linkedContainerID); exists {
|
||||
return m.applyThresholdOverride(base, override)
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
// hostThresholdOverrideNoLock returns the first override in the host-agent
|
||||
// resolution chain (host, linked node, linked guest), mirroring
|
||||
// resolveHostThresholdsNoLock's precedence. Callers must hold m.mu.
|
||||
func (m *Manager) hostThresholdOverrideNoLock(hostID, linkedNodeID, linkedVMID, linkedContainerID string) (ThresholdConfig, bool) {
|
||||
if hostID = strings.TrimSpace(hostID); hostID != "" {
|
||||
if override, exists := m.config.Overrides[hostID]; exists {
|
||||
return m.applyThresholdOverride(base, override)
|
||||
return override, true
|
||||
}
|
||||
}
|
||||
|
||||
if linkedNodeID = strings.TrimSpace(linkedNodeID); linkedNodeID != "" {
|
||||
if override, exists := m.config.Overrides[linkedNodeID]; exists {
|
||||
return m.applyThresholdOverride(base, override)
|
||||
return override, true
|
||||
}
|
||||
}
|
||||
|
||||
if linkedVMID = strings.TrimSpace(linkedVMID); linkedVMID != "" {
|
||||
if override, exists := lookupGuestOverride(m.config.Overrides, nil, linkedVMID); exists {
|
||||
return m.applyThresholdOverride(base, override)
|
||||
return override, true
|
||||
}
|
||||
}
|
||||
|
||||
if linkedContainerID = strings.TrimSpace(linkedContainerID); linkedContainerID != "" {
|
||||
if override, exists := lookupGuestOverride(m.config.Overrides, nil, linkedContainerID); exists {
|
||||
return m.applyThresholdOverride(base, override)
|
||||
return override, true
|
||||
}
|
||||
}
|
||||
|
||||
return base
|
||||
return ThresholdConfig{}, false
|
||||
}
|
||||
|
||||
// resolveHostAlertThresholdsNoLock resolves thresholds for persisted host-agent alerts.
|
||||
|
|
@ -217,6 +228,12 @@ func (m *Manager) CheckHost(host models.Host) {
|
|||
alertsEnabled := m.config.Enabled
|
||||
disableAllAgents := m.config.DisableAllAgents
|
||||
thresholds := m.resolveHostThresholdsNoLock(host.ID, host.LinkedNodeID, host.LinkedVMID, host.LinkedContainerID)
|
||||
// An explicit disk temperature override (host or inherited linked-resource)
|
||||
// beats the per-type defaults in DiskTempByType.
|
||||
diskTempOverridden := false
|
||||
if override, exists := m.hostThresholdOverrideNoLock(host.ID, host.LinkedNodeID, host.LinkedVMID, host.LinkedContainerID); exists && override.DiskTemperature != nil {
|
||||
diskTempOverridden = true
|
||||
}
|
||||
m.mu.RUnlock()
|
||||
|
||||
if !alertsEnabled {
|
||||
|
|
@ -318,7 +335,7 @@ func (m *Manager) CheckHost(host models.Host) {
|
|||
for _, disk := range host.Sensors.SMART {
|
||||
if disk.Temperature > 0 && !disk.Standby {
|
||||
effectiveTempThreshold := thresholds.DiskTemperature
|
||||
if diskType := strings.ToLower(strings.TrimSpace(disk.Type)); diskType != "" {
|
||||
if diskType := strings.ToLower(strings.TrimSpace(disk.Type)); diskType != "" && !diskTempOverridden {
|
||||
m.mu.RLock()
|
||||
if th, ok := m.config.DiskTempByType[diskType]; ok {
|
||||
t := th
|
||||
|
|
|
|||
|
|
@ -314,3 +314,47 @@ func TestHostDiskTempPerTypeThresholdDoesNotOverrideDisabledGlobalDefault(t *tes
|
|||
}
|
||||
m.mu.RUnlock()
|
||||
}
|
||||
|
||||
func TestHostDiskTempExplicitOverrideBeatsPerTypeThreshold(t *testing.T) {
|
||||
m := configureDiskTempTypeHostManager(t)
|
||||
|
||||
hostID := "host-temp-override-nvme"
|
||||
m.mu.Lock()
|
||||
m.config.Overrides[hostID] = ThresholdConfig{
|
||||
DiskTemperature: &HysteresisThreshold{Trigger: 60, Clear: 55},
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
// 62C is below the nvme per-type trigger (70) but above the explicit
|
||||
// override (60): the override must win and fire the alert.
|
||||
hostAbove := hostWithSMARTDiskTemp(hostID, "nvme", 62)
|
||||
m.CheckHost(hostAbove)
|
||||
|
||||
trackingKey := hostDiskTempAlertID(hostAbove)
|
||||
if _, exists := testLookupActiveAlert(t, m, trackingKey); !exists {
|
||||
t.Fatalf("expected alert for nvme disk at 62C with explicit override trigger 60, active: %v", alertKeys(m))
|
||||
}
|
||||
|
||||
m.ClearActiveAlerts()
|
||||
|
||||
m.mu.Lock()
|
||||
m.config.Overrides[hostID] = ThresholdConfig{
|
||||
DiskTemperature: &HysteresisThreshold{Trigger: 80, Clear: 75},
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
// 75C is above the nvme per-type trigger (70) but below the explicit
|
||||
// override (80): the override must win and stay quiet.
|
||||
hostBelow := hostWithSMARTDiskTemp(hostID, "nvme", 75)
|
||||
m.CheckHost(hostBelow)
|
||||
|
||||
if _, exists := testLookupActiveAlert(t, m, trackingKey); exists {
|
||||
t.Fatalf("expected no alert for nvme disk at 75C with explicit override trigger 80, active: %v", alertKeys(m))
|
||||
}
|
||||
m.mu.RLock()
|
||||
if _, pending := m.pendingAlerts[trackingKey]; pending {
|
||||
m.mu.RUnlock()
|
||||
t.Fatalf("expected no pending alert for nvme disk at 75C with explicit override trigger 80, but pendingAlerts has %q", trackingKey)
|
||||
}
|
||||
m.mu.RUnlock()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue