Skip to content
Snippets Groups Projects

Apertis Image Recipes

This repository contains the recipes used to build the Apertis reference images.

These recipes serve a few purposes:

  • build the reference images used to continuously validate Apertis itself;
  • provide some examples about the kind of images that Apertis can produce;
  • show how a complex set of images can be managed with a small set of templates.

It is important to note that no compatilbility guarantee is provided for use by directly importing them to build your own images.

The general suggestion is to roll your own recipes from scratch: a large part of the complexity in this repository is due to the number of different images and platform supported. This will be overkill for most projects, and using a simpler approach is going to work better in those cases.

If for any reason you deem desirable to import these recipes directly, it is strongly recommended to pin a particular version and/or take some measures to detect breaking changes early and act accordingly.

Getting started

To experiment with Apertis, begin with the sample-*.yaml recipes. They are a good starting point for building your own images based on the reference Apertis recipes.

From the Apertis SDK, build your first image:

$ sudo debos sample-image-development.yaml

The sample-image-development.yaml recipe builds an image suitable for the ARM-based i.MX6 SABRE Lite board with all the development tools installed.

Copy it to a SD card and then plug the SD card in your board to boot Apertis on it.

The image can be copied to the SD card by decompressing it and then copying the raw bytes using tools like dd.

If the SD Card reader is available from the Apertis SDK, the bmaptool command provides an alternative that is faster, more reliable and easy to use:

$ sudo bmaptool copy sample-development-*-fixedfunction-armhf.img.gz $SDCARD

You can now connect to your board via a serial connection, the default credentials are user:user.

Depending on your network setup, your board may also be available via SSH with the same credentials:

$ ssh user@apertis.local

With the development image you can install, remove, and update packages using the standard Debian tools like apt, including the GPLv3 components that are excluded by default from the Apertis image:

$ sudo apt install gdbserver

You can edit the recipe to customize the package selection, run custom scripts to change the rootfs contents, and download contents from remote sources.

For images to be deployed in production, Apertis uses OSTree to manage updates in a reliable way.

The sample-image-production.yaml recipe builds an image that boots into an OSTree deployment with the ability to automatically roll-back updates in case of boot failures:

$ sudo debos sample-image-production.yaml
$ sudo bmaptool copy sample-production-*-fixedfunction-armhf.img.gz $SDCARD

Providing a reproducible development environment is one of the key elements for Apertis, and the sample-image-sdk.yaml gives you the ability to generate your own SDK images, bootable in VirtualBox:

$ sudo debos --scratchsize 10G sample-image-sdk.yaml

You can then pick the generated VDI file and set it up in VirtualBox.

Customizing the recipes

Open the sample recipes and add, remove or edit their actions to make the generated artifacts suit your needs.

Some customization examples are already provided, check the Debos documentation for a full list of the available actions:

https://godoc.org/github.com/go-debos/debos/actions

The reference recipes

The main .gitlab-ci.yml orchestrates how platform-independent ospacks and platform-specific hwpacks are combined to generate all the reference artifacts.

Architectures supported via -t architecture:$VALUE:

  • arm64: (uboot) currently targets ARM 64bit Renesas R-Car boards
  • amd64: (uefi) supports any UEFI x86-64bit system
  • armhf: (uboot) currently targets the ARM 32bit i.MX6 SABRE Lite

Package set selection via -t type:$VALUE:

  • fixedfunction: headless system
  • target: HMI system
  • sdk: XFCE-based development environment with the HMI tools
  • basesdk: basic XFCE-based development environment
  • sysroot: cross-compilation target tarballs
  • devroot: emulation-based foreign platform build environments

Deployment types:

  • APT: suitable for development, prioritizes flexibility over robustness
  • OSTree: suitable for production, prioritizes robustness over flexibility

Firmware installer images:

  • u-boot automatic installer image for i.MX6 SABRE Lite
  • u-boot automatic installer image for i.MX8MN Variscite Symphony board

Parameters for ospack and image versioning:

  • suite: -t suite:v2021dev3
  • timestamp: -t timestamp:$(date +%s)

Building in Docker

To build in a reproducible environment outside of the Apertis SDK, using the pre-built Docker images in the Apertis registry is recommended:

$ RELEASE=v2021dev3 # the Apertis release to be built
$ docker run \
  -i -t --rm \
  -w /recipes \
  -v $(pwd):/recipes \
  --security-opt label=disable \
  -u $(id -u):$(id -g) \
  --group-add=$(getent group kvm | cut -d : -f 3) \
  --device /dev/kvm \
  --cap-add=SYS_PTRACE \
  --tmpfs /scratch:exec \
  registry.gitlab.apertis.org/infrastructure/apertis-docker-images/$RELEASE-image-builder \
  debos ospack-fixedfunction.yaml -t suite:$RELEASE

The image build will be run in the Docker container using your uid. By granting access to the KVM device where hardware virtualization is available Debos/Fakemachine can automatically select their KVM backend which provides better performance. Otherwise the ptrace and scratch tmpfs bits enable the use of the User Mode Linux backend, which works where hardware virtualization is not available, which is often the case on virtual machines in the cloud.

GitLab CI/CD automation

The reference images are built daily and for each commit with a rather big GitLab CI/CD pipeline.

The jobs in the pipeline make heavy usage of the image-builder Docker container image from the infrastructure/apertis-docker-images> project.

The .gitlab-ci.yml file defines all the jobs in the pipeline by instantiating the templates included from the .gitlab-ci/ folder:

  • templates-ospack-build.yml: building the hardware-agnostic portion of the rootfs (called ospack) for each architecture and image variant is the initial step of the build process, and this file provides the template for building them;
  • templates-ostree-commit.yml: this file provides the template to commit an ospack into an OSTree repository;
  • templates-artifacts-build.yml: all the templates producing the actual images and bundles for offline updates are here;
  • templates-upload.yml: contains the templates for uploading the artifacts to the storage server;
  • templates-submit-tests.yml: ships the template to submit test jobs to LAVA exercising the artifacts on actual hardware.

A current requirement for the upload jobs is the availability of ostree-push on the storage server to efficiently upload OSTree commits, while other artifacts are uploaded with rsync over SSH.

The GitLab runners for the build jobs need to be set up accordingly to the Building in Docker section to be able to run the UML backend for Debos:

  • --docker-cap-add=SYS_PTRACE
  • --docker-tmpfs='/scratch:rw,exec'

Signing keys

OSTree commits and static delta bundles can be signed using a pair of ed25519 keys. The public key used in Apertis should be copied to overlays/ed25519/usr/share/ostree/trusted.ed25519.d/apertis.ed25519. The private key needs to be specified via an ostree-receive config file on the server. (See .gitlab-ci/templates-upload.yml for where this file is used.)

The following commands can be used to generate the key pair:

  # Generate ed25519 certificate
$ openssl genpkey -algorithm ed25519 -outform PEM -out /tmp/key.pem

  # Extract the private and public parts from generated key.
  # Based on: http://openssl.6102.n7.nabble.com/ed25519-key-generation-td73907.html
$ ED25519PUBLIC="$(openssl pkey -outform DER -pubout -in ${pemfile} | tail -c 32 | base64)"
$ ED25519SEED="$(openssl pkey -outform DER -in ${pemfile} | tail -c 32 | base64)"
  # Secret key is concantination of SEED and PUBLIC
$ ED25519SECRET="$(echo ${ED25519SEED}${ED25519PUBLIC} | base64 -d | base64 -w 0)"

$ echo "ED25519PUBLIC = ${ED25519PUBLIC}"
$ echo "ED25519SECRET = ${ED25519SECRET}"