Skip to content
Drasko DRASKOVIC edited this page Oct 30, 2015 · 17 revisions

Description

Updater is a piece of software that connects to a device management and provisioning server and downloads new FW version (and optionally upgrade instructions) from a predefined or given URL.

Then it applies sysupgrade with preserving the needed system state (user installed packages, modified files, etc) - as explained here: http://wiki.openwrt.org/doc/howto/generic.sysupgrade

To be more flexible this whole procedure is divided in two parts:

  • Updater downloads update recipe from a distant server (and checks MD5 integrity of this recipe)
  • Updater starts update recipe which finishes the update procedure

Update recipe is a script that does all the custom update. Benefits of having most of the update process in separate remote script is that this script can evolve and be changed and customized (as opposed to a lightweight Updater that is on the board somewhere deployed in the field).

Method of operation

  1. Main user program receives a RPC (either over MQTT or WS) to initiate FW update

  2. In a handler for this RPC, main user program calls Updater (from a provided on-board client library, in this case weioLib)

  3. Updater checks config.weio for 2 things:

  • Current version number
  • URL of the update JSON metadata, which is similar to this:
[
   {
       "assets": [
           {
               "download_url": "http://we-io.net/downloads/v1.1/weio.tar.gz", 
               "name": "weio.tar.gz", 
               "md5": 3762
           }, 
           {
               "download_url": "http://we-io.net/downloads/v1.1/weio_recovery.bin", 
               "name": "weio_recovery.bin", 
               "md5": 13434884
           }
       ], 
       "body": ": WeIO is much more stable and a lot of new drivers has been added", 
       "name": "Attention. After downloading new version and starting install procedure please wait until 2 green LEDs stop to blink", 
       "tag_name": "v1.1" 
   }
]
  1. Updater downloads update.json metadata:
  • it reads from it LATEST release number and
  • if this number is bigger than current release, Updater looks in the update.json metadata to see URL of the update recipe to use and downloads it
  1. Updater starts recipe as a separate process (subprocess) and this recipe script finishes the update procedure:
  • downloads sysupgrade image from internally hard-coded location (in the recipe)
  • checks MD5 integrity
  • creates backups if needed
  • starts sysupgrade with correct parameters

Custom updater recipe in details

In most cases system upgrade is done in the following steps:

  1. Download new FW (sysupgrade image) from some URL to RAM (i.e. /tmp)

  2. Check the integrity of downloaded image by applying MD5 SUM

  3. Preserve system files as explained here: http://wiki.openwrt.org/doc/howto/generic.sysupgrade or here: http://wiki.openwrt.org/doc/techref/sysupgrade, which would often consider:

  4. Execute sysupgrade

Because this is a usual procedure, we can make this procedure default.

However, it might turn out that at some point we have to change update procedure even when having a number of boards already deployed in the filed.

This is where "custom update recipe" comes into play - i.e. we will trigger custom update procedure instead of default one.

This "custom updater procedure (or recipe)" is basically an executable, and can be any executable type - Bash script, Python script, C program, etc...

In order to execute this custom operation, Updater must download it first, and we must provide it URL where to download it from (for WeIO this URL is contained in update.json metadata).

So, since this is a piece of binary code, Updater treats it like any other binary image:

  • Goes to URL and fetches custom_update_recipe binary
  • Verifies integrity with MD5 SUM
  • Executes custom_update_recipe binary (for example by forking it in a separate shel process)

Tool for creating new update

Here you will find a script that will prepare new update. https://github.com/nodesign/weio/blob/next/updateMaker/prepareForWeIOServer/prepareUpdate.py To execute this script you will need 2 files in it's directory : recipe (this is script or executable that will do actual update procedure) weio_recovery.bin

Don't put extension to recipe. It will be executed with python function subprocess.call("/tmp/recipe"). That gives you freedom to make recipe in every possible exe manner (python script, shell script or binary)

Execute script by providing path to directory where these 2 files are stored and version number

uros$ python prepareUpdate.py ./ v1.2

Script will measure file sizes and md5 for both files and generate json file. Here is one generated for this example :

{
    "recipe": {
        "body": "This is a brand new version of WeIO great software", 
        "download_url": "http://we-io.net/downloads/v1.2/recipe", 
        "md5": "6889b8ee3ea5c5224af755b671b49574", 
        "size": 4402, 
        "title": "Update to v1.2", 
        "version": "v1.2"
    }, 
    "recovery": {
        "download_url": "http://we-io.net/downloads/v1.2/weio_recovery.bin", 
        "md5": "22b0385fd844b22936885a4c9e34c72a", 
        "size": 12058628
    }
}

File named updateWeio.json will be generated. Edit manually this file to change title and body that will be displayed in the web interface.

Uploading files to WeIO server

This procedure is available only for WeIO authors. However if you forked this project and you want to make your own versions switch to your local repository by providing your own server and setting alternative repository : https://github.com/nodesign/weio/blob/next/config.weio#L31-L33

Upload updateWeio.json to the well-known-address defined in [config.weio])https://github.com/nodesign/weio/blob/master/config.weio#L31). Place recipe and weio_recovery.bin to locations defined in download_url in JSON.