Commit Graph
53 Commits
Author SHA1 Message Date
Anand HegdeandGitHub 8613cfe548 feat: list pending package updates on the system page (#2427) 2026-09-27 11:27:13 -04:00
henrygd 24ec18a937 refactor(hub): decode each agent response into a new struct
The WebSocket path reused sys.data, and CBOR leaves omitted fields
untouched, so stale values carried over (e.g. Details re-saved every
poll, SystemdServicesUpdated stuck true, old map entries kept).

sys.data is now set only by the regular update for alerts. Removes the
Wi-Fi-only workaround in UnmarshalResponse.
2026-09-26 09:43:33 -04:00
henrygd 16e3fbadce store compact RSSI stats and skip real-time collection
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.
2026-09-25 18:02:34 -04:00
Vito CappelloandGitHub 86ab0fae8b feat: monitor connected Wi-Fi signal per interface (#2367) 2026-09-25 17:43:57 -04:00
Sven van GinkelandGitHub 4d10ea2e03 feat: add SYNC_SYSTEM_NAMES env var to sync system names with hostname (#1917) 2026-09-24 17:45:59 -04:00
a99fe5e997 feat: add TLS certificate expiry check to HTTPS network monitors (#2401)
Co-authored-by: henrygd <hank@henrygd.me>
2026-09-23 17:07:29 -04:00
henrygd 8bf6917fe0 fix: prevent WebSocket reconnect loops on slow agent collections (#2294)
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.
2026-09-23 11:21:51 -04:00
spatiumstasandGitHub 2d5ea3fa08 fix: preserve status alerts through pending recovery (#2375) 2026-09-22 19:14:54 -04:00
Sven van GinkelandGitHub 8047f005d4 fix(ui): preserve paused systems in network monitors table (#2391) 2026-09-22 18:40:46 -04:00
henrygd 187dc886a9 fix: resync network monitors after SSH reconnect and retry failed syncs 2026-09-18 23:49:54 -04:00
bb1b39928e feat: network monitoring from agents (#2266, #1911)
Co-authored-by: Sven van Ginkel <svenvanginkel@icloud.com>
Co-authored-by: xiaomiku01 <xiaomiku01@outlook.com>
2026-09-18 13:22:50 -04:00
f204dc17e6 feat(agent): Add docker image update available flag (#2211)
Co-authored-by: henrygd <hank@henrygd.me>
2026-09-10 19:39:40 -04:00
8d6a5d5f6e feat(agent): report btrfs filesystems as storage pools (#2315)
Co-authored-by: henrygd <hank@henrygd.me>
2026-09-09 19:53:39 -04:00
henrygd 98687be2f2 fix(hub): reject null systemd service entries to prevent hub panic 2026-09-08 10:08:33 -04:00
henrygd 997adc19bb fix: show idle GPU utilization in systems table (#2312) 2026-09-07 13:13:05 -04:00
henrygd 6cb302fcf6 fix(hub): bound realtime metric fetching and enforce access control by system
- synchronize realtime subscription state
- prevent overlapping fetches per system
- add realtime worker lifecycle tests
- reject subscriptions without system access
- test access revocation and shared-system permissions
2026-09-06 13:24:53 -04:00
5969d36856 feat(alerts): add container health alerts with log excerpt on notifications (#2225)
Add a new "ContainerHealth" alert type that fires when a Docker container's
health check reports unhealthy, and resolves when it recovers. This mirrors
the existing Status (up/down) alert pattern: an alert can be armed per system
and honors the "min minutes" delay before firing.

When the alert fires, the notification (email and any configured webhook,
including Discord via shoutrrr) includes a log excerpt fetched live from the
agent for up to 2 of the unhealthy containers, prioritizing lines containing
"error" or "fatal" (falling back to the log tail if none match), capped to
keep the message well under Discord's size limit.

---------

Co-authored-by: hank <hank@henrygd.me>
2026-09-02 12:46:23 -04:00
097180e8d7 feat(alerts): add alert for failed systemd services (#2173)
Adds a user-configurable "Failed Services" alert that notifies when any
tracked systemd service enters the failed state, and again when all services
recover.

---------

Signed-off-by: Martin Stenröse <martin@stenrose.se>
Co-authored-by: henrygd <hank@henrygd.me>
2026-09-01 20:41:48 -04:00
917d069ab3 feat: add ZFS monitoring (#2209)
- track pool capacity, health, I/O, scrub status, and vdev errors
- report dataset usage and correct ZFS filesystem metrics
- add pool charts, detail views, refresh controls, and health alerts
- persist pool details and include ZFS usage in disk alerts
- support configurable detail intervals and legacy agent compatibility

---------

Co-authored-by: hank <hank@henrygd.me>
2026-09-01 12:19:36 -04:00
Aditya Raj SinghandGitHub 3af6512514 fix(hub): don't read the SSH client after it is closed (#2277)
createSessionWithTimeout checked sys.client for nil and then dereferenced
it again inside the goroutine that calls NewSession. update() runs the
SMART fetch in its own goroutine, so closeSSHConnection can clear the
field between those two reads and the goroutine dereferences a nil
client, panicking the whole hub process.

Make client an atomic.Pointer, load it once before starting the
goroutine, and clear it with Swap so a concurrent close cannot be
observed mid-session-creation. NewSession on an already-closed client
returns an error, which the existing retry path already handles.

Closes #2157
2026-08-30 13:34:32 -04:00
henrygd 5f383c0eb1 fix(tests): stop system updaters on app termination 2026-08-17 12:32:34 -04:00
Sai Asish YandGitHub adaf6f338d systems: synthesize error when getRecord returns nil record (#1968) 2026-08-16 14:44:30 -04:00
eb5dd230cf fix(hub): remove stale smart_devices records when a drive is no longer reported (#2178)
* Fix duplicate /dev/sdg-style entries

* only prune devices after complete refreshes

---------

Co-authored-by: henrygd <hank@henrygd.me>
2026-08-15 13:40:30 -04:00
TowyTowyandGitHub c3a432101b fix(hub): re-dial SSH-pull agents when a connection silently dies (#2126)
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
2026-08-13 19:04:38 -04:00
Sven van GinkelandGitHub 9887b662ad fix(hub): refresh system details on agent reconnect ssh (#2086) 2026-08-11 18:08:18 -04:00
henrygd e3ade3aeb8 hub: optimize System.HasUser check 2026-04-10 18:32:37 -04:00
henrygd 0ae8c42ae0 fix(hub): System.HasUser - return true if SHARE_ALL_SYSTEMS=true (#1891)
- 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
2026-04-08 20:13:39 -04:00
henrygd ba10da1b9f hub: add additional validation checks for custom api routes
- 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.
2026-04-01 16:30:45 -04:00
henrygd ce5d1217dd fix(hub): cancel pending down status alert if system paused before alert sent 2026-03-31 14:08:44 -04:00
henrygd 9f19afccde hub: reset smart interval on agent reconnect if agent hasn't successfully saved smart devices
this is so people trying to get smart working can see the config changes immediately. not need to wait for the smart interval.
2026-03-29 12:30:39 -04:00
henrygd f25f2469e3 hub: add debug logs for smart behavior (#1800) 2026-03-28 21:16:26 -04:00
henrygd 5bd43ed461 hub: reset smart interval on agent reconnect if agent hasn't successfully saved smart devices
this is so people trying to get smart working can see the config changes immediately. not need to wait for the smart interval.
2026-03-28 20:47:16 -04:00
henrygd 35528332fd hub: fix possible nil pointer panic in realtime worker 2026-03-26 10:48:37 -04:00
henrygd e4e0affbc1 test(hub): add additional tests for all system alerts 2026-03-17 18:48:54 -04:00
henrygd 380d2b1091 add ports column to containers table (#1481) 2026-03-14 19:29:39 -04:00
henrygd b386ce5190 hub: add ExpiryMap.UpdateExpiration and sync SMART fetch intervals (#1800)
- Update smartFetchMap expiration when agent smart interval changes
- Prevent background SMART fetching before initial system details are
loaded
- Add buffer to SMART fetch timing check
- Get rid of unnecessary pointers in expirymap
2026-03-11 16:25:52 -04:00
henrygd e527534016 ensure deprecated system fields are migrated to newer structures
also removes refs to legacy load avg fields (l1, l5, l15) that were
around for a very short period
2026-03-10 18:46:57 -04:00
henrygd 35d0e792ad refactor(expirymap): optimize performance and add StopCleaner method 2026-03-08 19:09:41 -04:00
henrygd 654cd06b19 respect SMART_INTERVAL across agent reconnects (#1800)
Move tracking of the last SMART data fetch from individual System
instances to the SystemManager using a TTL-based ExpiryMap.

This ensures that the SMART_INTERVAL is respected even if an
agent connection is dropped and re-established, preventing
redundant data collection on every reconnect.
2026-03-08 19:03:50 -04:00
henrygd 04600d83cc refactor: small go 1.26 updates and go fix changes 2026-02-19 18:04:33 -05:00
henrygd 79ca31d770 improve container network stats granularity by using bytes instead of MB
Changes container network statistics to use raw byte values instead of converting to megabytes agent-side, providing more accurate measurements for low-bandwidth containers. Maintains backward compatibility with older agents/hubs through fallback logic.

- Agent now sends Bandwidth field as [sent_bytes, recv_bytes] array
- Deprecated NetworkSent/NetworkRecv fields still populated for compatibility
- Hub and frontend fall back to deprecated fields when Bandwidth is zero
- Record averaging correctly handles both old and new formats
- TODO markers added for cleanup in version 0.19+
2026-01-31 14:05:55 -05:00
henrygd 4547ff7b5d refactor: unify agent communication with Transport interface
- Introduce `Transport` interface to abstract WebSocket and SSH
communication
- Add generic `Data` field to `AgentResponse` for streamlined future
endpoints
- Maintain backward compatibility with legacy hubs and agents using
typed fields
- Unify fetch operations (SMART, systemd, containers) under a single
`request` method
- Improve `RequestManager` with deadline awareness and legacy response
support
- Refactor agent response routing into dedicated `agent/response.go`
- Update version to 0.18.0-beta.2
2026-01-05 13:13:55 -05:00
henrygd 7fff3c999a update changelog and comments 2025-12-19 16:27:39 -05:00
henrygd a9068a11a9 add SMART_INTERVAL env var with background smart data fetching 2025-12-19 16:14:31 -05:00
henrygd e59f8eee36 add system_details collection for infrequently updated data
- add includedetails flag to data requests for better efficiency
- integrate docker host info api for better os detection
- pull more OS details as well as cpu arch
- separate info bar component and refactor for new info
2025-12-18 17:26:05 -05:00
henrygd 41a3d9359f add dedicated S.M.A.R.T. page with persistent device storage
- Add /smart route to view SMART data across all systems
- Store SMART devices in new smart_devices collection
- Auto-fetch SMART data when system first comes online
- Add refresh/delete actions per device with realtime updates
- Add navbar and command palette entries
2025-11-30 13:32:37 -05:00
henrygdandShelby Tucker 01d20562f0 add basic systemd service monitoring (#1153)
Co-authored-by: Shelby Tucker <shelby.tucker@gmail.com>
2025-11-10 17:04:51 -05:00
henrygdandgeekifan 962613df7c Add initial S.M.A.R.T. support
- Implement SmartManager for collecting SMART data from SATA and NVMe drives
- Add smartctl-based data collection with standby mode detection
- Support comprehensive SMART attributes parsing and storage
- Add hub API endpoint for fetching SMART data from agents
- Create SMART table UI with detailed disk information

Co-authored-by: geekifan <i@ifan.dev>
2025-10-24 18:54:56 -04:00
henrygd dfd1fc8fda add image name to containers table (#1302) 2025-10-20 17:11:26 -04:00
henrygd 5360f762e4 expand container monitoring functionality (#928)
- Add new /containers route with virtualized table showing all containers across systems
- Implement container stats collection (CPU, memory, network usage) with health status tracking
- Add container logs and info API endpoints with syntax highlighting using Shiki
- Create detailed container views with fullscreen logs/info dialogs and refresh functionality
- Add container table to individual system pages with lazy loading
- Implement container record storage with automatic cleanup and historical averaging
- Update navbar with container navigation icon
- Extract reusable ActiveAlerts component from home page
- Add FooterRepoLink component for consistent GitHub/version display
- Enhance filtering and search capabilities across container tables
2025-10-18 16:32:16 -04:00