Skip to content

noderax/noderax-agent

Repository files navigation

Noderax

Noderax Agent

Noderax Agent is the Go-based node runtime for the platform. It enrolls a machine, opens the agent realtime socket, streams telemetry, claims tasks over HTTP long polling by default, and executes supported operations such as shell commands and package management.

Highlights

  • Enrollment-based node onboarding with approval tokens
  • One-click bootstrap installer for Ubuntu and Debian
  • Workspace-generated bootstrap tokens for the Add node flow
  • Installer-side live progress reporting back to the control plane during bootstrap
  • Background service support for Linux-based systems
  • Dedicated noderax runtime user for the service and remote operations
  • Built-in CLI for install, start, stop, restart, status, and config updates
  • Detached self-update command for official tagged agent releases
  • Realtime Socket.IO session for agent auth, metrics, and lifecycle signaling
  • HTTP long-poll task claiming as the primary execution path
  • Interactive terminal session support over the agent realtime socket
  • Heartbeat-based agent version, platform version, and kernel telemetry for fleet visibility
  • Graceful cancellation with log-drain timeout handling
  • Non-interactive execution environment with PAGER=cat and high COLUMNS
  • PTY shell fallback modes for hosts where the default controlling-TTY start path is restricted
  • Scheduled runs arrive as standard queued tasks, so no separate schedule runtime is required on the agent
  • Persistent node identity storage

Supported Platforms

  • Ubuntu and Debian hosts with systemd
  • Manual source-based execution on other developer environments

Quick Install

The preferred onboarding path is from the web dashboard:

  1. Open Nodes for the target workspace.
  2. Choose Add node.
  3. Fill in node metadata in step 1.
  4. Copy the generated install command from step 2.
curl -fsSL https://cdn.noderax.net/noderax-agent/install.sh | sudo bash -s -- --api-url https://api.example.com --bootstrap-token <token>

The installer:

  • checks and installs required packages
  • creates the noderax system user
  • grants passwordless sudo only for apt-get install/remove/purge
  • grants passwordless sudo to the dedicated /usr/local/libexec/noderax-agent-self-update helper used by fleet rollouts
  • downloads the correct prebuilt agent binary
  • bootstraps the node with the provided token
  • reports bootstrap progress back to the API so the web Add node modal can update live
  • installs and starts the background service automatically

One-Click Install Progress Stages

The bootstrap installer reports stage changes back to POST /api/v1/node-installs/progress while it runs.

Common stages:

  • installer_started
  • dependencies_installing
  • dependencies_ready
  • service_user_ready
  • binary_download_started
  • binary_downloaded
  • agent_bootstrapping
  • service_started

If any step fails, the installer reports failed so the web UI can stop waiting and show the error state.

R2 Release Automation

Agent release assets can be published to Cloudflare R2 automatically by the GitHub Actions workflow at .github/workflows/agent-release.yml.

Expected R2 object layout:

  • noderax-agent/install.sh
  • noderax-agent/releases/catalog.json
  • noderax-agent/releases/latest/noderax-agent-linux-amd64
  • noderax-agent/releases/latest/noderax-agent-linux-arm64
  • noderax-agent/releases/latest/SHA256SUMS
  • noderax-agent/releases/<version>/noderax-agent-linux-amd64
  • noderax-agent/releases/<version>/noderax-agent-linux-arm64
  • noderax-agent/releases/<version>/SHA256SUMS
  • noderax-agent/releases/<version>/release-manifest.json

Required GitHub secrets:

  • R2_ACCOUNT_ID
  • R2_ACCESS_KEY_ID
  • R2_SECRET_ACCESS_KEY
  • R2_BUCKET

R2_BUCKET must be the plain bucket name only. Do not use a URL or custom domain.

Correct example:

  • R2_BUCKET=noderax-assets

Incorrect examples:

  • R2_BUCKET=https://cdn.noderax.net
  • R2_BUCKET=https://<accountid>.r2.cloudflarestorage.com/noderax-assets

