v0.184.0 — E-2b + Part 5: wire the drive-absent alarm that was never called
NotifyStorageDisconnected and NotifyStorageReconnected were defined and called from NOWHERE. Registered in allowedEventTypes, in DefaultEnabledEvents, and given a Hungarian message on the hub -- and never invoked. A drive going absent produced apps stopped, a WARN log and a UI badge, then silence on every channel. Verified against the gitignored-cmd/ trap with a positive control. Fifth instance of this class, found by E-2 Phase 0 rather than by a failure. A drive that is ONLY a backup target has no apps to stop, so it was silent twice. ReconcileDriveGates now calls both halves. When the absent drive is the whole-guest backup target it raises the more specific backup_target_absent (error) instead -- never both, since two mails for one event trains people to ignore the channel -- and recovers as backup_target_restored (info, the existing pairing-gated pattern; severityNotifies NOT widened). The recovery mirrors the alarm's choice or the operator cannot match them. Which drive is the target comes from the AGENT (/disks backup_target, >= 0.112.0), not from our StoragePath.BackupTarget: that is customer INTENT, and on the two boxes migrated by hand in E-1 the intent was never recorded while the drive really is the target. An older agent omits the field -> false -> generic alarm, never a wrong one. Before this an absent backup target had NO prompt signal: the tier stays DUE (targetStoragePresent checks name presence, never reachability), so the only evidence was its own failure at the next due cycle, up to ~24h away. The R-100 shape. Tests observe the WIRE, not a mock, because the failure class is "nothing arrives": a real Notifier posts to an httptest hub and the test asserts the event type and severity that actually went out. MinAgent: 0.112.0 Green gate: build + vet + test rc=0 (27 packages), run separately from this commit.
This commit is contained in:
@@ -360,6 +360,27 @@ func (n *Notifier) NotifyStorageDisconnected(label string, stoppedApps []string)
|
||||
})
|
||||
}
|
||||
|
||||
// NotifyBackupTargetAbsent (E-2) reports that the drive holding the WHOLE-GUEST backup is gone.
|
||||
//
|
||||
// Distinct from NotifyStorageDisconnected on purpose. That one means "a drive went away and some apps
|
||||
// may have stopped"; this means "the thing that makes your backup survive a disk failure is gone" —
|
||||
// a different customer action and a different operator urgency. Before E-2 this had NO prompt signal
|
||||
// at all: the tier stays DUE (targetStoragePresent checks name presence, never reachability), so the
|
||||
// only evidence was its own failure at the next due cycle, up to ~24 h away on the daily local tier.
|
||||
func (n *Notifier) NotifyBackupTargetAbsent(label, target string) {
|
||||
n.PushEvent("backup_target_absent", "error",
|
||||
fmt.Sprintf("A rendszermentés meghajtója nem érhető el: %s (%s)", label, target),
|
||||
StorageDetails{Label: label})
|
||||
}
|
||||
|
||||
// NotifyBackupTargetRestored is the paired recovery. info severity — the existing recovery pattern;
|
||||
// severityNotifies is deliberately NOT widened.
|
||||
func (n *Notifier) NotifyBackupTargetRestored(label, target string) {
|
||||
n.PushEvent("backup_target_restored", "info",
|
||||
fmt.Sprintf("A rendszermentés meghajtója újra elérhető: %s (%s)", label, target),
|
||||
StorageDetails{Label: label})
|
||||
}
|
||||
|
||||
// NotifyStorageReconnected sends a drive reconnection event.
|
||||
func (n *Notifier) NotifyStorageReconnected(label string) {
|
||||
n.PushEvent("storage_reconnected", "info",
|
||||
|
||||
Reference in New Issue
Block a user