v0.5.0-rc1: slice 5 Phase A — storage observe/report + watchdog (read-only, live)
Fill the slice-3 storage_targets stub and add the fast-poll storage watchdog. Read-only this phase; the host-root surface (mounts/SMART/grow/destructive gate) is Phase B. Hub-owned desired manifest is slice 10, so reconcile against it is built-but-unfed. - internal/storage: StorageTarget wire contract, durable_id derivation per type, HostReader seam (procfs/sysfs, root-free), Observer (storage_targets from ListStorage/NodeStorage + host reads, lvmthin thin-pool fill), and the watchdog (third daemon goroutine; debounced out-of-band report on a known target's attach/disconnect transition). - proxmox.Storage: additive parse-only config fields (durable_id sources). - collector StorageObserver seam; Loop.SetTrigger out-of-band report; daemon runs the watchdog as a third goroutine; StorageConfig knobs. - cross-repo golden kept byte-identical with felhom.eu/hub; bidirectional key-set test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,7 @@ type Loop struct {
|
||||
client reporter
|
||||
interval time.Duration
|
||||
logger *slog.Logger
|
||||
trigger <-chan struct{} // optional: an out-of-band report request (storage watchdog)
|
||||
}
|
||||
|
||||
// NewLoop builds the loop. interval is the starting cadence (the hub may override it
|
||||
@@ -41,6 +42,12 @@ func NewLoop(collector collectorIface, client reporter, interval time.Duration,
|
||||
return &Loop{collector: collector, client: client, interval: interval, logger: logger}
|
||||
}
|
||||
|
||||
// SetTrigger wires an out-of-band report channel. A receive on it runs one extra
|
||||
// collect→report cycle immediately WITHOUT disturbing the regular ticker cadence — used by
|
||||
// the storage watchdog to push a disconnect to the hub in seconds. The watchdog debounces,
|
||||
// so this fires at most once per debounce window.
|
||||
func (l *Loop) SetTrigger(ch <-chan struct{}) { l.trigger = ch }
|
||||
|
||||
// Run reports immediately, then on each tick, until ctx is cancelled (then nil).
|
||||
func (l *Loop) Run(ctx context.Context) error {
|
||||
interval := l.interval
|
||||
@@ -60,6 +67,17 @@ func (l *Loop) Run(ctx context.Context) error {
|
||||
interval = next
|
||||
ticker.Reset(interval)
|
||||
}
|
||||
case <-l.trigger:
|
||||
// Out-of-band report (storage watchdog). Run a cycle now; keep the regular
|
||||
// cadence (do not reset the ticker). The envelope's interval is still adopted
|
||||
// if it changed, mirroring the normal path.
|
||||
l.logger.Info("hub: out-of-band report triggered (storage watchdog)")
|
||||
next := l.cycle(ctx, interval)
|
||||
if next != interval {
|
||||
l.logger.Info("hub: poll interval changed", "from", interval, "to", next)
|
||||
interval = next
|
||||
ticker.Reset(interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user