Versioning with SWUpdate
TLDR; It is now possible to let SWUpdate manage the sw-versions file entirely thanks to the --gen--swversions feature I've been working on.
SWUpdate
SWUpdate [1] is a project I've been using for a very long time for updating firmware on embedded systems.
The update service is a critical part of any embedded system, so having a well-tested, flexible, competent and ready-to-use solution is so much worth. Too many times I've seen custom made update services that contain bugs, is not flexible enough or using slots for whatever software that could be updated.
The thing is that in most cases, the update service decides what and how things should be updated. It is a bad design.
This is not the case for SWUpdate. All logic for what and how components should be updated resides inside the update package itself. That concept makes it flexible and future-proof - you do not have to guess what should be updated in a year or two.
Versions
SWUpdate can verify if an image component is already installed or of a higher version. In such cases SWUpdate can skip to install that component and continue with the next one. But how does SWUpdate determine which version that is installed on the system?
sw-versions
SWUpdate searches for a file, /etc/sw-versions by default, containing version information of all components installed. Each component has the optional attributes name and version that SWUpdate matches against the entries in the version file.
Those are optional, but I really advocate using these attributes. All software should have a version (how do you know what's delivered otherwise?), and explicitely store that version information on the system is just a small thing that increases the product quality a lot.
The format of the sw-versions file is:
<name of component> <version>
where <version> could be in any format [3].
If the attribute install-if-higher is used, then the version should be in either up to 4 numbers format (e.g. <major>.<minor>.<rev>.<build>) or to be a semantic [2] version. Otherwise it is impossible to calculate what's the higher version of two.
![/media/semver.png](/media/semver.png)
Generation of sw-versions
As there is no standardized way to read out the version of a certain component, SWUpdate does not write to sw-versions but expect that the system should populate it during boot.
The idea is good, but I can think of several different setups where it would be appreciated if the SWUpdate service actually updated the version file when new components are installed.
That is why I implemented [4] support for gen-swversions.
Usage of gen-swversions
gen-swversions generates a version file containing the installed (and versioned) components of the system. It uses the version file (set by CONFIG_SW_VERSIONS_FILE) as a base and updates the version information as soon any component has been successfully installed.
A new entry will be created if there are no previous version installed for that component.
The usage is simple:
1$ swupdate -i package.swu --gen-swversions /etc/sw-versions
The parameter requires a path to a file, this to handle the case when you don't want SWUpdate to update the actual version file, but still wants the information to be stored somewhere.
If you do choose to point to CONFIG_SW_VERSIONS_FILE, then you have a version file completely maintained by SWUpdate.
You can omit the --gen-swversions if you put the parameter into the configuration file [5] instead.
References
[1] | https://github.com/sbabic/swupdate |
[2] | https://semver.org/ |
[3] | https://sbabic.github.io/swupdate/sw-description.html#versioning-schemas-in-swupdate |
[4] | https://github.com/sbabic/swupdate/commit/b19aea14e1b56d284387c44c23672f97777f1128 |
[5] | https://github.com/sbabic/swupdate/blob/2f3b288b2c55e0033f4d2dbe49d46eaa939ad3bb/examples/configuration/swupdate.cfg#L55 |