Install the OTA-Pulse Agent
The OTA-Pulse agent (soc-ota-agent) is the device-side component that polls the backend for pending deployments, downloads firmware artifacts, writes them to the inactive A/B partition, and reboots into the new image. It runs as a systemd service and is written in Go.
Three installation paths are supported:
| Method | When to use |
|---|---|
Yocto layer (meta-otapulse) | Greenfield or existing Yocto builds — the recommended production path |
Buildroot external tree (buildroot-otapulse) | Buildroot-based boards |
| Manual binary install | Quick device tests, development VMs, or any Linux device |
Yocto (meta-otapulse)
The meta-otapulse layer bakes the agent, its config directory, systemd unit, and identity/inventory scripts directly into your image.
Supported releases: Kirkstone (LTS) · Langdale · Mickledore · Nanbield · Scarthgap
-
Clone and add the layer
Terminal window cd /path/to/yocto/sourcesgit clone https://github.com/binaryblack/OTA-Pulse.git ota-pulse# Add to your buildbitbake-layers add-layer /path/to/ota-pulse/meta-otapulseOr add the path directly to
conf/bblayers.conf:BBLAYERS += "${BSPDIR}/sources/ota-pulse/meta-otapulse" -
Inherit the integration class in your image recipe
For standard images (rootfs < 1 GB):
# In your image recipe (e.g., my-image.bb)inherit otapulseFor large images (Qt, multimedia — rootfs > 1 GB):
inherit otapulse-largeWhat
inherit otapulsedoes automatically:- Adds
soc-ota-agentto the image - Enables
.menderartifact generation - Adds
ext4toIMAGE_FSTYPES - Includes partition tools (
gptfdisk)
- Adds
-
Set the OTA server URL in
conf/local.conf# Required: your OTA-Pulse backend URLOTA_SERVER_URL = "http://<your-server-ip>:8000"# Optional: pre-provision an API key (tenant token) into the imageOTAPULSE_TENANT_TOKEN = "smk_..."# Optional: enable artifact signature verification for productionSOC_OTA_SIGNATURE_VERIFICATION = "1"SOC_OTA_VERIFY_KEY_FILES = "production-rsa-public.pem production-ecdsa-public.pem" -
Build the image
Terminal window bitbake your-image# Output: tmp/deploy/images/<MACHINE>/your-image-<MACHINE>.mender -
Flash and verify
Terminal window # Flash the WIC imagesudo dd if=your-image-<MACHINE>.wic of=/dev/sdX bs=4M status=progress# After first boot, verify on the devicesystemctl status soc-ota-agentsoc-ota-agent show-artifact
Signing keys for production
The layer ships with placeholder development keys. For production you must supply your own keys.
Option A — Replace the example keys:
cp your-production-rsa-public.pem \ meta-otapulse/recipes-core/signing-keys/files/example-rsa-public.pemOption B — Point to your keys in local.conf:
SOC_OTA_VERIFICATION_KEYS = "/absolute/path/to/production-rsa-public.pem"Supported algorithms: RSA-4096 PSS/SHA-256 and ECDSA-P384 SHA-384.
Buildroot (buildroot-otapulse)
-
Configure Buildroot with the OTA-Pulse external tree
Terminal window cd /path/to/buildrootmake BR2_EXTERNAL=/path/to/OTA-Pulse/buildroot-otapulse menuconfig -
Enable the package
In the
menuconfiginterface navigate to:Target packages → OTA-Pulse → otapulseConfigure the required settings:
- OTA Server URL — URL of your OTA-Pulse backend
- Artifact Verification Public Key Path — path to your RSA-4096 public key (mandatory)
- Device Type Identifier — stable identifier for this board
-
Generate signing keys (required)
Signature verification is mandatory in the Buildroot package. Generate a key pair before building:
Terminal window # Generate RSA-4096 key pairopenssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:4096openssl rsa -pubout -in private.pem -out public.pemKeep
private.pemin your CI/CD secrets. Setpublic.pemas the value ofBR2_PACKAGE_OTAPULSE_VERIFY_KEY. -
Build
Terminal window makeExample defconfigs are available for quick starts:
Config Platform otapulse_qemu_aarch64_defconfigQEMU (testing) otapulse_rpi4_defconfigRaspberry Pi 4 otapulse_imx8_defconfigNXP i.MX8
Manual binary install
Use this method to install the agent on any running Linux device over SSH — useful for development VMs, boards already in the field, or testing without a full Yocto/Buildroot workflow.
Prerequisites
- Go 1.21+, GCC,
liblzma-dev,libssl-dev,libglib2.0-dev(build host only) - Target device: Linux with systemd, kernel 4.x+, A/B root partition layout
-
Build the agent on your host
Terminal window cd /path/to/OTA-Pulse/soc-ota-agentmake buildThis produces an
otapulsebinary. For cross-compilation:Terminal window GOOS=linux GOARCH=arm64 make build -
Copy the binary to the device
Terminal window scp otapulse user@<device-ip>:/tmp/ssh user@<device-ip> \"sudo install -m 0755 /tmp/otapulse /usr/bin/soc-ota-agent" -
Create the configuration directory and config file
Terminal window ssh user@<device-ip> "sudo mkdir -p /etc/otapulse"Place the following JSON at
/etc/otapulse/otapulse.confon the device (fill in your values):{"ServerURL": "http://<your-server-ip>:8000","TenantToken": "your-tenant-token","UpdatePollIntervalSeconds": 1800,"InventoryPollIntervalSeconds": 28800,"RetryPollIntervalSeconds": 300}Field Description ServerURLURL of the OTA-Pulse backend TenantTokenAPI key for device authentication (from the console under Settings → API Keys) -
Install and start the systemd service
Terminal window scp /path/to/OTA-Pulse/soc-ota-agent/support/soc-ota-agent.service \user@<device-ip>:/tmp/ssh user@<device-ip> \"sudo cp /tmp/soc-ota-agent.service /etc/systemd/system/ && \sudo systemctl daemon-reload && \sudo systemctl enable soc-ota-agent && \sudo systemctl start soc-ota-agent" -
Verify the agent is running
Terminal window # On the devicesystemctl status soc-ota-agentsoc-ota-agent show-artifactjournalctl -u soc-ota-agent -f
File locations
After installation, the agent uses the following paths regardless of install method:
| Path | Description |
|---|---|
/usr/bin/soc-ota-agent | Agent binary |
/etc/otapulse/otapulse.conf | Main configuration (JSON) |
/etc/otapulse/scripts/ | State scripts (update lifecycle hooks) |
/var/lib/otapulse/ | Runtime state and deployment log |
/usr/share/otapulse/identity/ | Device identity scripts |
/usr/share/otapulse/inventory/ | Inventory collection scripts |
Quick troubleshooting
| Symptom | Check |
|---|---|
| Service won’t start | sudo journalctl -u soc-ota-agent --no-pager — look for config parse errors |
| Cannot reach backend | curl http://<server-ip>:8000/health from the device |
| Authentication failures | Verify TenantToken in /etc/otapulse/otapulse.conf; check system clock (NTP) |
| State stuck | cat /var/lib/otapulse/deployment.log |
Next: Register your first device
With the agent installed and running, register it in the console.