Stats.WiFi is now map[string]int8 (json "wf") holding only available
RSSI
readings; SSID and unavailable signals stay in Info.WiFi. Averages are
rounded to whole dBm.
Wi-Fi is collected only on the default 60s interval; real-time requests
reuse the last snapshot to avoid spawning osascript / dumping the BSS
cache every second.
- Let GPU Power Draw span full width when it's a lone card in the grid
- Split GPU charts into summary (power/engines) and per-GPU grids so
usage and VRAM charts stay paired side by side
When the root drive is also listed in EXTRA_FILESYSTEMS, its key is
taken before addPartitionRootFs runs. Returning false there sent the
agent to addLastResortRootFs, which picks the most active device and
could register a different drive as root, overwriting that drive's
extra entry. addPartitionRootFs has already resolved the root device,
so promote the existing entry to root instead.
addPartitionRootFs reported success even when addFsStat skipped the
registration because the I/O key was already in use, e.g. when the root
drive is also listed in EXTRA_FILESYSTEMS. hasRoot was then set without
any root filesystem, and the last-resort fallback never ran. addFsStat
now reports whether it registered the filesystem and addPartitionRootFs
propagates that.
Also uppercase the drive letter in windowsVolumeName so "c:" and "C:"
normalize to the same key.
filepath.Base is platform-dependent for a bare volume name: on Windows it
strips the "C:" specifier and returns "\", so every drive letter
normalizes to the same key. findIoDevice's exact match then returns
whichever disk.IOCounters entry the map yielded first, which registers the
root filesystem under a random drive. With EXTRA_FILESYSTEMS=D:,P: the
root disk disappears from the hub, and without it the root can be
registered under another drive's I/O device.
Normalize a bare volume specifier before taking a path base, and stop
taking a path base of the device in addPartitionRootFs, where it mangled
the value before findIoDevice could see it. registerFilesystemStats
already avoided this by only taking a base when the agent is not on
Windows.
Fixes#2417
- store checkupdates' private DB in the agent data dir, since
ProtectSystem=strict makes /tmp read-only
- sync the private DB every 12h and use `checkupdates -n` in between,
forcing a sync when the DB is missing so -n never reports a false 0
- set WaitDelay so a timed-out command can't hang on child processes
restartService only looked for beszel.service, but install-hub.sh installs
the unit as beszel-hub.service, so the restart was skipped on a standard
install and the hub kept running the old binary.
Try the installer's name first and keep beszel.service as a fallback for
hand written units. Same for the OpenRC branch.
The hub waited only 5s (the request manager default) for stats over
WebSocket and closed the connection on any error. On hosts where
`zpool list` stalls (seen on Proxmox, up to its 10s timeout), collection
exceeded that limit, so the hub sent a close (code 1000) and the agent
reconnected. The refresh ran every other cycle, which caused a
disconnect roughly every 2 minutes.
Hub:
- Wait up to 30s for WebSocket stats responses.
- Keep the connection open when a stats request times out; only close
it (and fall back to SSH) for other errors.
Agent:
- After the first collection, refresh `zpool list` pool stats and
`zfs list` dataset usage in the background and serve cached values
meanwhile, so a hung utility cannot delay the stats response.
- Allocate unused UID/GIDs instead of using 999
- Detect existing ID collisions and repair missing shadow entries
- Support userdel and deluser during uninstall
- Fix Docker group membership handling