Introduction
In this post I’m going to take a closer look at Hawkbit.
Getting started
To get started we need to get a hold of the code, build it and then run.
Clone the repo and build
The code is in the following github repository and is built using maven.
This will build the entire codebase.
Start the dependencies
MongoDB
MongoDB is used to store all software artifacts.
- Locate your
mongodb-osx-x86_64
distribution - Create the data-files if the don’t exist yet.
- Start mongo db
RabbitMQ
- Locate your rabbitmq installation
- Launch rabbitmq
- Install the RabbitMQ management plugin
You’ll see that when Hawkbit starts, it will create
2 exchanges
- dmf.exchange
- dmf.connector.deadletter
2 queues
- dmf_connector_deadletter_ttl
- dmf_receiver
Run the applications
The model
The basic idea around Hawkbit is software distribution. How do we manage that process and how can we get software artifacts onto devices. Hawkbit has create a model to support this concept.
Everything starts with the concept of a software module. A software module is an artifact of a specific software module type. A software module type defines if its software or firmware.
Example software module types can be
- Base OS Image
- Software Module
- Configuration Module
In the screenshot below, you can see the 3 types :
API Integration
DDI API
Retrieving controller info
Every controller can retrieve its information from the hawkbit server like this
curl -v curl -v http://localhost:8080/default/controller/v1/controller1 | python -m json.tool
This will return a number of links that the controller can follow, as well as some configuration.
{
"_links": {
"configData": {
"href": "http://localhost:8080/default/controller/v1/controller1/configData"
}
},
"config": {
"polling": {
"sleep": "00:05:00"
}
}
}
When we assign a distribution to a device, a deploymentBase link will become visibe.
{
"_links": {
"configData": {
"href": "http://localhost:8080/default/controller/v1/controller1/configData"
},
"deploymentBase": {
"href": "http://localhost:8080/default/controller/v1/controller1/deploymentBase/4?c=160000543"
}
},
"config": {
"polling": {
"sleep": "00:05:00"
}
}
}
This deploymentBase
link will give access to various chunks
in the deployment. Each chunck
contains zero or more artifacts that can be downloaded by the device:
curl http://localhost:8080/default/controller/v1/controller1/deploymentBase/4?c=159999582 | python -m json.tool
{
"deployment": {
"chunks": [
{
"artifacts": [
{
"_links": {
"download-http": {
"href": "http://localhost:8080/default/controller/v1/controller1/softwaremodules/1/artifacts/emptyfirmware.bin"
},
"md5sum-http": {
"href": "http://localhost:8080/default/controller/v1/controller1/softwaremodules/1/artifacts/emptyfirmware.bin.MD5SUM"
}
},
"filename": "emptyfirmware.bin",
"hashes": {
"md5": "b026324c6904b2a9cb4b88d6d61c81d1",
"sha1": "e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"
},
"size": 2
}
],
"name": "IxorTalk Base Image",
"part": "Base OS Image",
"version": "1"
},
{
"artifacts": [
{
"_links": {
"download-http": {
"href": "http://localhost:8080/default/controller/v1/controller1/softwaremodules/3/artifacts/emptyconfig.xml"
},
"md5sum-http": {
"href": "http://localhost:8080/default/controller/v1/controller1/softwaremodules/3/artifacts/emptyconfig.xml.MD5SUM"
}
},
"filename": "emptyconfig.xml",
"hashes": {
"md5": "1896f4052d3089ae5524dc2de823bb78",
"sha1": "680f4b06424f4c4e12b52e5f85c5903c13082d3c"
},
"size": 10
}
],
"name": "IxorTalk Customer1 Config",
"part": "Configuration Module",
"version": "3"
},
{
"artifacts": [
{
"_links": {
"download-http": {
"href": "http://localhost:8080/default/controller/v1/controller1/softwaremodules/2/artifacts/emptysw.bin"
},
"md5sum-http": {
"href": "http://localhost:8080/default/controller/v1/controller1/softwaremodules/2/artifacts/emptysw.bin.MD5SUM"
}
},
"filename": "emptysw.bin",
"hashes": {
"md5": "2a5ea88c94ba0193bd1fd95c645eb557",
"sha1": "d94eeb5ca871d4c56a44f9d96cc3e1b2992d06cc"
},
"size": 8
}
],
"name": "IxorTalk Customer1 Software",
"part": "Software Module",
"version": "2"
}
],
"download": "forced",
"update": "forced"
},
"id": "4"
}
curl -v curl -v http://localhost:8080/default/controller/v1/controller1 | python -m json.tool curl -v -H “Content-Type: application/json” -d @progress1.json -X POST http://localhost:8080/default/controller/v1/controller1/deploymentBase/3/feedback curl -v http://localhost:8080/default/controller/v1/controller1/deploymentBase/13?c=160267701 | python -m json.tool wget http://localhost:8080/default/controller/v1/controller1/softwaremodules/7/artifacts/emptyfirmware.bin.MD5SUM wget http://localhost:8080/default/controller/v1/controller1/softwaremodules/8/artifacts/emptysw.bin
Here you can see th
rabbitmqadmin publish routing_key=test exchange=dmf.exchange payload=’{“type”:”THING_CREATED”,”tenant”:”tenant123”,”thingId”:”abc”,”sender”:”Lwm2m”}’ properties=’{“type”:”THING_CREATED”,”tenant”:”tenant123”,”thingId”:”abc”,”sender”:”Lwm2m”}’
rabbitmqadmin get queue=test requeue=false rabbitmqadmin publish routing_key=test exchange=dmf.exchange payload=”hello”
Issues
- JSON date handling (ISO-8601)
- API versioning (allowing the APIs to evolve)
- Client APIs (Feign) - use proper Jackson/GSON decoders instead of working with strings, allow clients to specify more parameters.
-
ControllerResource returns strings. Shouldn’t we use the objects fro tis ?
final String deploymentJson = controllerResource.getDeployment(getTenant(), getId(), actionId); final String swVersion = JsonPath.parse(deploymentJson).read("deployment.chunks[0].version");
Remarks
- Cancelled icon is a green circle with white x. I would change the green color as it resembles finished icon a lot.
Questions
-
How does hawkbit offer secure artifact downloads ? Currently a client can download any software module offered by hawkbit without providing credentials. I noticed some references to hawkbit.server.security.* properties but dont know if they are actually used yet. (I also saw some kind of GatewayToken being used in the simulator).
-
Plans on integration with other repositories ? (ex: Nexus / Artifactory / npm)
-
Plans to support different Hawkbit clients ? (Java / C / NodeJS / ….)