Yocto Project
ShellHub maintains an OpenEmbedded layer, so the agent ships with your firmware without you writing a recipe. Use it rather than packaging the agent yourself.
Prerequisites
- A Yocto build environment on a supported release. The layer declares compatibility with
styhead,whinlatterandwrynose - A provisioning key, so units register themselves with nobody present
Adding the layer
$ git clone https://github.com/shellhub-io/meta-shellhub.git
$ bitbake-layers add-layer ../meta-shellhub
The layer depends only on meta from openembedded-core, so it drops into an existing
build without pulling anything else in.
Adding the agent to the image
IMAGE_INSTALL:append = " shellhub-agent"
There is also packagegroup-shellhub-runtime, which pulls the agent and its runtime
dependencies. Either works; the packagegroup is the one to prefer when your image is
assembled from packagegroups already.
The agent’s own dependencies come with it — openssh-scp so file transfer works, and
shadow so the login you connect as can be resolved.
Configuring it
Set these in local.conf or your distro configuration:
SHELLHUB_SERVER_ADDRESS = "https://cloud.shellhub.io"
SHELLHUB_PROVISIONING_KEY = "<your-provisioning-key>"
| Variable | Default |
|---|---|
SHELLHUB_SERVER_ADDRESS |
https://cloud.shellhub.io |
SHELLHUB_PRIVATE_KEY |
/etc/shellhub-agent.key |
SHELLHUB_PROVISIONING_KEY |
(none) |
SHELLHUB_TENANT_ID |
(none, deprecated) |
These are written into /etc/default/shellhub-agent, which the service reads at start.
One of the two registration variables is required — the configuration recipe stops the
build rather than producing an image that registers nowhere.
SHELLHUB_TENANT_ID is deprecated. It remains for integrations that already ship with it; use the
provisioning key for anything new.
Why the tenant is the wrong one. A device registering with the tenant alone goes through the namespace’s legacy registration path, which holds it for manual review — so a production run arrives as a queue of pending devices rather than a working fleet. A provisioning key also carries tags, so a policy can cover the batch before anybody opens the console. See Using provisioning keys.
The key must be writable and must not be in the image
The agent generates its device key when the file is missing. Two consequences, and both of them bite in production:
The key path has to be writable and to survive a reboot. On a read-only root filesystem, or a path on a volatile partition, every boot produces a new identity and a new device in the console.
No key may be baked into the image. Every unit written from an image containing one claims the same identity, and you get a single device that appears to move between machines instead of a fleet.
Init systems
The recipe installs a systemd unit or a sysvinit script, following your image’s
DISTRO_FEATURES. Neither needs configuration beyond the variables above.
Overriding the tenant per image
The layer ships shellhub-rootfs-postcommand.bbclass for the case where one build feeds
several namespaces. Inherit it and set SHELLHUB_ROOTFS_TENANT_ID, and the tenant in the
generated configuration is rewritten as the rootfs is assembled, without a rebuild of the
agent.
It rewrites the tenant only. A build that registers by provisioning key does not need it.
Verifying
Write the image to two devices and start both.
Expected result: Two devices appear, each carrying the provisioning key’s tags, and each with its own identity.