Physical-disk identity of every storage place + POST /disks/same-disk (felhom.eu architecture/16 §3/§4)
gates / gates (push) Successful in 31s
gates / gates (push) Successful in 31s
The agent names the physical disk(s) under each storage place from /sys, udev and /proc/mounts only
(partition -> disk, dm/LVM thin -> slaves, loop -> backing file), keys them (eui / serial:<bus>:<model>
:<serial> / vendor WWN) and says proven or unknown (vm, network, usb_bridge, weak_wwn, no_serial).
GET /disks and the hub report's storage_targets gain kind, physical_disks, identity,
identity_reason (golden updated; the hub copy changes in the same session). POST /disks/same-disk
maps two guest paths to places the agent itself made and answers {different, proven, reason};
an absent drive is unmapped, never the root disk. Tests on fixture trees for every spike case,
red-proofed. CHANGELOG entry follows the release (release-complete gate).
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
@@ -777,6 +777,7 @@ func runDaemon(cfg config.Config, logger *slog.Logger, logRing *applog.Ring) int
|
||||
hostReader := storage.NewProcHostReader()
|
||||
hostOps := newHostOps(cfg, logger)
|
||||
observer := storage.NewObserver(px, hostReader, hostOps, logger)
|
||||
observer.SetIdentity(storage.NewIdentityResolver()) // `16` §3 physical-disk identity
|
||||
// Backup + restore-test state store (slice 6): holds the latest backup-per-target +
|
||||
// latest restore-test result; the collector reads it via the BackupReporter /
|
||||
// RestoreTestReporter seams; the cadence scheduler writes it.
|
||||
@@ -2000,6 +2001,7 @@ func buildLocalAPIServer(cfg config.Config, px *proxmox.Client, store *backup.St
|
||||
DriveTargets: driveTargets, // Impl-2a: registry+units drives for the /disks view (union w/ Observe storages)
|
||||
Smart: storage.NewSmartReader(hostOps), // v0.95.0 Fix B: SMART for the union-path drives
|
||||
HostReader: storage.NewProcHostReader(), // Impl-2b: durableIDForMount raw-mount fallback + role gate
|
||||
Identity: storage.NewIdentityResolver(), // v0.157.0: `16` §3 identity on /disks + POST /disks/same-disk
|
||||
Tokens: tokens,
|
||||
BackupCadence: cfg.Backup.BackupCadence(),
|
||||
// Disk management (slice 8C): the privileged host surface + the data-bearing wipe gate.
|
||||
@@ -2188,6 +2190,7 @@ func runSelftestHub(ctx context.Context, cfg config.Config, logger *slog.Logger)
|
||||
return 1
|
||||
}
|
||||
observer := storage.NewObserver(px, storage.NewProcHostReader(), newHostOps(cfg, logger), logger)
|
||||
observer.SetIdentity(storage.NewIdentityResolver()) // `16` §3 physical-disk identity
|
||||
// Wire the LIVE PBS reporter here too (v0.39.0): selftest=hub is a separate one-shot process — no
|
||||
// verify loop runs — so a nil reporter previously yielded pbs_snapshots:[] and an absent dr_recipe
|
||||
// pbs coord. The live reporter lists snapshots directly (fresh store, last-known-good fallback) so
|
||||
@@ -2244,6 +2247,7 @@ func runSelftestStorage(ctx context.Context, cfg config.Config, logger *slog.Log
|
||||
hostReader := storage.NewProcHostReader()
|
||||
hostOps := newHostOps(cfg, logger)
|
||||
observer := storage.NewObserver(px, hostReader, hostOps, logger)
|
||||
observer.SetIdentity(storage.NewIdentityResolver()) // `16` §3 physical-disk identity
|
||||
|
||||
octx, cancel := context.WithTimeout(ctx, 60*time.Second)
|
||||
fmt.Printf("=== felhom-agent %s selftest=storage ===\n", version)
|
||||
|
||||
Reference in New Issue
Block a user