Files
felhom-agent/internal/hub/testdata/host-report.golden.json
T
admin 14642e3c7b v0.119.0 — the host report carries the box's addresses
A managed box's IP was invisible in every operator surface because nothing
reported one: HostMetrics carried node/cpu/mem/disk/load/uptime/temp/wrapper-sha
and no address of any kind. The hub could not show a host's LAN IP anywhere.

Two things that looked like the answer are traps, both checked before writing
code: lan_resolver.host_ip is an OPTIONAL config value absent unless that feature
is configured, and DeriveHostIP(local_api.listen_addr) returns 169.254.253.1 —
since R-50 the local API binds a link-local address identical on every box. Both
would have produced a confident wrong answer.

New wire field addresses[], one entry per (interface, address). Deliberately
iface+cidr rather than a single lan_ip: a Proxmox host legitimately holds several
(management bridge, tailnet, WG tunnel) and picking one to call "the" LAN IP is a
guess the agent is not entitled to make — silently wrong on a box whose bridge is
not vmbr0. The agent reports what exists; the hub does the labelling.

The filter is one predicate, chosen by MEASURING both demo hosts rather than by
reasoning about interface names. IsGlobalUnicast() alone drops loopback, IPv6
link-local (one per bridge, pure noise) and IPv4 link-local (169.254/16 — exactly
the island address above). It needs no veth/fwbr/tap denylist: that per-guest
plumbing carries no IP at all and self-excludes, verified on both boxes.

No new privilege and no block I/O — net.Interfaces() is a netlink/procfs read, so
the sudoers fence is untouched and the health-check rule is honoured.

The seam DEFAULTS to the real enumerator, inverting the nil-reporter-means-off
convention: this stanza has no config gate, so a forgotten wiring call would have
shipped it silently empty — the inert-seam failure recorded four times here.

Cross-repo: the golden is duplicated byte-identically in felhom.eu and the
contract test fails on top-level key drift, so both goldens moved together and
addresses[0]'s key set is asserted bidirectionally. The field marshals as [],
never null — the repo's own no-nulls invariant caught that on the first run.

Tests +9; three red-proofs (global-unicast filter, down-interface guard, inert
collectAddresses) each run, observed failing, and reverted.
2026-07-31 08:40:58 +02:00

171 lines
4.7 KiB
JSON

{
"host_id": "demo-host-01",
"reported_at": "2026-06-08T12:00:00Z",
"agent_version": "0.3.1",
"host": {
"node": "demo-felhom",
"cpu_percent": 3.2,
"memory_total_bytes": 16777216000,
"memory_used_bytes": 4194304000,
"memory_percent": 25,
"disk_total_bytes": 152000000000,
"disk_used_bytes": 30000000000,
"disk_percent": 19.7,
"loadavg": ["0.10", "0.20", "0.15"],
"uptime_seconds": 86400,
"cpu_temp_c": 47
},
"guests": [
{
"vmid": 100,
"name": "felhom-cust-acme",
"status": "running",
"controller_version": "",
"spec": { "cores": 2, "memory_bytes": 2147483648, "disk_bytes": 21474836480 }
},
{
"vmid": 101,
"name": "felhom-cust-beta",
"status": "stopped",
"controller_version": ""
}
],
"storage_targets": [
{
"name": "local-lvm",
"type": "lvmthin",
"durable_id": "pve/data",
"state": "attached",
"reachable": true,
"total_bytes": 100000000000,
"used_bytes": 42000000000,
"avail_bytes": 58000000000,
"used_fraction": 0.42,
"content": "rootdir,images",
"mount_path": "",
"backing_device": "",
"class_hint": "fast",
"role": "",
"thin_pool": { "data_used_fraction": 0.42, "metadata_used_fraction": null },
"smart": {
"health": "UNKNOWN",
"temperature_c": null,
"power_on_hours": null,
"reallocated_sectors": null,
"pending_sectors": null,
"offline_uncorrectable": null,
"critical_warning": null,
"media_errors": null,
"percentage_used": null
}
},
{
"name": "usb-backup",
"type": "usb",
"durable_id": "uuid:0fc63daf-8483-4772-8e79-3d69d8477de4",
"state": "attached",
"reachable": true,
"total_bytes": 2000000000000,
"used_bytes": 500000000000,
"avail_bytes": 1500000000000,
"used_fraction": 0.25,
"content": "backup",
"mount_path": "/mnt/usb-backup",
"backing_device": "/dev/sdb1",
"class_hint": "slow",
"role": "",
"smart": {
"health": "UNKNOWN",
"temperature_c": null,
"power_on_hours": null,
"reallocated_sectors": null,
"pending_sectors": null,
"offline_uncorrectable": null,
"critical_warning": null,
"media_errors": null,
"percentage_used": null
}
}
],
"backups": [
{
"target_id": "local",
"vmid": 9001,
"archive": "local:backup/vzdump-lxc-9001-2026_06_09-11_00_00.tar.zst",
"mode": "snapshot",
"crash_consistent": true,
"size_bytes": 524288000,
"success": true,
"started_at": "2026-06-09T11:00:00Z",
"duration_seconds": 42.5,
"uncovered_volumes": ["/mnt/bulk"]
}
],
"restore_tests": [
{
"source_archive": "local:backup/vzdump-lxc-9001-2026_06_09-11_00_00.tar.zst",
"source_tier": "local",
"scratch_vmid": 990000,
"pass": true,
"verified": "boot+running",
"tested_at": "2026-06-09T11:05:00Z",
"duration_seconds": 38.2,
"warnings": [
"WARN: Systemd 257 detected. You may need to enable nesting."
],
"warnings_recognized": true
}
],
"pbs_snapshots": [
{
"namespace": "root",
"backup_type": "ct",
"backup_id": "9001",
"backup_time": "2026-06-09T14:18:33Z",
"size_bytes": 2518889256,
"owner": "felhom@pbs!n100",
"protected": false,
"encrypted": true,
"verify_state": "ok",
"verify_upid": "UPID:dooplex:00034582:5269BDD7:00000005:6A282176:verify:felhom-spike:felhom@pbs!n100:"
}
],
"cloudflared": { "status": "active" },
"audit_tail": [],
"capabilities": [],
"leaf_fingerprint": "60b5974d586f5f3c8ec41eb998d0f07406178219c36bf6d3ff377570279d8245",
"addresses": [
{ "iface": "vmbr0", "cidr": "192.168.0.162/24" }
],
"dr_recipe": {
"recipe_version": 1,
"guests": [
{ "vmid": 100, "cores": 2, "memory_bytes": 2147483648, "disk_bytes": 21474836480 }
],
"pbs": {
"repo_id": "felhom-pbs",
"namespace": "felhom-spike",
"namespace_state": "resolved",
"latest_snapshot_id": "9001"
},
"drives": [
{
"durable_id": "uuid:0fc63daf-8483-4772-8e79-3d69d8477de4",
"mount_path": "/mnt/usb-backup",
"intent": "enrolled",
"total_bytes": 2000000000000
}
],
"pve_storage": [
{ "name": "local-lvm", "type": "lvmthin", "content": "rootdir,images" },
{ "name": "usb-backup", "type": "usb", "content": "backup" },
{ "name": "felhom-pbs", "type": "pbs", "content": "backup" }
],
"backup_target": {
"state": "resolved",
"storage_id": "usb-backup",
"mount_path": "/mnt/usb-backup"
}
}
}