Skip to main content
Version: Torizon OS 6.x.y

First Steps With Subsystem Updates

Introduction​

In this article you will learn how to configure and implement the resources needed to use Torizon Subsystem Updates.

The steps for setting up a subsystem update with Torizon are as follows:

  • Define how the subsystem will be updated, whether through local file copy, UART, bluetooth, or another option;
  • Create a script or program to get an available payload and execute its installation in the subsystem - the Torizon OS Device should be able to run this script/program;
  • Configure the subsystem update feature in the Torizon OS and the Torizon Cloud according to the steps described in this article;
caution

This is a beta feature. Check and perform the instructions to enable beta features.

Also, let us know what you think about the feature and what else you need:

Contact us!

Prerequisites​

In order to perform subsystem updates, you should have:

Configuring Aktualizr​

The first step to use the Subsystem Updates Feature is to configure the Aktualizr update client to handle the target subsystem packages on the device. For this:

  1. Add a new target subsystem to Torizon OS by including a new entry into the Aktualizr Configuration file: secondaries.json.

    Torizon Cloud considers container applications, bootloader, and your target subsystems as secondary targets for updates. The OS on the device is considered the primary one. Learn more about it in the Aktualizr Reference Documentation. Check the following example adding the entry for a new secondary corresponding to your target subsystem.

    The default Aktualizr configuration in Torizon OS will load that file from the /usr/lib/sota/ directory. To override this configuration check the Aktualizr Reference Documentation.

secondaries.json
{
...
"torizon-generic": [
... other subsystems ...,
{
"partial_verifying": false,
"ecu_hardware_id": "your-target-subsystem",
"full_client_dir": "/var/sota/storage/your-target-subsystem",
"ecu_private_key": "sec.private",
"ecu_public_key": "sec.public",
"firmware_path": "/var/sota/storage/your-target-subsystem/your-payload.tar",
"target_name_path": "/var/sota/storage/your-target-subsystem/target_name",
"metadata_path": "/var/sota/storage/your-target-subsystem/metadata",
"action_handler_path": "/usr/bin/your-action-handler.sh"
}
]
}
  1. Replace your-target-subsystem value on the ecu_hardware_id key. This key holds the name for the target subsystem. This same name will be referenced in the Torizon Cloud and the TorizonCore Builder commands.

  2. Add the directory where the resources for your target subsystem will be located by changing the value /var/sota/storage/your-target-subsystem on the full_client_dir key. It is highly recommended to have a directory under /var to comply with OSTree restrictions.

  3. Replace /var/sota/storage/your-target-subsystem/your-payload.tar, on the firmware_path key, with the directory where you want the payload for your update to be delivered.

  4. Replace /var/sota/storage/your-target-subsystem/target_name, on the target_name_path key, with the directory where Aktualizr should create the target name definition file. It is recommended to set a directory under full_client_dir path. This configuration doesn't have significant role in the update process, although it remains mandatory.

  5. Replace /var/sota/storage/your-target-subsystem/metadata, on the metadata_path key, with the directory where you want Aktualizr to provide the metadata file.

  6. Replace path/to/your-action-handler.sh, on the action_handler_path key, with the directory where you will provide your custom action handler program or script. This is your custom program/script that will perform the installation of the delivered payload into your subsystem. Learn about the action handler and the other components in the Subsystem Updates Components section.

Understanding the Action Handler​

Actions​

The action handler performs 3 important actions:

get-firmware-info​

This action will be invoked whenever the update client needs to gather information about the payload currently installed on the Target Subsystem. Such information is employed by the Aktualizr update client when sending a manifest with the installed payload versions to the Update server. The reported installed version that will be displayed in logs and Web interfaces and the update trigger are based on the information returned from this action.

The Aktualizr update client will provide a path for the last delivered payload, and your action handler will process it to provide the needed information, closing the loop.

install​

This action will be invoked whenever the update client needs to deliver new payload to the target subsystem.

The Aktualizr update client will provide a path for the last delivered payload, and your action handler will deliver it to the target subsystem.

complete-install​

This action will be invoked by the update client on its startup if there are pending updates for the target subsystem to give it an opportunity to complete a previous installation.

Structure​

Follow the next example of a bash script to understand a basic structure of a Subsystem Update action handler:

#!/usr/bin/bash
# ---
# Main program
# ---
case "$1" in
get-firmware-info)
# Perform normal processing for this action.
<your subsystem information collecting code>
echo "ACTION HANDLER: get-firmware-info"
exit 64
;;
install)
# Perform normal processing for this action.
<your installation code>
echo '{"status": "ok", "message": "New picture installed"}'
exit 0
;;
complete-install)
# Perform normal processing for this action.
<your installation completion code>
echo "ACTION HANDLER: complete-install"
exit 64
;;
*)
# Perform normal processing for this action.
echo "ACTION HANDLER: ERROR event $1 not supported"
exit 64
;;
esac

Execution​

You should consider that the action handler will be invoked as follows:

$ SECONDARY_INTERFACE_MAJOR=1 \
SECONDARY_INTERFACE_MINOR=0 \
<aktualizr-environment-variables> your-action-handler <action>

