Uploaded image for project: 'Mender'
  1. Mender
  2. MEN-1174

Discuss whether to make install scripts support most of Mender's install states



    • Type: Task
    • Status: Done
    • Priority: Medium
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:


      From customer in this document:

      They need some kind of notification of update in progress to allow their logic to make changes such as not disabling wifi, etc when an update is downloading. They didn’t say it, but I suspect there is a need for a number of different states to be reported here.

      Debian packages have a similar concept where its scripts are called with a state parameter that describes which stage in the install the package manager is currently doing. Pre- and postinstall are two of these stages, but there are many more. I think this generalization makes a lot of sense for Mender as well.

      Acceptance criteria for this task:

      • Figure out if such a state based scripting mechanism makes sense for Mender.
        • Example: When entering download, call this script: ./install-script download-state
        • Then, we about to reboot, call this script: ./install-script reboot-state
      • Turn our current Mender states into some sort of stable API.
        • We can't change this once we publish it.
        • It doesn't have to be a 1-to-1 relationship, we can have more internal states than we publish in the API.
      • The proposal should support states that need to be confirmed, such as a ok-to-reboot state, where the script, if it exists, need to approve reboot. Obviously there needs to be a way to query this script repeatedly in an efficient manner. This also relates to possible DBUS support, but that may be outside the scope of this ticket.

      Current proposal


      State hooks

      • Each state has an enter/leave and error hook
      • All hooks have a configurable timeout, at which point the update will fail.
      • The order of hooks for each state is:
        • Leave old state
        • If error happens while executing action inside given state error hook is called (this is true for errors happening while executing enter and leave scripts as well)
        • Enter new state

      The states

      • Like an API, not necessarily 1-to-1 mapping with Mender client implementation
      • Deliberately avoiding the word "update" since we decided it was ambiguous. Will stick to "artifact"
      • States:
        • Idle
        • Sync
        • Download
          • Encompasses all bootstrapping, inventory updates, checking for deployment, etc.
        • ArtifactInstall
          • For rootfs this one will just be flipping partition, since content writing is done during download
        • ArtifactReboot
          • Long term this an optional state (package updates usually don't need a reboot)
          • This is ONLY called while rebooting device after installing an update; won't be called during any other reboot attempt
        • ArtifactCommit
          • This state will serve as the verify step for install scripts
        • ArtifactRollback
          • For rootfs, flips back partition
        • ArtifactRollbackReboot
          • Separate from the reboot state because reboot state needs approval, whereas rollback should not
        • ArtifactFailure
          • Called if any of the artifact (download, install, commit, ...) related action fails

      Order that states will usually be executed in:

      • Idle
      • Sync
      • Download
      • ArtifactInstall
      • ArtifactReboot
      • ArtifactCommit

      Remaining states are failure states and can be entered almost anywhere


      Script locations

      Because not all states are necessarily dealing with an artifact, there are various locations where scripts will be grabbed from, and this needs to be well defined

      State \ script location Rootfs-hosted Artifact-hosted[2]
      Idle X  
      Sync X  
      Download X  
      ArtifactInstall   X
      ArtifactReboot   X
      ArtifactCommit   X
      ArtifactRollback   X
      ArtifactRollbackReboot   X
      ArtifactFailure   X

      The two groups are located in different filesystem locations, and should be kept in:

      • Rootfs-hosted: /etc/mender/scripts
      • Artifact-hosted: /var/lib/mender/scripts

      Along with the scripts, the version of the artifact should be stored, and the Mender client should check this version before attempting to run any script. This is to avoid the situation where you change the version of the agent and the new one doesn't understand the script semantics of the old one. IOW, if you use any scripts at all, then both the agent you upgrade from, and the one you upgrade to, have to understand the version of the artifact you're using to upgrade.

      Script running

      All scripts will be run without arguments.

      All scripts must run under a timeout, which could potentially be different for different types of scripts (TBD).

      In addition, each script invocation must be remembered in the local database, so that it can be repeated if he node reboots spontaneously. Probably the same should be the case for timeouts, so that reboots do not prolong timeouts indefinitely.

      Script form

      Each state/event pair can have a number of scripts, indexed by to leading digits and an underscore. They can also have an optional dot followed by an arbitrary string, for identification. Example:

      ...and so on...

      The ordering within each pair does not influence other pairs, IOW, when executing Download_Enter scripts, only digit orderings within that group are considered. All scripts are executed in ascending order.

      No script in the same state/event category can have the same two digits, even if the name after the optional dot is different (to prevent ambiguous execution order).

      See also the changes to the format documentation.

      Idle and Sync scripts will reside under /etc/mender/scripts, and are expected to be included in the update itself.

      The rest will reside inside the artifact according to the artifact documentation. When the artifact is parsed/prepared, all scripts should be simultaneously extracted to /var/lib/mender/scripts. Alongside them, the version file from the top level of the artifact should also be extracted. This will be checked on every script execution that it matches a version that the Mender agent understands.


      [2] If inside artifact, the script must be extracted and run from the /data partition. The rootfs partition can not be used because we need to support read-only rootfs.


          Issue Links



              a10040 Kristian Amlie
              a10040 Kristian Amlie
              0 Vote for this issue
              3 Start watching this issue



                  Zendesk Support