Bridging the Gap: The RAUC hawkBit Client
OTA field updates are a common requirement in modern embedded device deployments. The larger the amount of devices to control, the more important is having a good infrastructure that is reliable in updating and smart in rolling out the software.
With the RAUC update framework, we already have one of the components required for solving this challenge: an update client operating on your target and making sure that your updates are installed safely and securely.
The second component is a deployment server that manages your update artifacts, controls roll-out strategies, gives feedback about device update states, etc.
This is where the Eclipse hawkBit project comes into play. While RAUC focuses on being not much more than the update core, hawkBit focuses on being a deployment server only. This qualifies it as an ideal counterpart for RAUC.
Thus, the only question remaining is: How should we bring them together?
Evolution of rauc-hawkbit
In the middle of 2016, in the context of a customer project where unattended OTA field updates with hawkBit as the deployment infrastructure were required, Pengutronix started implementing a python-based service that runs on the target and talks to RAUC on the one side via its D-Bus interface and to hawkBit on the other side over its RESTful DDI API.
Later that year, parts of the code were reused in an internal project, a RAUC hawkBit deployment server demonstrator. We presented this at the FOSDEM in Brussels, at the Chemnitz Linux days and on the Embedded World exhibition.
Finally, in early 2017, the customer and we decided to make a reusable project out of the hawkBit client core components and provide it as open source software. The advantages that were the motivation behind doing this step are quite the same as for almost every open source project: Only this way it will have the chance to be actively maintained, used, tested and possibly improved by the community.
A few month later, after a bunch of refactoring, cleanup and testing, we now finally release the initial version (0.1.0) of this project.
See How It Works
Now, let's conclude the history lesson and start with some technical facts.
The communication with the D-Bus interface of RAUC is done using the corresponding glib methods from Python via the GObject introspection interface.
During its initial interaction with the server, the client identifies itself to the server and sends some meta-data that allows identification, filtering, etc. Then the client service regularly polls the deployment server for new artifacts or actions. The polling interval itself is a property set by the hawkBit server and can be adjusted to specific needs. Once hawkBit has an update available for the device, the client first downloads it and then triggers RAUC via D-Bus to install the downloaded bundle.
During installation, the client receives progress feedback from RAUC and forwards it to hawkBit, allowing the user to see the exact individual progress of each pending update. After a successful or failed update, hawkBit gets notified about the result, allowing to base roll-out strategies on this information.
rauc-hawkbit is available in the python package index (pypi) making it easy to install for testing purposes.
For those who use Yocto/OpenEmbedded as build system, the meta-rauc layer provides a rauc-hawkbit recipe and all required dependencies. You can simply add it to your image:
IMAGE_INSTALL_append = " rauc-hawkbit"
or build it directly with bitbake:
The rauc-hawkbit client is designed to be both an example application as well as a base library providing the required functionality for bringing RAUC and hawkBit together. For testing, you can simply use the provided executable python script rauc-hawkbit-client. If you consider actually using it in the field, you may want to integrate it into your application, web interface or something else. In that case, you can use it as a python module via import rauc_hawkbit.
To use the example command-line application, all you need is a configuration file containing some mandatory information, such as the server address, an authentication token or the name of your target:
[client] hawkbit_server = 127.0.0.1 ssl = false tenant_id = DEFAULT target_name = test-target auth_token = ahVahL1Il1shie2aj2poojeChee6ahShu mac_address = ff:ff:ff:ff:ff:ff bundle_download_location = /tmp/bundle.raucb log_level = debug
To start the rauc-hawkbit client run:
rauc-hawkbit-client -c config.cfg
Note that for this example to be fully functional, you also need to have a RAUC instance running on your device and a hawkBit instance set up on your server. Refer to this page on how to quickly set up a development instance of hawkBit.
"Getting things off the ground" could be the motto for the v1.9 release of RAUC. The support for custom metadata in the manifest got a step further, a new, more flexible, D-Bus API for bundle inspection paved the way for obtaining more detailed information, and a new manifest hash marks the first of several planned changes for configurable event logging. However, one of the most invasive changes happened under the hood: We have started the transition from autotools to meson as a build system.