The workflow checks bucket existence before publishing. If you get NoSuchBucket, the most common reasons are:

  • R2_BUCKET is not the real bucket name
  • R2_ACCOUNT_ID belongs to a different Cloudflare account
  • the access key pair belongs to a different account than the bucket

Trigger behavior:

  • Pushes to main refresh install.sh and the latest binaries
  • Tags matching agent-v* publish a versioned channel, release-manifest.json, and the shared catalog.json, then also refresh latest
  • Manual runs can republish an existing tagged version through workflow_dispatch

The workflow builds Linux amd64 and arm64 binaries, injects version metadata into the Go binary, and uploads the artifacts directly to R2 through the S3-compatible endpoint.

Official tagged release notes come from CHANGELOG.md. The release workflow turns that file into:

  • the versioned CDN release-manifest.json
  • the shared releases/catalog.json
  • the GitHub Release body
  • the GitHub Release release-manifest.json asset used by API fallback

Installed Paths

Linux (systemd)

  • Binary: /opt/noderax-agent/noderax-agent
  • Symlink: /usr/local/bin/noderax-agent
  • Config: /etc/noderax-agent/config.json
  • State: /var/lib/noderax-agent/agent_identity.json
  • Service: /etc/systemd/system/noderax-agent.service
  • Runtime user: noderax
  • Sudoers: /etc/sudoers.d/noderax-agent

Non-Interactive Bootstrap From A Local Binary

If you already have the binary on the target host, you can run the same bootstrap flow without the shell installer:

sudo ./noderax-agent install --non-interactive --api-url https://api.example.com --bootstrap-token <token>

Manual Installation

1. Build the agent

go build -o noderax-agent ./cmd/agent

2. Prepare a config file

cp config.example.json config.json

Set at least:

  • api_url

Leave enrollment_token empty. The enrollment command will populate it.

3. Run enrollment

./noderax-agent enroll

The agent will:

  • ask for the enrollment email
  • call POST /api/v1/enrollments/initiate
  • save the returned token
  • poll GET /api/v1/enrollments/{token}
  • persist the approved nodeId and agentToken

4. Start the agent manually

./noderax-agent

Use a custom config path if needed:

NODERAX_CONFIG_FILE=/path/to/config.json ./noderax-agent

Service Management

sudo noderax-agent start
sudo noderax-agent stop
sudo noderax-agent restart
sudo noderax-agent status

Fleet Self-Update

Platform-admin fleet rollouts do not use shell.exec. They dispatch the dedicated agent.update task type, which hands off to the root-only helper below:

sudo /usr/local/libexec/noderax-agent-self-update --target-version 1.0.1 --target-id <rollout-target-id>

The managed updater:

  • fetches the official tagged release manifest from the CDN and falls back to the matching GitHub Release asset
  • selects the correct Linux amd64 or arm64 artifact
  • verifies the downloaded binary with SHA256
  • atomically replaces the managed binary and refreshes the symlink
  • reports progress back to the API
  • restarts noderax-agent.service
  • leaves final success confirmation to the next heartbeat, which must report the target version

Configuration Management

Show active config:

noderax-agent config show

Update config values:

sudo noderax-agent config set api_url https://api.example.com
sudo noderax-agent config set task_timeout 30s
sudo noderax-agent config set metrics_interval 15s
sudo noderax-agent config set log_level debug

Supported keys:

  • api_url
  • enrollment_token
  • node_id
  • agent_token
  • heartbeat_interval
  • metrics_interval
  • task_poll_interval
  • request_timeout
  • task_timeout
  • shutdown_timeout
  • realtime_enabled
  • realtime_ping_interval
  • realtime_queue_size
  • realtime_backoff_jitter
  • realtime_namespace
  • realtime_path
  • state_file
  • log_level

Task Delivery Model

