Introducing pv-mqtt-sdk: MQTT Support in the Hub API

We are excited to announce pv-mqtt-sdk, the new Pantacor Hub agent for Pantavisor devices, together with MQTT support in the Hub API.

Instead of polling the Hub, your devices now stay permanently connected over MQTT: updates arrive the moment they are posted, the device stays reachable for commands, live logs and web SSH, and REST takes over automatically whenever the broker cannot be reached.

The Problem

The Hub’s device API has so far been HTTP-only. Devices polled for new revisions on an interval, so updates landed minutes late, the device’s online state depended on those polls, and interactive features (remote commands, streaming logs, an SSH session from your browser) had no good place to live.

The Solution: an MQTT message plane, with REST as the fallback

pv-mqtt-sdk runs in a container on the device and connects it to the Hub over MQTT 3.1.1 on wss://<hub>/mqtt/: a persistent session with the device id as client id, subscribed to steps/new, user-meta and commands under ph/v1/dev/<device-id>/, liveness published retained on status with an offline will, and token renewals that do not drop the connection. Push is the primary path — but every pending step is also reconciled over REST on every reconnect, and a device that cannot reach the broker falls back to REST polling, so updates are never lost either way.

What you get

Feature What it does
Updates Revisions pushed over MQTT are downloaded (resumable, sha256-verified) and installed in order through pv-ctrl; every phase, reboot and verdict is reported back to the Hub.
Metadata user-meta is applied to pantavisor live; device-meta is forwarded as a diff, with the agent’s pantavisor.sdk.* keys.
Commands An allowlist the device enforces: reboot, garbage collection, SSH on/off, and listings of containers, groups, daemons, drivers, wakelocks and the xconnect graph.
Live logs Log files streamed to the Hub on demand, filtered on the device, bounded in rate and time.
Web SSH A browser SSH session to the device’s own SSH server, end-to-end encrypted, relayed over the MQTT connection (prototype).
Claim & identity Registers or adopts pantavisor’s identity, is claimed the moment the owner does it, supports TLS owner verification, renews its token without dropping the connection.

Safe updates, including connectivity rollback

Objects download into /storage/objects, resumable with HTTP Range across restarts, sha256-verified, and installed with renames so they appear whole or not at all. Revisions install strictly in order; pantavisor’s own progress (installing, TESTING, DONE, ERROR with its reason) is relayed to the Hub across the reboots the update causes.

Why connectivity rollback belongs to the agent

With pv-mqtt-sdk, pantavisor no longer manages the device’s connection to the Hub: the agent does. The connectivity validation used to be pantavisor’s job — its own Hub client rolled a remote update back when the device could not reach the Hub — and with that client switched off, a revision the agent installs that cannot reach the Hub would simply sit in TESTING while the Hub keeps believing the device runs it. The agent therefore takes that validation over, with its own algorithm:

  • Before installing anything new, it pins the running revision: its state and hard links to its objects, so the garbage collector cannot collect its way back.
  • During TESTING in two steps, the new revision first has to get a network (a default route, an address, the Hub’s name resolving), then reach the Hub. Each step is judged against a budget learnt from the device itself: for its last 5 good boots, the agent records how long the network took to come up and the Hub took to answer, and gives the revision 3 times those medians. So a slow board that needs minutes for Wi-Fi is not rolled back for being slow, and one bad boot does not widen every later window.
  • The Hub budget only counts on a stable network — one usable in at least 80% of the checks. On one, an unreachable Hub is the revision’s doing; a network that keeps coming and going is degraded, and the revision gets the two budgets together.
  • When the window closes with no Hub, the revision’s pantavisor progress is rewritten to ERROR with the reason (“no network within 15m0s of testing (no address on wlan0)”, “network up for 2m10s, api.pantahub.com unreachable after 5 attempts”), and the previous revision runs again. Meanwhile further installs and RUN_GC are refused, and only the revision the agent installed is ever rolled back.

Getting started

Add the agent to a device with one revision, no reflash:

1. Download and merge the container

Prebuilt container exports are available under the Containers section at pantavisor.io/downloads (select channel release-candidate, container Pantahub MQTT agent container / pv-mqtt-sdk).

Clone your device and merge the downloaded container for your architecture (armv8, armv6, or x86_64):

pvr clone https://pvr.pantahub.com/<user>/<device> device && cd device
pvr merge ../pv-mqtt-sdk-<arch>.pvrexport.tgz && pvr checkout

2. Add OEM configuration to disable REMOTE and LOGPUSH

Because the standalone container export only packages the container service, you must add the OEM configuration to disable Pantavisor’s built-in remote control (PV_CONTROL_REMOTE=0) and log push (PV_LOG_PUSH=0) so the agent can take over:

mkdir -p pv-oem-developer-001
cat << 'EOF' > pv-oem-developer-001/default.config
PV_CONTROL_REMOTE=0
PV_LOG_PUSH=0
EOF

Why this is needed: pv-mqtt-sdk runs only when PV_CONTROL_REMOTE=0. Disabling remote control and log push hands over update management, metadata synchronization, and telemetry to the agent while keeping the device’s identity (it adopts pantavisor’s own credentials).

3. Commit, sign and deploy

pvr add . && pvr commit && pvr sig update && pvr add . && pvr commit && pvr post

Links

We would love to hear your feedback — try it out and let us know what you think!