agent-smith-go

module
v1.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: GPL-3.0

README

Agent Smith

Test Coverage Lint CodeQL Release

Rewst's lean, open-source command executor that fits right into your Rewst workflows. See community corner for more details.

Installation

Agent Smith runs as a system service on Windows, Linux, and macOS. Installation involves configuring the agent with your organization credentials and starting the service.

Prerequisites
  • A Rewst organization ID
  • Configuration URL and secret from your Rewst platform
  • Administrative/root privileges for service installation
Basic Installation
  1. Download the appropriate binary for your platform from the releases page
  2. Configure the agent with your organization credentials:

Windows:

rewst_agent_config.win.exe --org-id YOUR_ORG_ID --config-url CONFIG_URL --config-secret CONFIG_SECRET

Linux/macOS:

./rewst_agent_config.linux.bin --org-id YOUR_ORG_ID --config-url CONFIG_URL --config-secret CONFIG_SECRET
# or
./rewst_agent_config.mac-os.bin --org-id YOUR_ORG_ID --config-url CONFIG_URL --config-secret CONFIG_SECRET
Configuration Options
  • --logging-level: Set logging verbosity (info, warn, error, debug)
  • --syslog: Write logs to system log instead of file (Linux/macOS)
  • --disable-agent-postback: Disable agent postback
  • --no-auto-updates: Disable auto updates
  • --mqtt-qos: MQTT subscription QoS level (0 = at-most-once, 1 = at-least-once, 2 = exactly-once). Defaults to 1 when omitted.

Example with optional parameters:

./rewst_agent_config --org-id YOUR_ORG_ID --config-url CONFIG_URL --config-secret CONFIG_SECRET --logging-level info --syslog --disable-agent-postback --no-auto-updates --mqtt-qos 1

Update

Once installed, the agent can be updated and configured using the config executable. The optional parameters are also available.

./rewst_agent_config --org-id YOUR_ORG_ID --update --logging-level info --syslog --disable-agent-postback --no-auto-updates --mqtt-qos 1

Service Mode

Once configured, the agent can run in service mode using the generated configuration:

./rewst_agent_config --org-id YOUR_ORG_ID --config-file /path/to/config.json --log-file /path/to/agent.log

Diagnostic Mode

The diagnostic mode provides an interactive menu to validate an installed agent without needing to inspect log files or know platform-specific service commands. It is useful for troubleshooting connectivity issues, verifying permissions, and confirming the agent is healthy.

Usage

Run without an org ID to scan all installed agents:

Windows:

rewst_agent_config.win.exe --diagnostic

Linux:

sudo ./rewst_agent_config.linux.bin --diagnostic

macOS:

sudo ./rewst_agent_config.mac-os.bin --diagnostic

To target a specific organization directly:

./rewst_agent_config --org-id YOUR_ORG_ID --diagnostic
Interactive menu

Once launched, the menu guides you through the following checks:

[1] Scan installed agents and check status
[2] Test command execution
[3] Test MQTT/WebSocket connectivity
[4] Test temp directory write access
[5] View live log data
[6] Run all checks
[0] Exit
Option What it checks
1 Lists all installed agents with running/stopped status and config details (device ID, IoT Hub, engine host, log level)
2 Runs a test command using the platform shell (PowerShell on Windows, Bash on Linux/macOS) and confirms execution succeeds
3 Attempts TLS connections to the agent's IoT Hub on port 8883 (MQTT) and port 443 (WebSocket). Prints troubleshooting tips if both fail
4 Creates a test file in the scripts temp directory and reads it back to confirm write access
5 Opens the agent log file and tails it in real time. Press Ctrl+C to stop
6 Runs checks 1–4 in sequence
Example output
  ╔══════════════════════════════════════════════════╗
  ║         Agent Smith Diagnostic Mode              ║
  ║         Version: v1.1.0                          ║
  ║         Platform: windows/amd64                  ║
  ╚══════════════════════════════════════════════════╝

  ── Installed Agents ──

    [PASS] a1b2c3d4-... - RUNNING (RewstRemoteAgent_a1b2c3d4-...)
      Device ID:    device-xyz
      IoT Hub:      abc123.azure-devices.net
      Engine Host:  engine.rewst.io
      Log Level:    info
      Syslog:       false
      Auto-Updates: true
      MQTT QoS:     1

  ── MQTT/WebSocket Connectivity ──

    Host: abc123.azure-devices.net
    Testing MQTT (TLS port 8883)... OK
    [PASS] MQTT TLS connection to abc123.azure-devices.net:8883
    Testing WebSocket (port 443)... OK
    [PASS] WebSocket connection to abc123.azure-devices.net:443

Uninstallation

To remove Agent Smith from your system:

# Replace with your organization ID
./rewst_agent_config --org-id YOUR_ORG_ID --uninstall

This will stop the service, remove configuration files, and clean up system service registrations.

Features

  • Cross-platform: Runs on Windows, Linux, and macOS
  • Secure: Uses Azure IoT Hub MQTT for encrypted communication
  • Extensible: Plugin system for custom notifications and integrations
  • Reliable: Automatic reconnection and error handling
  • Lightweight: Minimal resource footprint

How It Works

  1. Agent connects to your Rewst organization via Azure IoT Hub MQTT
  2. Receives command execution requests from Rewst workflows
  3. Executes commands using PowerShell (Windows) or Bash (Unix/Linux/macOS)
  4. Returns results back to the Rewst platform
  5. Supports system information collection and custom plugins
Message Delivery Guarantee

