Create a Workflow Script
OTA Update Workflow is the core logic behind the OTA update.
You need to first define the software (OTA) update workflow logic in the form of a Workflow Definition Script. The script can be written as a Linux shell script or Python/Perl script or any scripting language of your choice.
The workflow script defines the various steps involved in the software update process and the order in which the steps need to be executed. The workflow script will also have a rollback on failure
logic to rollback the device software to the original state (the previous working state), if the update fails.
Workflow Script Blueprint
An OTA update workflow script should have the following logic:
- Stop the app or service running in the device ( On failure, do what? - Undo the current action.)
- Back up the existing working app/version and working config files (On failure, do what? - Undo the previous actions)
- Download and install the new app binary to the app directory (On failure, do what? - Restore from the backup)
- Update the app configuration and settings, or download a new config file with the required settings. (On failure, do what? - Restore from the backup)
- Start the app or service (On failure, do what? - Restore from the backup)
- Verify if the app is up and running (On failure, do what? - Restore from the backup)
- Clean up the back up.
- Done. Exit.
Here is a sample Workflow Script
file written in Linux Shell script, using the above blueprint. Please feel free to modify the below shell script to adapt it for your application's OTA update workflow requirements.
$ cat update.sh
#!/bin/sh
#================================================
# Example Workflow Script:
# MyApp Update Workflow Script
#================================================
# On-failure (before the backup) just restore the service
invoke_restore() {
systemctl start myapp
systemctl status myapp
exit 1
}
# On-failure clean up and restore from backup.
invoke_restore_backup() {
systemctl stop myapp
cp /usr/local/bin/myapp.bkup /usr/local/bin/myapp
cp -R /var/lib/myapp.bkup /var/lib/myapp
rm -rf /var/lib/myapp.bkup
cp /etc/myapp/config.json.bkup /etc/myapp/config.json
systemctl start myapp
systemctl status myapp
exit 1
}
debug_error() {
echo "$(date +"%Y-%m-%d %H:%M:%S.%N"): Error: $1"
}
debug_log() {
echo "$(date +"%Y-%m-%d %H:%M:%S.%N"): $1"
}
# Workflow Begins.
# stop the service first
systemctl stop myapp
# backup the current working app
cp /usr/local/bin/myapp /usr/local/bin/myapp.bkup
if [ $? -eq 0 ]; then
debug_log "Binary copied."
else
debug_error "Binary backup failed."
invoke_restore
fi
# backup the current config file
cp /etc/myapp/config.json /etc/myapp/config.json.bkup
if [ $? -eq 0 ]; then
debug_log "Config copied."
else
debug_error "Config backup failed."
invoke_restore
fi
# Download the new myapp file from your online storage such as AWS S3 Bucket
curl -O https://abcdefghxyz.amazonaws.com/v41/bin/myapp && chmod +wx myapp && sudo mv myapp /usr/local/bin
if [ $? -eq 0 ]; then
debug_log "New binary downloaded."
else
debug_error "New binary download failed."
invoke_restore_backup
fi
# Download a new myapp config.json file from your online storage such as AWS S3 Bucket
curl -O https://abcdefghxyz.amazonaws.com/v41/cfg/config.json && sudo mv config.json /etc/myapp/config.json
if [ $? -eq 0 ]; then
debug_log "New config file downloaded."
else
debug_error "New config file download failed."
invoke_restore_backup
fi
# Start the service again
systemctl start myapp
# Check the status of the service
STATUS="$(systemctl status myapp | grep 'Active: active (running)')"
if [ -z $STATUS ]; then
debug_error "myapp service failed to run."
invoke_restore_backup
else
debug_log "myapp service is running."
fi
# Clean up files
rm -f /usr/local/bin/myapp.bkup
rm -f /etc/myapp/config.json.bkup
The workflow script assumes that the artifact (your app binary, app package(RPM, DEB), or docker container) is stored in a third-party online registry such as AWS S3, GitHub Packages Registry or Docker Hub or any cloud based online registry.
Note:
If you are packaging the above workflow script along with your app binary, config file and creating a tar.gz
file to upload it to the SocketXP Artifact Registry, you can skip the steps(shown below) that involve "curl download of the myapp binary file and the config file from the AWS S3 bucket" in the above workflow script. You'll find your myapp binary and the config.json files(untarred and unzipped) in the same local directory as your workflow script.
However, make sure that you move the app binary and config files from the current directory to the appropriate destination folder in your device.
# Download the new myapp file from your online storage such as AWS S3 Bucket
curl -O https://abcdefghxyz.amazonaws.com/v41/bin/myapp && chmod +wx myapp && sudo mv myapp /usr/local/bin
if [ $? -eq 0 ]; then
debug_log "New binary downloaded."
else
debug_error "New binary download failed."
invoke_restore_backup
fi
# Download a new myapp config.json file from your online storage such as AWS S3 Bucket
curl -O https://abcdefghxyz.amazonaws.com/v41/cfg/config.json && sudo mv config.json /etc/myapp/config.json
if [ $? -eq 0 ]; then
debug_log "New config file downloaded."
else
debug_error "New config file download failed."
invoke_restore_backup
fi
The artifact should be accessible from the IoT device, where it will be eventually downloaded by the workflow script.
Cloud based online storages or registries usually provide a unique random public URL to the artifact for this purpose.