v0.169.0: disk-health card + degradation notification (Lemezek állapota)
Consumes the agent v0.94.0 smart payload (MinAgent floor unchanged; feature-detect by presence). One pure verdict fn agentapi.DiskVerdictFor shared by the dashboard card and the 6h check. Card via a 60s /disks TTL cache (anti-smartctl-storm); unreachable agent -> Nincs adat, page never blocks. disk-health-check (6h) emits disk_health_degraded on a degradation only vs an in-memory baseline (first run silent, recovery/UNKNOWN never notify, multi-attr -> one event). No global banner (deliberate). Pairs with the hub allowlist bump. Tests: verdict table (>=90 red-proof), notifier emit, check first-run-silent (red-proof), degradation-once, recovery-silent, UNKNOWN-excluded, FAILING-critical, nil-smart card, TTL cache.
This commit is contained in:
@@ -322,6 +322,10 @@ type DiskInfo struct {
|
||||
// BoundUnderParent reports whether the drive's felhom-data is currently bound under the shared parent
|
||||
// (live + usable in the guest). The controller's drive-absent gate keys on this + State.
|
||||
BoundUnderParent bool `json:"bound_under_parent"`
|
||||
// Smart is the per-disk SMART health (agent v0.94.0+), nil when the device exposes no SMART or the
|
||||
// agent predates the field — the disk-health card + 6h degradation check feature-detect on this and
|
||||
// render "Nincs adat" (never alarm) when nil. See DiskVerdictFor.
|
||||
Smart *SmartSummary `json:"smart,omitempty"`
|
||||
}
|
||||
|
||||
// FSUUID returns the raw filesystem UUID from a "uuid:<…>" DurableID, or "" if this disk's identity
|
||||
@@ -1003,14 +1007,31 @@ type ThinPoolFill struct {
|
||||
MetadataUsedFraction *float64 `json:"metadata_used_fraction"`
|
||||
}
|
||||
|
||||
// SmartSummary mirrors the agent's per-disk SMART health (only the fields the UI renders). Pointers
|
||||
// are null when the device type does not expose that attribute.
|
||||
// SmartSummary mirrors the agent's per-disk SMART health. Pointers are null when the device type
|
||||
// does not expose that attribute (a null is "unknown / not-applicable", distinct from a real zero).
|
||||
// The SATA set (reallocated/pending/offline-uncorrectable) and the NVMe set
|
||||
// (critical_warning/media_errors/percentage_used) are both carried; a device populates only its own.
|
||||
type SmartSummary struct {
|
||||
Health string `json:"health"` // PASSED | FAILING | UNKNOWN
|
||||
TemperatureC *int `json:"temperature_c"`
|
||||
PercentageUsed *int `json:"percentage_used"` // NVMe wear (%); null for SATA/USB
|
||||
Health string `json:"health"` // PASSED | FAILING | UNKNOWN
|
||||
TemperatureC *int `json:"temperature_c"`
|
||||
PowerOnHours *int `json:"power_on_hours"`
|
||||
// SATA attributes.
|
||||
ReallocatedSectors *int `json:"reallocated_sectors"`
|
||||
PendingSectors *int `json:"pending_sectors"`
|
||||
OfflineUncorrectable *int `json:"offline_uncorrectable"`
|
||||
// NVMe attributes.
|
||||
CriticalWarning *int `json:"critical_warning"`
|
||||
MediaErrors *int `json:"media_errors"`
|
||||
PercentageUsed *int `json:"percentage_used"` // NVMe wear (%); null for SATA/USB
|
||||
}
|
||||
|
||||
// SMART health vocabulary (mirrors the agent's).
|
||||
const (
|
||||
SmartPassed = "PASSED"
|
||||
SmartFailing = "FAILING"
|
||||
SmartUnknown = "UNKNOWN"
|
||||
)
|
||||
|
||||
// StorageTarget mirrors the agent's GET /host/metrics storage_targets entry (the per-storage
|
||||
// capacity + health the monitoring view renders). It is a SUBSET of the agent's wire shape — only
|
||||
// the fields the UI reads; unknown JSON keys are ignored.
|
||||
|
||||
Reference in New Issue
Block a user