The per-system updater reused an SSH client across ticks and ran the data
exchange with no deadline. If a connection went half-open (dead peer that
never sends RST/FIN) or an agent accepted the session but never wrote a
response, the read in fetchDataViaSSH blocked forever. Because
StartUpdater calls update() synchronously on its ticker, a blocked read
froze the whole per-system goroutine: the ticker's subsequent ticks were
dropped, no error was returned so the system stayed "up", and the agent
was never re-dialed until the hub process restarted.
Bound each SSH data exchange with sshOperationTimeout via runWithTimeout:
on timeout the connection is torn down (unwinding the blocked read) and a
retryable error is returned, so the next tick re-dials. Also enable TCP
keep-alive on dialed connections as a backstop for genuine network death.
Fixes#2041
CalculateCpuPercentLinux subtracted the stored previous counters from the
current ones without checking direction. When a stats response is processed
after a newer one for the same container, or an accounting counter resets,
the current total reads lower and the unsigned subtraction wraps to ~2^64
instead of going negative.
On the container counter that surfaces as the reported error, and the sample
is discarded along with the container's network stats:
cpu pct greater than 100: 1.15292150348562e+13
On the system counter it is quieter and worse: the wrapped value inflates the
divisor, so the percentage collapses toward zero and is stored as a healthy
sample rather than rejected. A synthetic rollback measures 2.7e-12 percent.
Both directions are now treated as a new baseline (0% for one sample), which
matches how the function already handles the first-run case.
CalculateCpuPercentWindows had the same unguarded subtraction and is fixed
the same way.
Fixes#2149
Co-authored-by: Ryan Chou <ryanchou1994@users.noreply.github.com>
Switch to localStorage, which is shared across all tabs/windows of the
same origin. Also clean up the stored entry and strip the callback URL
on both success and failure paths.
valibot's email() action uses a domain-label regex that disallows the
-- sequence, so Punycode ACE labels like xn--mnchen-3ya.de (the ASCII
form of münchen.de) are incorrectly rejected.
Switching to rfcEmail() applies the RFC 5321 domain-label pattern,
which allows hyphens within labels and therefore accepts both standard
and internationalized domain names.
Some enterprise NVMe drives (e.g. Dell Ent NVMe CM7 U.2) report capacity
via nvme_total_capacity instead of user_capacity.bytes in smartctl output.
The NVMe SMART parser now falls back to nvme_total_capacity when
user_capacity.bytes is zero.
- move hub's GetEnv function to new utils package to more easily share
across different hub packages
- change System.HasUser to take core.Record instead of user ID string
- add tests
- Validate the user is assigned to system in authenticated routes where
the user passes in system ID. This protects against a somewhat
impractical scenario where an authenticated user cracks a random 15
character alphanumeric ID of a system that doesn't belong to them via
web API.
- Validate that systemd service exists in database before requesting
service details from agent. This protects against authenticated users
getting unit properties of services that aren't explicitly monitored.
- Refactor responses in authenticated routes to prevent enumeration of
other users' random 15 char system IDs.
- System page tabs display option
- Remove very specific chart components (disk usage, container cpu, etc)
and refactor to use more flexible area and line chart components
- Optimizations around chart handling to decrease mem usage. Charts are
only redrawn now if in view.
- Resolve most of the react dev warnings
Co-authored-by: sveng93 <svenvanginkel@icloud.com>