The current default execution path is HTTP polling.

  • The agent long-polls POST /api/v1/agent/tasks/claim
  • A claimed task is acknowledged with accepted and started
  • Logs are appended through POST /api/v1/agent/tasks/:taskId/logs
  • Completion is posted to POST /api/v1/agent/tasks/:taskId/completed
  • Cancellation intent is checked through agent control polling

The agent realtime socket remains important for:

  • agent authentication
  • metrics streaming
  • lifecycle support
  • interactive terminal control and streaming
  • optional compatibility with API-side realtime task dispatch when explicitly enabled

Fleet visibility also powers update completion. A fleet rollout only completes after heartbeat telemetry confirms that the restarted node is actually running the requested tagged agent version.

Realtime Socket.IO v4

Typical realtime settings:

NODERAX_API_URL=https://<domain>
NODERAX_REALTIME_NAMESPACE=/agent-realtime
NODERAX_REALTIME_PATH=/socket.io/
NODERAX_REALTIME_PING_INTERVAL=2s
NODERAX_REALTIME_METRICS_INTERVAL=3s

Notes:

  • Auth is performed after socket connection with agent.auth
  • Namespace and Engine.IO path are configured separately
  • Startup performs a polling health-check against /socket.io/ before the full socket session is used

Common failure modes:

  • invalid URL input
  • tls/proxy handshake failure
  • namespace connect failure
  • auth error

Interactive Terminal Sessions

Interactive terminal sessions are not delivered through the HTTP task claim loop. They use the agent realtime socket directly.

Incoming control events:

  • terminal.start
  • terminal.input
  • terminal.resize
  • terminal.stop

Outgoing lifecycle events:

  • terminal.opened
  • terminal.output
  • terminal.exited
  • terminal.error

Implementation notes:

  • The agent opens a PTY-backed interactive shell rather than reusing the non-interactive task executor
  • Shell resolution tries $SHELL, /bin/bash, /bin/zsh, then /bin/sh
  • Unix PTY startup falls back across multiple modes:
    • pty+ctty
    • pty-no-ctty
    • pty-minimal
  • The terminal session environment sets TERM=xterm-256color and PAGER=cat
  • Output is chunked and flushed on a timer so the web console receives live updates without waiting for more keystrokes
  • On constrained hosts, fallback PTY modes may log reduced job-control capability while remaining usable
  • terminal.stop requests a remote shell shutdown, and the API applies a timeout fallback if the shell disappears without a final clean exit event

Task Execution Environment

The agent executes shell.exec tasks in a controlled non-interactive environment:

  • PAGER=cat
  • COLUMNS=100000
  • graceful cancellation with log drain timeout
  • scheduled tasks use the same execution path as manually queued tasks
  • when installed through the bootstrap installer, shell and package tasks run under the noderax user
  • shell.exec does not auto-elevate to root; it runs in the noderax user context by default
  • package operations can elevate through passwordless sudo -n, but only for apt-get install, apt-get remove, and apt-get purge
  • agent self-update can elevate through passwordless sudo -n, but only for the dedicated /usr/local/libexec/noderax-agent-self-update helper
  • ad-hoc root shell commands are intentionally out of scope for the bundled sudoers profile

For package listing on Debian/Ubuntu, the agent uses optimized dpkg -l parsing to return structured package metadata.

Project Structure

Verification

Recommended checks:

go test ./...
go vet ./...

Development

Run tests:

go test ./...

Build locally:

go build -o noderax-agent ./cmd/agent

Run in foreground:

cp config.example.json config.json
./noderax-agent enroll
./noderax-agent

Notes

  • Linux installation assumes systemd.

  • The managed service config path can be overridden with NODERAX_CONFIG_FILE.

  • API-side realtime task push is not the default control path; HTTP claiming should be considered the normal operating mode.

  • Interactive terminals are the main exception: they depend on the agent realtime socket being healthy.

  • When a node is put into maintenance mode from the control plane, the API stops assigning new work to that node while in-flight tasks are allowed to finish.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors