Creating Preloaded Images¶
The main purpose of the FoundriesFactory CI is to produce Targets. These Targets are
produced by two different types of CI builds: LmP platform and
container builds. By default, platform builds don’t include the Docker
Compose Apps and container images defined in the Target. In a similar
fashion container builds don’t produce an image that can be flashed to a
device.
As customers move closer to more formal phases of CI and/or production, they normally want each Target to have a complete image that can run without having to download container images. This can be done by configuring a Factory for “preloaded images”.
There are two ways to create these images:
- fioctl targets image
- configuring ci-scripts.git to preload each build
The easiest way to configure this is by updating a Factory’s
factory-config.yml in ci-scripts.git with:
lmp:
...
containers:
preloaded_images:
enabled: true
# Optional: The list of apps to preload can be with:
# containers:
# preloaded_images:
# enabled: true
# shortlist: "money-making-app,debug-tools"
For simple workflows, this may suffice. Because lmp configuration inherits from
containers, it will cause every Target built in the Factory to include and
enable all Docker Compose Apps.
The lmp can specify a different configuration or disable preload_images:
lmp:
preloaded_images:
enabled: false
# enabled: true
# shortlist: "money-making-app"
...
containers:
preloaded_images:
enabled: true
# Optional: The list of apps to preload can be with:
# containers:
# preloaded_images:
# enabled: true
# shortlist: "money-making-app,debug-tools"
And finally, it is possible to configure just lmp builds to preload containers.
In this case, because containers configuration doesn’t inherits from
lmp, container builds will not preload images:
lmp:
preloaded_images:
enabled: true
# Optional: The list of apps to preload can be with:
# lmp:
# preloaded_images:
# enabled: true
# shortlist: "money-making-app,debug-tools"
...
containers:
...
Common Advanced Scenario¶
It’s quite common to have more complex workflows. For example,
a Factory may have their containers.git set up with multiple branches and
each branch could specify a different set of applications.
For example, let’s assume you have 4 different branches with the following application:
# devel and experimental:
money-making-app - The "product"
debug-tools - A compose app with some tooling used for development
# master:
money-making-app - The "product"
fiotest - A compose-app that some devices run for QA.
# production:
money-making-app - The "product"
In this scenario, it is possible to configure each Target individually to preload different applications in its image.
This can be configured by additional variables on ref_options.
ref_options:
refs/heads/devel:
params:
APP_SHORTLIST: "<app1>,<app2>,<...>"
ASSEMBLE_SYSTEM_IMAGE: "<1|0> "
APP_SHORTLIST- Overrides the list of application.ASSEMBLE_SYSTEM_IMAGE- To enable|disable preloading Apps.
Let’s assume you want to produce the following types of Targets:
develpreloaded with themoney-making-appanddebug-tools.masterandproductionpreloaded with themoney-making-app.experiementalwill not preload anything .
This can be configured in factory-config.yml with:
lmp:
tagging:
# Use a "production" branch, that may have some special platform
# features enabled/disabled. However, it still uses the containers
# from master for its apps:
refs/heads/production:
- tag: production
inherit: master
...
containers:
preloaded_images:
enabled: true
shortlist: "money-making-app"
tagging:
# Changes to containers master create both "master" and "production" tagged targets
refs/heads/master:
- tag: master
- tag: production
refs/heads/devel:
- tag: devel
ref_options:
refs/heads/devel:
params:
APP_SHORTLIST: "money-making-app,debug-tools"
refs/heads/experimental:
params:
# Don't produce a preloaded system image
ASSEMBLE_SYSTEM_IMAGE: "0"
With this configuration in place, the factory will produce Targets with the correct apps preloaded and enabled by default.
Starting compose apps early¶
Preloading docker images doesn’t mean the compose apps start automatically. Usually compose apps are started by aktualizr-lite after device registration. However, aktualizr-lite first checks for available updates. If there is a new target available compose apps will only be started after the update is performed.
Note
Note that this mainly applies to the first launch of compose apps. If
docker-compose.yml contains restart clause, the container will be started
by dockerd on subsequent boots.
In some scenarios it is required that compose apps start before device registration and before aktualizr-lite on a freshly flashed device. This can be done using one off systemd service and image with pre-loaded containers.
Example compose apps early start script can be found in meta-lmp:
The recipe produces a systemd one off service and shell script.
Note
The systemd startup service only runs when the device is not registered to the Foundries Factory. Otherwise the script is not executed.
The following patch for meta-subscriber-overrides is required to add the recipe to the lmp-factory-image
--- a/recipes-samples/images/lmp-factory-image.bb +++ b/recipes-samples/images/lmp-factory-image.bb @@ -24,9 +24,10 @@ CORE_IMAGE_BASE_INSTALL += " \ networkmanager-nmcli \ git \ vim \ + compose-apps-early-start \ packagegroup-core-full-cmdline-utils \ packagegroup-core-full-cmdline-extended \ packagegroup-core-full-cmdline-multiuser \
The shell script checks for the list of compose apps to start in the
/var/lmp/default-apps file. This file can’t be provided by OSTree so it needs
to be created at runtime. If the file is not present all available compose
apps are started.
Compose apps listed in the default-apps file should be started as soon as the docker service is started. In addition to that, when restart clause is present in the compose app service, it will be started by dockerd on every boot if it was at least once started by the script. Example:
services:
fiotest:
image: hub.foundries.io/demo/fiotest
restart: always