Skip to content

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 $USER recommended 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

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.

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

  1. Start rouser in dry-run mode and verify metrics are collected: bash RUST_LOG=debug rouser --dry-run -l debug 2>&1 | head -30

  2. If inhibition works, you can temporarily lower the CPU threshold to 1 to 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:

  1. KDE Plasma: Add a polkit rule (see systemd user service docs)
  2. Check D-Bus session: echo $DBUS_SESSION_BUS_ADDRESS should be non-empty
  3. 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

  1. Adjust thresholds based on your system's typical activity patterns (use RUST_LOG=debug dry-run to baseline)
  2. Review Configuration Reference for all available options and EMA smoothing details
  3. Read the full docs/ directory for metrics collection methods, inhibition flow, and security hardening

See Also