Skip to content

Commands & OTA Updates

The Cloud Backend can push commands to Edge appliances. Since Edge devices may be behind NAT or firewalls, the communication model is poll-based: the Edge device periodically asks the Cloud API for pending commands.

sequenceDiagram
    participant Edge as Edge Appliance
    participant CloudAPI as Cloud Backend
    participant SQL as Azure SQL

    loop Every N seconds
        Edge->>CloudAPI: GET /api/v1/commands (X-Device-Key)
        CloudAPI->>SQL: SELECT pending commands WHERE device_id = ?
        CloudAPI-->>Edge: [{ command: "update_snap", payload: { ... } }, ...]
        Edge->>Edge: Execute commands
        Edge->>CloudAPI: POST /api/v1/commands/:id/ack { status: "completed" }
    end
CommandPayloadEffect
update_snap{ snap_name, version }Trigger OTA snap update
restart_service{ service }Restart a specific Edge service
run_discovery{ subnet }Trigger network discovery on a subnet
config_update{ ... }Apply configuration changes

The exact command set depends on the Edge agent version. See Backend/internal/domain/devices/ for the command dispatch logic.

Edge appliances run software distributed as snap packages. The update process:

sequenceDiagram
    participant Operator
    participant CloudAPI as Cloud Backend
    participant Storage as Azure Blob Storage / Local
    participant Edge as Edge Appliance

    Operator->>CloudAPI: POST /api/v1/admin/publish (X-Snap-Publish-Token)
    Note right of Operator: snap blob upload
    CloudAPI->>Storage: Store snap blob
    CloudAPI->>CloudAPI: Record new snap version

    Edge->>CloudAPI: GET /api/v1/snaps/latest
    CloudAPI-->>Edge: { version: "1.2.3", download_url: "..." }

    alt New version available
        Edge->>Storage: Download snap blob from download_url
        Edge->>Edge: Verify checksum
        Edge->>Edge: Apply snap update
        Edge->>CloudAPI: Report update status
    end
EnvironmentConfig
ProductionAZURE_STORAGE_ACCOUNT + AZURE_STORAGE_CONTAINER=snaps (private Azure Blob)
Local devSNAP_BLOB_LOCAL_ROOT=/path/to/snap-blobs

The download URL returned by GET /api/v1/snaps/latest is built from API_PUBLIC_URL, so this env var must match the host that Edge devices use to download snaps.

New snap versions are published by CI/CD using:

POST /api/v1/admin/publish
Authorization: Bearer <SNAP_PUBLISH_TOKEN>

The SNAP_PUBLISH_TOKEN is a static CI bearer token (not a user JWT).

TableMigrationContent
edge_commandsV22Pending commands per device, status
edge_snap_updatesV21Published snap versions, download metadata

See Backend/db/migration/V21__edge_snap_updates.sql and V22__edge_device_control.sql.