Incoming messages are handed to a buffered queue drained by a pool of command-execution workers. When that queue fills (a burst of commands, or execution slow enough to keep every worker busy), the subscribe callback applies back-pressure instead of dropping the message: it blocks until a worker frees a slot. Because the agent subscribes at QoS 1 (at-least-once) by default and the MQTT client only acknowledges a message after the callback returns, a saturated agent stops acknowledging — so the broker holds and later redelivers the command rather than the agent silently discarding it. This trades a small amount of in-broker buffering for no silent command loss.

The only case where a message is discarded is when it arrives while a connection cycle is tearing down (service stop or reconnect). The connection is going away regardless, so at QoS ≥ 1 the broker redelivers on the next connection. These drops are surfaced loudly — an Error log line, a cumulative dropped-message counter, and a best-effort AgentMessageDropped plugin notification — rather than a single warning, so they are observable in monitoring.

Tuning queue capacity and concurrency

Two optional fields in the device configuration file let high-volume deployments tune the queue without code changes:

Config key Default Description
worker_count 10 Number of concurrent command-execution workers draining the queue.
message_queue_size 100 Capacity of the buffered inbound message queue before back-pressure begins.

Both fall back to their defaults when omitted or set to a non-positive value. Raising message_queue_size absorbs larger bursts before back-pressure begins; raising worker_count widens execution parallelism. Example snippet:

{
  "worker_count": 25,
  "message_queue_size": 500
}
Command Result Delivery

After a command runs, the agent posts its result back to the Rewst engine with retry and exponential backoff. If every in-line attempt fails (network error or 5xx across the whole retry budget), the result is not dropped:

  • The failure is surfaced beyond the log with a best-effort AgentPostbackFailed:<post_id> plugin notification so monitoring can observe it.
  • The result is written to a bounded on-disk spool (under the agent's data directory) and re-attempted on the next successful connection cycle. A transient engine outage therefore recovers automatically once connectivity returns, instead of losing the result.

The spool is bounded by count and age (the oldest/expired entries are evicted) so it cannot grow without limit, and the flush is bound to the connection cycle so it never blocks shutdown.

The in-line retry budget is tunable per deployment:

Config key Default Description
postback_max_attempts 3 Total postback attempts (including the first try) before the result is spooled.
postback_base_retry_backoff_seconds 1 Base delay for exponential backoff between attempts (base * 2^(n-2)).

Both fall back to their defaults when omitted or set to a non-positive value, so existing configurations are unaffected. Example snippet:

{
  "postback_max_attempts": 6,
  "postback_base_retry_backoff_seconds": 2
}

Build

Required tools and packages:

  • commitizen: To use a standardized description of commits.

    pipx ensurepath
    pipx install commitizen
    pipx upgrade commitizen
    
  • go-winres: To embed icons and file versions to windows executables.

    go install github.com/tc-hib/go-winres@latest
    

Run the following command using powershell or pwsh to build the binary:

./scripts/build.ps1

Testing and Coverage

Agent Smith maintains high code quality through comprehensive testing with an 80% coverage threshold.

Running Tests

Run all tests:

go test ./...

Run tests with verbose output:

go test ./... -v

Run tests for a specific package:

go test ./cmd/agent_smith -v
go test ./internal/service -v
go test ./plugins -v

Run a specific test:

go test ./cmd/agent_smith -v -run TestLoadConfig
Coverage Reports

Generate coverage report:

./scripts/coverage.ps1

This script:

  • Runs tests across all packages
  • Generates coverage profiles
  • Enforces 80% minimum coverage threshold

Note: When running tests locally on Linux, some tests write to /tmp/rewst_remote_agent/scripts. If that directory was created by root (e.g., via sudo), your user won't have write access. Fix it by running:

sudo chmod -R o+w /tmp/rewst_remote_agent
Test Categories

Unit Tests: Test individual functions and components in isolation

  • Message parsing and validation
  • Configuration loading
  • SAS token generation
  • Path resolution

Integration Tests: Test component interactions

  • MQTT message flow (with test broker)
  • Service lifecycle (start/stop/restart)
  • Plugin loading and notifications
  • Command execution and postback

Platform-Specific Tests: Test OS-specific functionality

  • Windows service management
  • Linux systemd integration
  • macOS launchd integration
  • System information collection
Writing Tests

When contributing new code, ensure:

  1. Test coverage: Aim for >80% coverage for new code
  2. Table-driven tests: Use for multiple test cases
    tests := []struct {
        name     string
        input    string
        expected string
    }{
        {"case1", "input1", "expected1"},
        {"case2", "input2", "expected2"},
    }
    
  3. Clean up resources: Use t.TempDir() and defer statements
  4. Avoid flaky tests: Use proper synchronization and timeouts
  5. Mock external dependencies: Don't rely on network or filesystem in unit tests
CI/CD

Tests run automatically on:

  • Every pull request
  • Every push to main branch
  • Pre-release validation

GitHub Actions Workflows:

  • .github/workflows/test.yml - Runs test suite
  • .github/workflows/coverage.yml - Validates coverage threshold

Pull requests must:

  • ✅ Pass all tests
  • ✅ Maintain ≥80% coverage
  • ✅ Pass all linters
  • ✅ Pass CodeQL security scanning

Code Quality and Linting

Agent Smith uses golangci-lint for strict security and code formatting enforcement.

Running Locally
Install golangci-lint:

See this guide to learn how to install golangci-lint on your local machine.

Run linter:
golangci-lint run
Auto-fix formatting:
golangci-lint run --fix
CI/CD

Linting runs automatically on:

  • Every pull request
  • Every push to main branch

Contributing

Contributions are always welcome. Please submit a PR!

Please use commitizen to format the commit messages. After staging your changes, you can commit the changes with this command.

cz commit

License

Agent Smith is licensed under GNU GENERAL PUBLIC LICENSE. See license file for details.

Directories

Path Synopsis
cmd
agent_smith command
internal
interpreter
go build:linux
go build:linux

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL