Skip to main content
Documentation
Preview
You're viewing the Next docs — a rolling preview of in-development changes. The current release docs may differ.

Set Up Rugix OTA Updates

Enable the system update integration of Nexigon Agent in a Rugix image and prepare the release tooling for publishing update bundles. The agent installs bundles with Rugix Ctrl and reports progress through OTA update properties.

The integration combines Nexigon repositories for update bundles, properties for desired configuration and reported state, and events for update history. Rugix Ctrl provides bundle installation and boot-group management. The agent coordinates checks, installation, and commit handling, and implements holds, maintenance windows, retries, spread releases, and checkpoint releases.

You need a Rugix build project with Nexigon Agent configured and a Nexigon repository for releases. Follow Getting Started with Rugix if the image does not yet include Nexigon Agent.

Two packaging options are available depending on your build system:

  • Rugix Bakery: The nexigon-rugix repository provides ready-made Rugix recipes.
  • Yocto: The meta-nexigon repository provides Yocto layers, including meta-nexigon-rugix for Rugix-based systems and meta-nexigon-rauc for RAUC-based systems.

Setup with Rugix Bakery

The built-in updater requires a development build of Nexigon Agent. The released 0.6.x agent and the nexigon-rugix-ota recipe on the v0.3 recipe branch use the standalone update service. That service does not implement the policies described here.

Use the v0.3 recipes to install and configure the agent, but omit nexigon/nexigon-rugix-ota. Configure the built-in integration through extra_config instead.

rugix-bakery.toml
[repositories]
nexigon = { git = "https://github.com/nexigon/nexigon-rugix.git", branch = "v0.3" }

Obtain a development build that includes the system update integrations. In the following example, replace <development-build-tag> with the download tag of that build. The Rugix quickstart installs the current released agent, so it also needs this version override.

layers/customized.toml
recipes = [
    # ...
    "nexigon/nexigon-agent",
    "nexigon/nexigon-agent-config",
    "nexigon/nexigon-rugix-watchdog",
]

[parameters."nexigon/nexigon-agent"]
version = "<development-build-tag>"

[parameters."nexigon/nexigon-agent-config"]
extra_config = """
[commands]
enabled = true

[integrations.rugix.system-updates]
enabled = true
path = "my-repo/my-package/stable"
check-interval-secs = 14400
check-jitter-secs = 300
use-bundle-hash = false
"""

Merge this section into any existing extra_config value so that terminal, forwarding, and other settings are retained. The agent configuration recipe reads the connection credentials from the project’s .env file as described in the quickstart.

The path setting is optional. Without it, the agent does not update until dev.nexigon.ota.config supplies a path. This allows generic images to be paired and assigned an update channel after flashing.

The example checks every four hours, with up to five minutes of random jitter. System Updates lists all integration settings.

The nexigon-rugix-watchdog recipe reboots the device if the system has not been committed within its timeout, which defaults to 30 minutes. This allows the device to roll back to the previous version.

The Nexigon template for Rugix Bakery provides release scripts and CI integration for publishing bundles. When adapting it for the built-in updater, replace its standalone OTA recipe with the configuration above.

Setup with Yocto

Use the main branch of meta-nexigon to build a development version of Nexigon Agent with the system update integration.

Add the meta-nexigon-rugix layer to your build. The layer depends on meta-nexigon-core, which provides the Nexigon Agent recipes.

Include the agent configuration package in your image:

IMAGE_INSTALL:append = " nexigon-agent-conf"

This package installs Nexigon Agent, Rugix Ctrl, and the rollback watchdog. The layer enables the Rugix integration of the agent. Set NEXIGON_SYSTEM_UPDATES = "" to disable the integration and its runtime dependencies. Set the default update path through BitBake variables:

NEXIGON_OTA_REPOSITORY = "my-repo"
NEXIGON_OTA_PACKAGE = "my-package"
NEXIGON_OTA_TAG = "stable"

See the meta-nexigon README for all variables and the Kas example configurations for reference setups with both Rugix and RAUC.

Update Lifecycle

