Installation
This guide will help you get rouser running on your Linux system within 5 minutes.
Prerequisites
- Linux system with systemd (systemd user instance)
- Your user logged in and active session (
loginctl enable-linger $USERrecommended for persistence after logout) - Rust 1.70+ (for building from source only — pre-built binaries available on releases)
- D-Bus session bus available
Installation Options
Option 1: Build from Source
# Clone repository
git clone https://github.com/owaindjones/rouser.git
cd rouser
# Build release binary and install to ~/.local/bin
cargo build --release
mkdir -p ~/.local/bin
cp target/release/rouser ~/.local/bin/rouser
chmod +x ~/.local/bin/rouser
Option 2: Via Installer Script (Recommended)
The installer script fetches the latest release, installs the binary, config, and enables systemd user service automatically:
curl -fsSL https://raw.githubusercontent.com/owaindjones/rouser/main/scripts/install.sh | bash
For safety, review or verify the script before running it:
curl -fSL -o install.sh https://raw.githubusercontent.com/owaindjones/rouser/main/scripts/install.sh
# Inspect: cat install.sh or sha256sum install.sh to record for future verification
bash install.sh
See scripts/install.sh --help for options.
Option 3: Manual Download from Release
Download pre-built archives from GitHub Releases matching your architecture:
# Update URL with actual release version and arch (x86_64 or aarch64)
curl -LO https://github.com/owaindjones/rouser/releases/download/v0.1.0/rouser-v0.1.0-linux-x86_64.tar.gz
# Extract — contains binary + config + systemd service file
tar -xzf rouser-v*.linux-*.tar.gz
# Install components manually:
cp rouser ~/.local/bin/rouser
mkdir -p ~/.config/rouser
cp config/rouser.toml ~/.config/rouser/config.toml
systemctl --user daemon-reload # if installing service file
Configuration
Config File Discovery
By default, rouser loads and merges multiple config sources (lowest → highest priority):
| Priority | Path | Description |
|---|---|---|
| 1 (lowest) | Embedded defaults | Compiled-in config/rouser.toml from the binary |
| 2 | /etc/rouser/config.toml |
System-wide user overrides |
| 3 (highest) | $XDG_CONFIG_HOME/rouser/config.toml or ~/.config/rouser/config.toml |
Per-user overrides |
Values in higher-priority configs override embedded defaults via deep merge: nested tables are merged field-by-field, scalars and arrays from user configs take precedence.
Auto-install Default Configs
On first startup (when no user config file exists), rouser automatically creates a default config:
- Root users → /etc/rouser/config.toml
- Non-root users → ~/.config/rouser/config.toml
An INFO log message is emitted on auto-install. Existing configs are never overwritten.
Create Configuration File
To manually create a user config, copy the embedded defaults:
mkdir -p ~/.config/rouser
rouser --print-config > ~/.config/rouser/config.toml
Or use --print-config to generate it from the merged configuration:
# Print final merged config (after auto-install of any missing files)
rouser --print-config
Example configuration:
update_interval = "5s"
log_level = "info"
[metrics.cpu]
per_core_threshold = 80.0 # Per-core CPU max usage % above which to inhibit sleep
total_threshold = 25.0 # Total averaged CPU usage % (default: 25.0)
[metrics.gpu]
threshold = 15.0 # GPU usage % per device (default: 15.0)
ema_alpha = 0.7 # EMA smoothing factor for GPU readings
[metrics.network]
threshold = 10.0 # Network throughput in Mbps (default: 10.0)
ema_alpha = 0.5 # EMA smoothing for network I/O
exclude_interfaces = ["lo"] # Exclude loopback from monitoring
include_interfaces = [] # Empty = monitor all interfaces
[metrics.disk]
threshold = 10.0 # Disk I/O in MB/s (default: 10.0)
ema_alpha = 0.5 # EMA smoothing for disk activity
exclude_device_prefixes = ["loop", "fd", "sr", "cdrom"] # Exclude virtual devices
[timing]
duration_threshold = "5s" # Min time metrics must exceed threshold before inhibiting (default: 5s)
cooldown_duration = "10s" # Time after releasing inhibition before re-inhibiting possible (default: 10s)
[inhibitor]
what = "shutdown:idle" # Lock types to inhibit (colon-separated). See D-Bus Inhibition docs for details.
mode = "block" # Inhibition mode: block, delay, or block-weak
See Configuration Reference for full option descriptions.
Testing Configuration
Validate Configuration
# Uses sequential default config search
rouser --validate-config
# With explicit path
rouser -c ~/.config/rouser/config.toml --validate-config
Dry Run Mode
Collect metrics and log readings without inhibiting sleep:
# Runs indefinitely until Ctrl+C
rouser --dry-run
# With debug logging to see per-device GPU readings
RUST_LOG=debug rouser -c ~/.config/rouser/config.toml --dry-run -l debug
Sample output in dry-run mode:
CPU max threshold: 80%, CPU avg threshold: 25%, EMA alpha: 0.70
GPU threshold: 15.0%, EMA alpha: 0.70
Network threshold: 10 Mbps, EMA alpha: 0.50
Disk threshold: 10 MB/s, EMA alpha: 0.50
Duration threshold: 5s
Cooldown duration: 10s
Running the Daemon
Manual Execution
# Run with default config search path
rouser
# Custom config path
rouser -c /path/to/config.toml
# Override log level at runtime
rouser -l debug --dry-run
The daemon runs indefinitely — press Ctrl+C to stop. When running as a systemd user service, use the service management commands below instead.
Systemd User Service (Recommended)
After testing with dry-run:
# Install and enable the user service (if not done by installer script)
systemctl --user daemon-reload
systemctl --user enable --now rouser.service
# Check status
systemctl --user status rouser
# View live logs
journalctl --user -u rouser -f
Service Management
systemctl --user start rouser # Start service
systemctl --user stop rouser # Stop service
systemctl --user restart rouser # Restart (after config change)
systemctl --user disable rouser # Disable auto-start on login
Verifying Inhibition
Check active sleep inhibitors:
# List all current inhibitors
loginctl list-inhibitors
# Or use systemd-inhibit
systemd-inhibit --list
When rouser is inhibiting, you should see an entry with description "rouser".
Quick Test
-
Start rouser in dry-run mode and verify metrics are collected:
bash RUST_LOG=debug rouser --dry-run -l debug 2>&1 | head -30 -
If inhibition works, you can temporarily lower the CPU threshold to
1to test: ```toml # In config.toml — set thresholds very low just for testing [metrics.cpu] per_core_threshold = 1.0 # Will trigger on any significant activity total_threshold = 1.0[timing] duration_threshold = "5s" # Short test window cooldown_duration = "10s" ```
Then run rouser and check loginctl list-inhibitors. Restore thresholds after testing.
Troubleshooting
Service Won't Start After Logout
Ensure logind lingering is enabled for your user:
loginctl enable-linger $USER
# Verify: loginctl show-user $USER | grep Linger
Without lingering, systemd only starts the service during active login sessions.
D-Bus Permission Errors
If rouser cannot acquire sleep inhibition:
- KDE Plasma: Add a polkit rule (see systemd user service docs)
- Check D-Bus session:
echo $DBUS_SESSION_BUS_ADDRESSshould be non-empty - Manual test:
systemd-inhibit --what=sleep --mode=block --description="Test" sh -c "sleep 5"— if this works but rouser doesn't, it's a config or threshold issue
Inhibition Not Working on KDE Plasma
KDE Powerdevil may ignore inhibitors from unprivileged users. Create /etc/polkit-1/rules.d/50-rouser.rules:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.login1.inhibit" &&
subject.user == "your_username") {
return polkit.Result.YES;
}
});
Then sudo systemctl restart polkit.
Debug Logging
Enable verbose logging to see per-device metric readings:
# In config.toml — log_level is at root level
update_interval = "5s"
log_level = "debug"
Or override via CLI (takes priority over config):
rouser --dry-run -l debug
Example Configurations
Home Server (low activity baseline)
update_interval = "10s"
log_level = "info"
[metrics.cpu]
per_core_threshold = 70.0
total_threshold = 50.0
ema_alpha = 0.3
[metrics.gpu]
threshold = 85.0
ema_alpha = 0.3
[metrics.network]
threshold = 50.0
ema_alpha = 0.2
exclude_interfaces = ["lo"]
[metrics.disk]
threshold = 30.0
ema_alpha = 0.2
exclude_device_prefixes = ["loop", "fd", "sr", "cdrom"]
[timing]
duration_threshold = "60s"
cooldown_duration = "120s"
[inhibitor]
what = "sleep:idle"
mode = "block"
Development Workstation (high activity tolerance)
update_interval = "5s"
log_level = "info"
[metrics.cpu]
per_core_threshold = 90.0 # Only inhibit during heavy compilation/builds
total_threshold = 70.0
ema_alpha = 0.3
[metrics.gpu]
threshold = 95.0 # Gaming or GPU workloads
ema_alpha = 0.3
[metrics.network]
threshold = 200.0 # Large downloads/uploads
ema_alpha = 0.2
exclude_interfaces = ["lo"]
[metrics.disk]
threshold = 100.0 # Heavy I/O builds or VM operations
ema_alpha = 0.2
exclude_device_prefixes = ["loop", "fd", "sr", "cdrom"]
[timing]
duration_threshold = "30s" # Shorter threshold for responsive inhibition
cooldown_duration = "60s"
[inhibitor]
what = "shutdown:idle:sleep:suspend" # Block all sleep types
mode = "block"
Next Steps
- Adjust thresholds based on your system's typical activity patterns (use
RUST_LOG=debugdry-run to baseline) - Review Configuration Reference for all available options and EMA smoothing details
- Read the full docs/ directory for metrics collection methods, inhibition flow, and security hardening
See Also
- Configuration Reference — Complete configuration options with defaults
- Command Line Arguments — CLI usage and environment variables
- Systemd User Service — Detailed service setup and troubleshooting
- Metrics Overview — How each metric type is collected