The action-handler should perform its operations quickly. Usually, those operations are critical to the update process, and because of that it is recommended that OS signals (particularly SIGTERM) be trapped and ignored. If the action-handler is terminated by a signal, Aktualizr will consider this as an error.

The action-handler would normally be executed to the end and would return a certain exit code. The meaning of exit codes is the same for all actions.

The output of the action handler program/script to its standard output would be parsed by the Aktualizr update client as a JSON string. The expected contents in this output depends on the action being handled.

Information Exchange​

Input - Aktualizr Environment Variables​

The Aktualizr call to the action handler includes envinronment variables as described in the Execution section. There are environment variables included only in particular actions, and variables included in every action. The environment variables passed to the action handler are described in the Reference Documentation.

Output​

To return information from the actions performed, the action handler must write a JSON output to stdout, specific for each action. Those particular outputs will be described in the Writing the action handler section, and they can comprise at least two parts:

  • status (string): This can be set to one of the following values: ok, need-completion or failed. These are the values Aktualizr uses to identify the status of the update.
  • message (string): A message to be shown in aktualizr logs and Torizon Cloud Web UI (useful for debugging).

The action handler should also return an exit code. Read more about them in the Reference Documentation

Writing the Action Handler​

You need to write a custom action handler script or program to report the subsystem package version and execute the installation process, including any particularities, such as checks and rollbacks. The following sections present what is needed to implement for each action of the action handler. Compare the next sections to the Provided Example and to the Action Handlers repository on GitHub for better understanding.

1. Action: get-firmware-info​

Provide a script/program action capable of using the input to get the information needed, process it and provide the needed output, described next.

It is important to know that the Aktualizr Update Client is responsible for securely download and deliver the payload for the updates so the action-handler can execute the update installation. Having said that, your get-firmware-info action should return information about the actual installed payload on your target subsystem, ensuring reliable data is served through the overall process.

Some of the properties on the output JSON described next are optional. However, if your action-handler does not return this data, Aktualizr will consider the downloaded content is the same as the installed one, which can not be true, since your installation process can go wrong for a lot of different reasons. For quick evaluation, it is perfectly reasonable to only return the status and exit code. However, on the final implementation, we highly recommend you to implement the output as described next.

Input Environment Variables​

This action receives the full path to the payload file. This path would point to the same value configured in the Aktualizr config file - "firmware_path" key. The file may not exist though if there was no previous successful installation. Learn more in the Reference Documentation.

Output​

When returning information for the get-firmware-info action, your script should return a JSON string with the following structure:

  • name (string): The name of the currently installed target (package); if this field is not present (recommended) or it is set to null, it will be automatically determined from a β€œtarget name” file which is kept along with the firmware file.
  • sha256 (string): The SHA-256 checksum of the currently installed version of the firmware file; if this field is not present or is set to null it will be automatically determined based on the current firmware file (as defined in variable SECONDARY_FIRMWARE_PATH). This automatic operation is not ideal though because the target subsystem may not be running this exact firmware binary (if, for example, that component was upgraded not via the Aktualizr update client or if the last firmware was not applied due to some previous error).
  • length (integer): Size in bytes of the currently installed firmware file. This field must be set only when sha256 is set and it will be ignored otherwise.
  • status (string): This can be set to one of the following values: ok or failed.
  • message (string): A message to be shown in the aktualizr-torizon logs (useful for debugging).

2. Action: install​

Provide a script/program action capable of taking the payload file, validate and install it into the target subsystem being managed.

Input Environment Variables​

  • Type of update being performed: remote or offline
  • Full path to the payload file to be installed
  • The SHA-256 checksum of the firmware file to be installed
  • JSON string containing the custom metadata

Learn more in the Reference Documentation.

Output​

This action needs to return a JSON string with the following structure:

  • status (string): This can be set to one of the following values: ok, need-completion or failed.
  • message (string): A message to be shown in the aktualizr-torizon logs (useful for debugging).

3. Action: complete-install​

Provide a script/program action capable of completing the installation process in case of a multi-step installation. This is usually needed when the action handler returned need-completion status on a previous install action. Check the Status Section for more.

Input Environment Variables​

  • Full path to the payload to be installed
  • The SHA-256 checksum of the payload file to be installed
  • JSON string containing the custom metadata from the director and image Uptane repositories associated with the target

Learn more in the Reference Documentation.

Output​

A JSON string with the following structure:

  • status (string): This can be set to one of the following values: ok, need-completion or failed. If this property is set to ok or failed the information maintained by the update client to indicate there is a pending update will be cleared.
  • message (string): A message to be shown in the aktualizr-torizon logs (useful for debugging).

Creating Custom Packages​

Upload the payload to Torizon Cloud, thus creating a custom update package.

This can be done by:

  • Using TorizonCore Builder: learn how to use the platform push command to send custom packages to the platform by reading the Signing and Pushing Packages article.
  • Using Torizon Cloud Web UI: learn how to upload a custom package by reading the Uploading a custom package section.

Executing Updates​

To execute an update, use the process similar to updating the OS and Application components.

Learn how to do it:



Send Feedback!