Skip to content
Ryan Sturmer edited this page Oct 12, 2016 · 5 revisions

Update Concepts

The updater has a number of design goals, and might be better labeled the "FabMo Agent" - in addition to essential software update functions, it also manages network interfaces, performs system maintenance tasks, loads firmware and collates and reports various software version identifiers.

Requirements

The mechanics of an actual update should be as follows:

  • Updates should be deliverable without an internet connection
  • Updates should be able to be initiated by the user, or happen automatically
  • Automatic updates should require user consent
  • Updates should be checked for consistency when applied (Some kind of MD5 sum or hash)
  • System functions affected by an update should be inaccessible while the update is conducted
  • Updates should not perturb user configuration values if they don't have to
  • Updates may perturb user configuration values if a compatibility-breaking change is introduced
  • Updater should be able to update itself
  • A failed update should result in a restoration to the previous factory state (or the most recently updated state?)
  • Update packages should not be generic scripts that can perform any function (constrained function to actual updates only)
  • Updates can and should be able to include things like apps, configuration changes, macros, etc
  • Updates should include a changelog and other relevant information for users
  • Updated software systems should know when they have just been updated so they can take appropriate steps in their user interactions
  • There should be a system for doing development updates, the way we do now, with pulling changes from git/npm

Design Detail

Updates should be deliverable without an internet connection

Update packages that are downloaded automatically by the updater can just as easily be applied by providing them to the updater directly. This can be done through the updater interface, and once the upload is complete, the updates are applied using the same codepath that is used to apply ones that are downloaded by the updater.

Updates should be able to be initiated by the user, or happen automatically

The updates that are available to a given system are provided in a packages list that can be retrieved and examined without having to actually download the packages. The correct packages to get are determined automatically, and downloaded in the background. The user can provoke this process, or provide an update package manually.

Automatic updates should require user consent

This is achieved by not actually installing downloaded updates, but simply indicating to the user they are available. They can be installed by the user at-will.

Updates should be checked for consistency when applied

The MD5 hash for the updates should be included in the update package, as well as in the manifest that points to the update files. This is not yet complete

System functions affected by updates should be shut down when updates are conducted

This is achieved by a services list that is specified in update packages, which details which services must be disabled during installation/re-enabled once installation is complete.

Updates should manage configuration changes appropriately

It may make sense to provide a language for updates to add/remove and change configuration values, rather than replacing files wholesale. G2 configuration values for instance that are deprecated should be removed from the appropriate files, and it is burdensome to have the engine scrubbing files at startup. Radical sweeping changes however, may make this confusing and/or complicated. Additionally, it might make sense to make backups of configuration and settings before conducting an update. This is not yet complete

A failed update should result in the restoration to a previous or factory state

The process for this is outlined below:

  • An installation token file, called install_token lives alongside the software in the main directory
  • If the install token is present, it is assumed that the software was installed correctly by an updater
  • If the install token is missing, the software is assumed to be invalid
  • If the software is invalid, a reset to factory state is triggered, the factory software is unzipped to the appropriate directories, and the system settings are cleared. The install token file is written to indicate that this operation is successful.

The options below have yet to be implemented

  • An additional token is written to indicate that a factory reset has taken place, this token could go in the same place as a similar token that indicates that a normal update has taken place
  • The factory reset check is a run-once service that happens at boot time (but could be run on demand say, after an update procedure, to shore up any botched update activity)

An update should not be a generic script that can do any old thing

To deliver an update there are a couple of core functions, and everything else is handled by scaffolding:

  • Delete files
  • Copy files
  • Expand archives
  • Update configuration values ** Not yet implemented **
  • Write the "just updated" token ** Not yet implemented **

Update packages contain:

  • A manifest that includes:
    • The product to update
    • The new product version
    • A minimum version for the updater to successfully execute (ie you need at least updater 2.1 to run this package)
    • A changelog
    • A platform and operating system specification
    • A list of affected services
  • A list of operations to be conducted in order, which may include
    • Deleting files/directories
    • Copying files/directories (may be expanded from tarball)
    • Add/Update/Delete configuration JSON values ** Not yet implemented **

** Example: **

{
   product : 'FabMo-Engine',
   repository : 'https://github.com/FabMo/FabMo-Engine.git'
   os : 'linux',
   platform : 'edison',
   version : '1.2.3',
   md5 : '3b85ec9ab2984b91070128be6aae25eb',
   changeLogFile : 'changelog.txt',
   services : ['fabmo'],
   operations : [
      {
         op : 'deleteFiles'
         paths : [
            '/fabmo/engine/*'
            '/opt/fabmo/log'
         ]
      }
   ]
}