The agent checks for updates once it has connected to Nexigon Hub, then every check-interval-secs plus a random delay of up to check-jitter-secs, and immediately when the nexigon.ota.check command runs. On each check, the agent:

  1. Reads configuration. Applies dev.nexigon.ota.config over the defaults built into the image.
  2. Checks boot state. If the active boot group differs from the default, the agent commits the system to confirm that the update booted. If the device does not run the installed version, it records a rollback.
  3. Resolves the target version. Resolves the configured path and plans the next version, which is a checkpoint if the target requires one.
  4. Applies the policy. Waits while updates are on hold, the device’s turn in a spread release has not come, a retry is not yet due, or the maintenance window is closed.
  5. Installs the update. Downloads the Rugix bundle and installs it with rugix-ctrl update install.
  6. Reboots. Reboots into the new version with rugix-ctrl system reboot --spare.

Every state transition is published through the dev.nexigon.ota.status property, and installations and their outcomes are emitted as events in the ota category. This gives you real-time status in the Nexigon UI and a history of update events in the event log. The status also reports the version of Rugix Ctrl and its boot groups as slots. See OTA Updates for the update model.

Configuration

The path setting in [integrations.rugix.system-updates] selects the image’s default release. The Bakery example above tracks the stable tag of the my-package package in the my-repo repository. It also enables commands so that nexigon.ota.check can request an immediate update check.

This path is the image’s default update channel. The device property dev.nexigon.ota.config can override it without rebuilding the image. Removing the override restores the built-in default. Follow Deploy System Updates for the deployment procedure.

Bundle Verification

Rugix Ctrl verifies bundles before installation. The integration supports these verification inputs:

  • Cryptographic signature: Rugix Ctrl’s normal verification applies when no metadata hash is used. This is recommended for production deployments.
  • Hash-based verification: With use-bundle-hash enabled, the agent passes rugix.bundleHash from the asset metadata to Rugix Ctrl when present. When it is absent, verification falls back to the bundle signature.

The verification mode is set locally in the image and cannot be disabled with the cloud-provided OTA configuration. Hash verification ensures that the downloaded bundle matches metadata received through the authenticated Nexigon connection, but it is not an independent publisher signature. A party that can replace both the asset and its metadata remains trusted. Configure Rugix bundle signing and a device trust root for production publisher authentication.

Release Workflow

The Nexigon template for Rugix Bakery provides release scripts. For example, in a project based on the template:

./scripts/prepare-release.sh                      # Generate version, create in Nexigon Hub
./scripts/build-release.sh customized-efi-amd64   # Build with pinned version
./scripts/upload-release.sh                       # Upload artifacts with metadata

The prepare-release.sh script generates a version identifier (e.g., build-20260401120000-abc1234), creates the version in the Nexigon repository, and writes a .release-env file that pins the version for subsequent steps. This ensures the version baked into the image matches the version uploaded to the repository.

When adapting the scripts, preserve the release contract: the package version’s metadata.imageVersion identifies the version baked into the image, and each bundle is attached as <system-name>.rugixb. The updater selects the bundle for its system name and compares the image version with its installed version. The package version’s display name and a floating channel tag serve different purposes and do not replace that image-version metadata. The agent also resolves its installed version as a tag of the package, so keep the locked build tag that prepare-release.sh assigns.

To route devices through a checkpoint release, create later versions with the checkpoint as their base, for example with nexigon-cli repositories versions create <package-path> --base <checkpoint>.

Asset Metadata

The upload script attaches metadata to bundle assets:

{
  "rugix": {
    "bundleHash": "sha512-256:..."
  },
  "relations": {
    "sbom": ["customized-efi-amd64.spdx.json"]
  }
}
  • rugix.bundleHash: Passed to Rugix Ctrl when use_bundle_hash is enabled. Without a metadata hash, Rugix Ctrl uses its normal signature verification.
  • relations.sbom: Names the SBOM attachment of the same version. With vulnerability management, Nexigon indexes it to find known vulnerabilities in the version and on the devices running it.

CI Integration

The template includes a GitHub Actions workflow that runs the same scripts. The prepare-release job creates the version and uploads .release-env as a GitHub Actions artifact. Parallel build jobs download it, build each system variant, and upload the results.

Verify the Setup

Build and boot the configured image. Once Nexigon Agent is connected, confirm that the device reports dev.nexigon.ota.status in Nexigon, with the installed image version in currentVersion, the effective configuration in config, and Rugix Ctrl with the booted group in updater. Configure Updates on the device page shows the same status.

If the property is missing, confirm that Nexigon Agent is paired and inspect its log as root on the device:

journalctl -u nexigon-agent -b

Once the device is connected and a release is published, follow Deploy System Updates to select a version or channel, roll out the release, and monitor progress.