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;
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:
- Basic understanding of the Subsystem Updates Overview article
- The payload files for the update readily available
- Account registered in the Torizon Platform Services
- A provisioned Torizon OS device
- TorizonCore Builder installed on your host machine (Optional)
- The credentials.zip file download from your Torizon Plattform account section (Optional)
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:
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.
{
...
"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"
}
]
}
Replace
your-target-subsystem
value on theecu_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.Add the directory where the resources for your target subsystem will be located by changing the value
/var/sota/storage/your-target-subsystem
on thefull_client_dir
key. It is highly recommended to have a directory under/var
to comply with OSTree restrictions.Replace
/var/sota/storage/your-target-subsystem/your-payload.tar
, on thefirmware_path
key, with the directory where you want the payload for your update to be delivered.Replace
/var/sota/storage/your-target-subsystem/target_name
, on thetarget_name_path
key, with the directory where Aktualizr should create the target name definition file. It is recommended to set a directory underfull_client_dir
path. This configuration doesn't have significant role in the update process, although it remains mandatory.Replace
/var/sota/storage/your-target-subsystem/metadata
, on themetadata_path
key, with the directory where you want Aktualizr to provide the metadata file.Replace
path/to/your-action-handler.sh
, on theaction_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
orfailed
. 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
orfailed
. - 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
orfailed
. - 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
orfailed
. 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: