Skip to content
Snippets Groups Projects

System OTA for Linux Gateways

System OTA is a robust, unattended update system for Linux Gateways, suitable for home automation gateways and other devices where reliability is paramount.

Architecture Overview

The update system is comprised of the following elements:

  • Immutable file system used as rootfs with:
    • Provisions for maintaining state of select files and directories.
    • RAUC pre-installed and pre-configured for storage slots.
    • SysOTA pre-installed and pre-configured for the boot loader, update server and package name.
  • Shared or dedicated[1] NetOTA server providing update meta-data.
  • Shared or dedicated public storage server for storing image blobs.

Shared or dedicated in the sense that either a special purpose installation or a shared installation used by many different device types, operators and manufacturers are both allowed by the system.

Development

This is a somewhat typical Go and make project. You can use plain go to build and test most things. For a more complete experience, including to access the set of integration tests and various static analysis tools, you should install a few more dependencies:

  • make
  • zmk
  • reuse
  • spread

Running make will build everything. There's a build-time configuration system. To create the configure script run make configure.

To try the service out in practice you may want to do this though:

make configure
./configure --prefix=/usr
make
sudo make install
sudo systemctl enable sysotad.service

As you iterate you may need to refresh in-memory definition of systemd unit files:

sudo systemctl daemon-reload

To remove what you've installed run the uninstall target:

sudo make uninstall

Remember that uninstall is stateless, if you want to rename a file, first uninstall, then rename and finally install again.

Testing

The project has a combination of unit tests, available through the standard go interface, and integration tests implemented with spread. To run all kinds of tests invoke make check. This will skip and report tests that depend on tools you do not have locally.

Please try not to send patches which regress the test suite.

Go Unit Tests

There's a wide range of standard Go unit tests available. To execute those simply run:

go test ./...

Go Static Analysis

SystemOTA uses a wide array of Go static analysis tools, including the standard go vet as well as the third-party: staticcheck, goconst, errcheck, wsl and ineffassign.

All those checks are integrated into make check and make static-check. The precise goals for each individual tool can be discovered by tab-completing make static-check-go-.

The tools are usually not packaged so you should install them directly. Assuming you are using Go 1.16+ you can do that with with:

go install honnef.co/go/tools/cmd/staticcheck@latest
go install github.com/jgautheron/goconst/cmd/goconst@latest
go install github.com/kisielk/errcheck@latest
go install github.com/bombsimon/wsl/v3/...@latest
go install github.com/gordonklaus/ineffassign@latest

REUSE compliance checks

REUSE is a legal compliance toolchain which, among others, ensures that each file is accompanied by a machine readable copyright and license.

REUSE checks are integrated into make check and make static-check. The precise goal is make static-check-reuse.

The REUSE toolchain can be installed from the system packager (usually something like python3-reuse) or with pip by running:

pip install reuse

Spell checker

SystemOTA uses a cspell based spell checker. The same spell checker, along with the exception database, can be used from Visual Studio Code and from command line. The list of known exceptions is kept in the file cspell.json.

The spell checker is integrated into make check and make static-check. The precise goals make static-cspell-lint.

To install the cspell with npm by running:

npm install --global cspell

Spread system checks

To execute integration tests you will need a working installation of spread and lxd or qemu. Currently Qemu is preferred, as it allows performing mount operations inside the virtual machine. GitLab CI also uses qemu as LXD cannot be used from a docker container. For more information on how to prepare a test environment with qemu, refer to the spread-qemu-hirsute job defined in .gitlab-ci.yml file.

A compatible build of spread is available from the Ubuntu PPA ppa:zyga/oh-tools. It can be also compiled from sources at https://git.ostc-eu.org/OSTC/tools/oh-spread/.

LXD is available as a snap package. Install it with sudo snap install lxd and then initialize it with sudo lxd init --auto.

To execute integration tests run:

make check-spread

If you use spread directly you may want to pass some options to spread, namely -reuse -resend to speed up subsequent runs by keeping the ephemeral container or virtual machine, with all the build dependencies and cache, around.

Packaging

If you are looking at packaging, the typical ./configure --prefix=/usr && make && make install trio should do the trick but for a real installation you will need to configure SystemOTA and RAUC inside your operating system image, at least to select the boot loader and to describe the partition layout to RAUC.

You may want to enable the sysotad.service systemd unit after installation.

Yocto meta-layers

There's an official meta-layer with SystemOTA in the Oniro repository at https://booting.oniroproject.org/distro/oniro/ in the meta-oniro-core layer.