Design

The hawkBit update server defines a hierarchy of software that starts with a distribution, which can have (sub-)modules and these may have multiple artifacts. The hawkBit Data Model concept can be found here.

For Apertis, we want device agent to be as simple as possible. So it should only need to check the hawkBitserver for an update, download and install it.

The build server (Jenkins), when ostree static delta file has been created, is responsible to create a distribution containing a single module for each build and for each Apertis release, type and architecture.

The ostree static delta file is uploaded to the module as its single artifact.

Distribution and module version are based on the image version.

To be more concrete, when the image pipeline is building the armhf minimal image it also builds a matching full static OSTree bundle named, for instance, apertis_ostree_v2020pre-minimal-armhf-uboot_20191011.0.delta.

This bundle is uploaded to hawkBit under the apertis_v2020pre-minimal-armhf-uboot module with version 20191011.0. This module is linked to a distribution sharing the same name and version.

hawkBit backend installation

The hawkBit update server can be installed using docker-compose (cf. HawkBit Getting Started).

It needs a docker-compose.yml and an application.properties file to configure the hawkBit server.

docker-compose.yml file (based on docker-compose.yml):

#
# Copyright (c) 2018 Bosch Software Innovations GmbH and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
version: '3'

services:

  # ---------------------
  # MySQL service
  # ---------------------
  mysql:
    image: "mysql:5.7"
    environment:
      MYSQL_DATABASE: "hawkbit"
      MYSQL_USER: "root"
      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
    restart: always
    ports:
      - "3306:3306"
    labels:
      NAME: "mysql"

  # ---------------------
  # HawkBit service
  # ---------------------
  hawkbit:
    image: "hawkbit/hawkbit-update-server:latest-mysql"
    environment:
      - 'SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/hawkbit'
      - 'SPRING_DATASOURCE_USERNAME=root'
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./application.properties:/opt/hawkbit/application.properties
    labels:
      NAME: "hawkbit"

application.properties file:

#
# Copyright (c) 2015 Bosch Software Innovations GmbH and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#

# User Security
spring.security.user.name=admin
spring.security.user.password={noop}admin
spring.main.allow-bean-definition-overriding=true

# DDI authentication configuration
hawkbit.server.ddi.security.authentication.anonymous.enabled=false
hawkbit.server.ddi.security.authentication.targettoken.enabled=true
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true

# Optional events
hawkbit.server.repository.publish-target-poll-event=false

## Configuration for DMF/RabbitMQ integration
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest
#spring.rabbitmq.virtual-host=/
#spring.rabbitmq.host=localhost
#spring.rabbitmq.port=5672

# Define own users instead of default "admin" user:
hawkbit.server.im.users[0].username=apertis
hawkbit.server.im.users[0].password={noop}Apertis!
hawkbit.server.im.users[0].firstname=Apertis
hawkbit.server.im.users[0].lastname=HawkBit
hawkbit.server.im.users[0].permissions=ALL

# Enable CORS and specify the allowed origins:
#hawkbit.server.security.cors.enabled=true
#hawkbit.server.security.cors.allowedOrigins=http://localhost

Copy them to a directory and run:

$ docker-compose up -d

You can then connect to the hawkBit Management UI at server address and port 8080, with username apertis and password Apertis!.

Trigger a deployment from Apertis hawkBit update server

Deployment setup

This should be done automatically during image build, but can also be done manually.

Create a Software Module in Upload page

This allows to group multiple artifacts.

Click on :heavy_plus_sign: in Software Module panel and provide Type, Name, and Version.

Multiple artifacts can be attached to the Software Module using the upload File button.

Create a Distribution in Distributions page

The distribution is a collection of software module(s).

1st create the Distribution (:heavy_plus_sign: sign in Distributions panel), which will require Name and Version info, then drag-and-drop required Software Module(s) on top of the newly created Distribution.

Deployment to target(s)

There is 2 ways two start the distribution deployment: manually for a specific target, or to multiple targets using a filter.

Manually deploy to one target

From the Deployment page, simply drag-n-drop the distribution on top of the desired target.

Rollout deployment to multiple targets

This needs to create a filter in Target Filters page by clicking on :heavy_plus_sign: sign, and providing a Name and the filter string (e.g. attribute.isoCode==DE).

:exclamation: Do not forget to save the filter.

Then, we are now able to create the deployment in Rollout page by clicking on :heavy_plus_sign: sign, giving it a Name and selecting the Distribution, Filter and the number of group to use.

Target device

Target authentication

Target devices are identified in hawkBit by there Controller Id and Target Token.

A Target token is generated automatically for each new device added using the UI.

A device can be added manually in the hawkBit management UI, or multiple devices can be added by uploading a csv file containing:

Controller_Id_1,targetName1
Controller_Id_2,targetName2
…

A device can also be added using the Management API, allowing to set the Target Token:

$ curl --user 'admin:admin' 'http://localhost:8080/rest/v1/targets' -i -X POST -H 'Content-Type: application/json;charset=UTF-8' -d '[ {"securityToken" : "2345678DGGDGFTDzztgf","address" : "https://192.168.0.1","controllerId" : "Controller_Id_1","name" : "Controller 1","description" : "Test controller 1"} ]' -v

apertis-hawkbit-agent

The apertis-hawkbit-agent is a component in the OSTree-based images to poll hawkBit update server, and in case of an update is available to download it and trigger apertis-update-manager to apply it.

Installation

Add apertis-hawkbit-agent package using apt action to debos image.

Configuration

The server URL, Controller ID and Target Token are mandatory and should be copied to /etc/apertis-hawbit-agent.ini on the device.

After reboot, the device should be able to connect to hawkBit update server and retrieve updates.

Possible improvements

  • stabilizing the hawkBit instance
  • optimize resource consumption by moving away from full static bundles
  • use hawkBit tags for the distributions, setting type and architecture. This will allow to easily find the right distribution to send to a specific target or set of targets.
  • improve Apertis hawkBit agent interaction with Apertis Update Manager by calling the RegisterSystemUpgradeHandler DBus method, and calling ApplySystemUpgrade when all artifacts has been applied, which may happen with partial upgrades.
  • Send successful feedback from Apertis hawkBit agent to hawkBit update server only after reboot of the upgraded system went well.

The results of the search are