Files
admin 27b68f043b 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>
2026-06-09 09:59:05 +02:00

30 lines
1.7 KiB
Go

// Package storage observes and reconciles the host's storage targets (doc 03 §7).
//
// Slice 5 builds the full model + reconcile machinery; only the read-only, no-hub-desired-
// state parts run live:
//
// - Observe every Proxmox storage target and report it into the host-report
// (hub.StorageTarget). The reported view is what the agent SEES; the hub holds the
// authoritative manifest (desired class/role/policy/creds) and is not served until
// slice 10. So class is a rotational HINT here, never authoritative.
// - A storage watchdog: a fast-poll loop that detects a KNOWN target going
// attached↔disconnected in seconds and triggers an immediate, debounced out-of-band
// host-report (rather than waiting for the slow ~15-minute cycle).
//
// Phase A (this file set) is read-only: every host read it needs — /proc/mounts,
// /dev/disk/by-uuid, /sys/.../rotational, device presence — is non-privileged. Anything
// needing root (SMART via smartctl, lvs for thin-pool metadata, blkid) is deferred to
// Phase B's privileged HostOps surface.
//
// Layout:
// - hostread.go — the HostReader seam + a non-privileged procfs/sysfs implementation.
// - durableid.go — deterministic durable_id derivation per target type (the
// DR-load-bearing field: the hub re-attaches the RIGHT drive by it).
// - observe.go — the Observer: builds []hub.StorageTarget from Proxmox + host reads.
// - watchdog.go — the fast-poll watchdog: transition detection + debounced trigger.
//
// The collector (internal/hub) calls the Observer through a narrow seam, so hub does not
// import storage (storage imports hub for the wire type) — the same interface-seam pattern
// the collector uses for proxmox and cloudflared.
package storage