Support exportfs output where network info appears on same line as path
(e.g. /srv/media/tv 192.168.0.0/16(...)) in addition to continuation
line format. Ensures all NFS exports are detected correctly.
Display NFS exports with ro/rw permissions and network ranges for better
visibility into share configuration. Support both smbd and samba-smbd
service names for SMB share detection across different distributions.
Filter NFS export options to show only key settings (rw/ro, sync/async)
instead of verbose option strings. Improves readability while maintaining
essential information about export configuration.
Fix NFS export display to show each export path only once instead of
once per client. Use HashMap to deduplicate by path and sort results
alphabetically. Remove IP addresses and client specifications from
display, showing only export paths with their options.
Prevents duplicate entries when a single export is shared with multiple
clients or networks.
Add sub-service display for NFS exports and SMB shares under their
respective services. NFS shows active exports from exportfs with
options. SMB shows configured shares from smb.conf with paths.
Increase disk operation timeouts to handle multiple drives:
- lsblk: 2s → 10s
- smartctl: 3s → 15s (critical for multi-drive systems)
- df: 2s → 10s
Prevents timeouts when querying SMART data from systems with multiple
drives (3+ data drives plus parity).
Simplify backup section header by removing the 'Repo' prefix and
displaying only the timestamp with status icon. Repository details
are still shown as sub-items below the timestamp.
Extended size formatting to handle repositories smaller than 1MB by displaying in kB units. Size display logic now cascades: kB for < 1MB, MB for 1MB-1GB, GB for >= 1GB.
Update agent to read nfs-backup.toml instead of legacy backup-status-*.toml
files. Add support for 'completed' status string used by backup script.
Changes:
- Read nfs-backup.toml from status directory
- Match 'completed' status as Status::Ok
- Simplify file scanning logic for single NFS backup file
Remove disk-based backup display and implement repository-centric view
with per-repo archive counts and sizes. Backup now uses NFS storage
instead of direct disk monitoring.
Changes:
- Remove BackupDiskData, add BackupRepositoryData structure
- Display format: "Repo <timestamp>" with per-repo details
- Show archive count and size (MB/GB) for each repository
- Agent aggregates repo data from backup status TOML files
- Dashboard renders repo list with individual status indicators
Implement event-driven rendering to dramatically reduce CPU usage.
Only render when something actually changes instead of constantly
rendering at 20 FPS.
Changes:
- Increase poll timeout from 50ms to 200ms (5 FPS)
- Add needs_render flag to track when rendering is required
- Trigger rendering only on: user input, new metrics, heartbeat
checks, or terminal resize events
- Reset render flag after each render cycle
Based on cm-player optimization approach.
Skip the first line in tailscale status output which is always the
current host showing as idle. Add additional hostname check to prevent
showing the current host in the peer list. Only display actual remote
peers with their connection methods.
Replace JSON parsing with simpler text output parsing from tailscale
status command. The text format clearly shows hostname and connection
method (direct/relay/idle) making detection more reliable.
Fixes issues with incorrect hostname (localhost instead of actual name)
and incorrect connection method detection (showing relay when actually
using direct connection).
Replace single connection method display with individual sub-service
rows for each online Tailscale peer. Each peer shows hostname and
connection type (direct, relay, or idle) allowing monitoring of all
connected devices and their connection quality.
Query tailscale status --json to enumerate all online peers and display
each as a separate sub-service under tailscaled.
Fix service selection scrolling to prevent selector bar from being
hidden by "... X more below" message. When scrolling down, position
selected service one line above the bottom if there's content below,
ensuring the selector remains visible above the overflow message.
Remove unused get_zmq_stats method and service_type field to eliminate
compilation warnings and dead code.
Add connection_method field to NetworkInterfaceData to track whether
Tailscale is using direct P2P, DERP relay, or HTTP proxy connections.
The connection method is displayed as a sub-service under tailscaled
service, following the same pattern as VPN routes and firewall ports.
Query tailscale status --json to determine active connection type and
display as informational sub-service when tailscaled is active.
- Add mouse click support for hostname selection in title bar
- Fix right-aligned hostname position calculation
- Add mouse scroll support for both panels
- Add mouse click to select service rows
- Add right-click popup menu for service actions (Start/Stop/Logs)
- Add hover highlighting for popup menu items
- Improve terminal resize crash protection with 90x15 minimum size
- Add "Host:" prefix and separators to status bar
- Move NixOS metrics from system panel to status bar
- Change "... X more below" indicator to use border color
- Remove service name from popup menu title
Update monitoring to handle multiple simultaneous torrent copy operations
using the new directory-based marker structure.
Changes:
- Rename get_active_torrent_copy() to get_active_torrent_copies()
- Read all marker files from /tmp/torrent-copy/ directory
- Return Vec<String> instead of Option<String> for multiple copies
- Display each active copy as separate sub-service
- Unsanitize filenames by replacing _ with /
This enables monitoring when multiple torrents finish simultaneously
and are being copied in parallel to permanent storage.
Add real-time monitoring of torrent copy operations when completed
downloads are copied from SSD to HDD storage.
Changes:
- Add marker file tracking during rsync operations
- Monitor active copy operations via /tmp/torrent-copy-active
- Display copy status as sub-service under openvpn-vpn-download
- Show currently copying torrent name in dashboard
The copy status appears as an informational sub-service while rsync
is actively copying completed torrents to permanent storage, providing
visibility into potentially long-running file transfer operations.
Run sudo nft directly without timeout wrapper to preserve capabilities.
The timeout -> sudo chain was preventing nft from accessing netlink
with proper permissions.
- Change from 'timeout 3 sudo nft' to 'sudo nft'
- Allows CAP_NET_ADMIN to pass through correctly
- Update version to v0.1.256
Use explicit path /run/current-system/sw/bin/nft to match sudoers
configuration. Previously using 'nft' without path was resolving to
wrong location and failing permission checks.
- Change from 'sudo nft' to 'sudo /run/current-system/sw/bin/nft'
- Matches sudoers entry for passwordless execution
- Update version to v0.1.255
Change CPU load status to use load_5min instead of load_1min for more
stable status reporting. 5-minute average smooths out temporary spikes
and provides better indication of sustained load.
- Change load_status calculation from load_1min to load_5min
- Add comment explaining use of 5-minute average for stability
- Update version to v0.1.254
- Log exit status code when nft command fails
- Log stderr output to diagnose issues
- Distinguish between command execution failure and non-zero exit
- Update version to v0.1.253
Consolidate VPN-related information under openvpn-vpn-download service.
Now shows both VPN route and torrent statistics as sub-services.
- Remove route from openvpn-vpn-connection
- Add route to openvpn-vpn-download (displayed first)
- Torrent stats displayed second
- Update version to v0.1.251
Change nftables port parser to specifically look for 'chain input_wan'
instead of any chain with 'input' in the name. This ensures we only
collect WAN/external ports, not LAN or other internal chains.
- Look for 'chain input_wan' specifically
- Remove internal network filters (no longer needed)
- Update version to v0.1.249
Update nftables port collector to use sudo when querying ruleset.
Requires corresponding sudoers configuration in NixOS.
- Change nft command to use sudo
- Update version to v0.1.248
Display open external ports from nftables firewall rules as sub-services
grouped by protocol. Only shows WAN incoming ports by filtering input chain
rules and excluding private network sources.
- Parse nftables ruleset for accept rules with dport in input chain
- Filter out internal network traffic (192.168.x, 10.x, 172.16.x, loopback)
- Extract single ports and port sets from rules
- Group and display as "TCP: 22, 80, 443" and "UDP: 53, 123"
- Update version to v0.1.247
Update collector to use qBittorrent Web API instead of Transmission RPC.
Query qBittorrent through VPN namespace using existing passwordless sudo
permissions for ip netns exec commands.
- Change service name from transmission-vpn to openvpn-vpn-download
- Replace get_transmission_stats() with get_qbittorrent_stats()
- Use curl through VPN namespace to access qBittorrent API at localhost:8080
- Parse qBittorrent JSON response for state, dlspeed, upspeed
- Count active torrents (downloading, uploading, stalledDL, stalledUP)
- Update version to v0.1.246
Change docker images to use name field for all data instead of metrics,
matching the pattern used by torrent stats and VPN routes. Increase display
width for Status::Info sub-services from 18 to 50 characters to accommodate
longer informational text without truncation.
- Docker images now show: "image-name size: 994.0 MB" in name field
- Torrent stats show: "17 active, ↓ 2.5 MB/s, ↑ 1.2 MB/s" in name field
- Remove fixed-width padding for Info status sub-services
- Update version to v0.1.245
Implement aggregate torrent statistics display for transmission-vpn service
via Transmission RPC API. Shows active torrent count and total download/upload
speeds. Change VPN route label from "ip:" to "route:" for clarity.
- Add get_transmission_stats() method to query Transmission RPC
- Display format: "X active, ↓ MB/s, ↑ MB/s"
- Update version to v0.1.244
- Remove ZMQ stats display from system widget
- Remove update_zmq_stats method
- Remove zmq_packets_received and zmq_last_packet_age fields
- Clean up display to only show essential information
- Handle 12th/13th Gen Intel format (e.g., "12th Gen Intel(R) Core(TM) i7-12700K")
- Extract full model including suffix (i7-12700K instead of truncated name)
- Simplify pattern matching logic
- Reduce fallback truncation to 15 chars
- Parse Intel models (i3/i5/i7/i9-XXXX) from full name
- Parse AMD Ryzen models (Ryzen X XXXX) from full name
- Display format: "i7-9700 (8 cores)" instead of full CPU name
- Reduces CPU section width significantly
- Collect CPU model name and core count from /proc/cpuinfo
- Only collect once at startup (check if fields already set)
- Display below C-state row in dashboard CPU section
- Move CPU info collection from NixOS collector to CPU collector
Docker images now use Status::Info like VPN IP.
No "D" prefix, no status icon - just name and metrics.
All informational sub-services handled consistently.
Version: v0.1.239
Agent uses Status enum to control display:
- Status::Info: no icon, no status text (VPN IP)
- Other statuses: icon + text (containers, nginx sites)
Dashboard checks status, no hardcoded service_type exceptions.
Version: v0.1.237
Display VPN external IP as sub-service under openvpn-vpn-connection.
Query external IP through openvpn-namespace using curl ifconfig.me.
Version: v0.1.232
Collectors now clear their target vectors (tmpfs, drives, pools, services)
before populating to prevent duplicates when updating cached AgentData.
- Clear tmpfs list in memory collector
- Clear drives and pools in disk collector
- Clear services in systemd collector
- Bump version to v0.1.231
CRITICAL FIX: Collectors now update cached AgentData instead of
creating new empty data each cycle. This prevents the dashboard
from seeing flashing/disappearing data.
- Add cached_agent_data field to Agent struct
- Update cached data when collectors run
- Always broadcast the full cached data every 2s
- Only individual collectors respect their intervals
- Bump version to v0.1.230
Collectors now respect their configured intervals instead of running
every transmission cycle (2s). This prevents disk SMART checks from
running every 2 seconds, which was causing constant disk activity.
- Add TimedCollector wrapper with interval tracking
- Only collect from collectors whose interval has elapsed
- Disk collector now properly runs every 300s instead of every 2s
- Bump version to v0.1.229
Replace hardcoded terminal width thresholds with dynamic calculation
based on actual column requirements. Column visibility now adapts
correctly at 58, 52, 43, and 34 character widths instead of the
previous arbitrary 80, 60, 45 thresholds.
- Add width constants for each column (NAME=23, STATUS=10, etc)
- Calculate cumulative widths dynamically for each layout tier
- Ensure header and data formatting use consistent width values
- Fix service name truncation to respect calculated column width
Service panel now dynamically shows/hides columns based on terminal width:
- ≥80 chars: All columns (Name, Status, RAM, Uptime, Restarts)
- ≥60 chars: Hide Restarts only
- ≥45 chars: Hide Uptime and Restarts
- <45 chars: Minimal (Name and Status only)
Improves dashboard usability on smaller terminal sizes.