286 lines
12 KiB
ReStructuredText
286 lines
12 KiB
ReStructuredText
|
.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
|
|||
|
|
|||
|
*******************************************
|
|||
|
Understanding the Yocto Project Autobuilder
|
|||
|
*******************************************
|
|||
|
|
|||
|
Execution Flow within the Autobuilder
|
|||
|
=====================================
|
|||
|
|
|||
|
The "a-full" and "a-quick" targets are the usual entry points into the
|
|||
|
Autobuilder and it makes sense to follow the process through the system
|
|||
|
starting there. This is best visualized from the Autobuilder Console
|
|||
|
view (:yocto_ab:`/typhoon/#/console`).
|
|||
|
|
|||
|
Each item along the top of that view represents some "target build" and
|
|||
|
these targets are all run in parallel. The 'full' build will trigger the
|
|||
|
majority of them, the "quick" build will trigger some subset of them.
|
|||
|
The Autobuilder effectively runs whichever configuration is defined for
|
|||
|
each of those targets on a separate buildbot worker. To understand the
|
|||
|
configuration, you need to look at the entry on ``config.json`` file
|
|||
|
within the ``yocto-autobuilder-helper`` repository. The targets are
|
|||
|
defined in the ‘overrides' section, a quick example could be qemux86-64
|
|||
|
which looks like::
|
|||
|
|
|||
|
"qemux86-64" : {
|
|||
|
"MACHINE" : "qemux86-64",
|
|||
|
"TEMPLATE" : "arch-qemu",
|
|||
|
"step1" : {
|
|||
|
"extravars" : [
|
|||
|
"IMAGE_FSTYPES:append = ' wic wic.bmap'"
|
|||
|
]
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
And to expand that, you need the "arch-qemu" entry from
|
|||
|
the "templates" section, which looks like::
|
|||
|
|
|||
|
"arch-qemu" : {
|
|||
|
"BUILDINFO" : true,
|
|||
|
"BUILDHISTORY" : true,
|
|||
|
"step1" : {
|
|||
|
"BBTARGETS" : "core-image-sato core-image-sato-dev core-image-sato-sdk core-image-minimal core-image-minimal-dev core-image-sato:do_populate_sdk",
|
|||
|
"SANITYTARGETS" : "core-image-minimal:do_testimage core-image-sato:do_testimage core-image-sato-sdk:do_testimage core-image-sato:do_testsdk"
|
|||
|
},
|
|||
|
"step2" : {
|
|||
|
"SDKMACHINE" : "x86_64",
|
|||
|
"BBTARGETS" : "core-image-sato:do_populate_sdk core-image-minimal:do_populate_sdk_ext core-image-sato:do_populate_sdk_ext",
|
|||
|
"SANITYTARGETS" : "core-image-sato:do_testsdk core-image-minimal:do_testsdkext core-image-sato:do_testsdkext"
|
|||
|
},
|
|||
|
"step3" : {
|
|||
|
"BUILDHISTORY" : false,
|
|||
|
"EXTRACMDS" : ["${SCRIPTSDIR}/checkvnc; DISPLAY=:1 oe-selftest ${HELPERSTMACHTARGS} -j 15"],
|
|||
|
"ADDLAYER" : ["${BUILDDIR}/../meta-selftest"]
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
Combining these two entries you can see that "qemux86-64" is a three step build where the
|
|||
|
``bitbake BBTARGETS`` would be run, then ``bitbake SANITYTARGETS`` for each step; all for
|
|||
|
``MACHINE="qemx86-64"`` but with differing SDKMACHINE settings. In step
|
|||
|
1 an extra variable is added to the ``auto.conf`` file to enable wic
|
|||
|
image generation.
|
|||
|
|
|||
|
While not every detail of this is covered here, you can see how the
|
|||
|
template mechanism allows quite complex configurations to be built up
|
|||
|
yet allows duplication and repetition to be kept to a minimum.
|
|||
|
|
|||
|
The different build targets are designed to allow for parallelization,
|
|||
|
so different machines are usually built in parallel, operations using
|
|||
|
the same machine and metadata are built sequentially, with the aim of
|
|||
|
trying to optimize build efficiency as much as possible.
|
|||
|
|
|||
|
The ``config.json`` file is processed by the scripts in the Helper
|
|||
|
repository in the ``scripts`` directory. The following section details
|
|||
|
how this works.
|
|||
|
|
|||
|
Autobuilder Target Execution Overview
|
|||
|
=====================================
|
|||
|
|
|||
|
For each given target in a build, the Autobuilder executes several
|
|||
|
steps. These are configured in ``yocto-autobuilder2/builders.py`` and
|
|||
|
roughly consist of:
|
|||
|
|
|||
|
#. *Run clobberdir*.
|
|||
|
|
|||
|
This cleans out any previous build. Old builds are left around to
|
|||
|
allow easier debugging of failed builds. For additional information,
|
|||
|
see :ref:`test-manual/understand-autobuilder:clobberdir`.
|
|||
|
|
|||
|
#. *Obtain yocto-autobuilder-helper*
|
|||
|
|
|||
|
This step clones the ``yocto-autobuilder-helper`` git repository.
|
|||
|
This is necessary to prevent the requirement to maintain all the
|
|||
|
release or project-specific code within Buildbot. The branch chosen
|
|||
|
matches the release being built so we can support older releases and
|
|||
|
still make changes in newer ones.
|
|||
|
|
|||
|
#. *Write layerinfo.json*
|
|||
|
|
|||
|
This transfers data in the Buildbot UI when the build was configured
|
|||
|
to the Helper.
|
|||
|
|
|||
|
#. *Call scripts/shared-repo-unpack*
|
|||
|
|
|||
|
This is a call into the Helper scripts to set up a checkout of all
|
|||
|
the pieces this build might need. It might clone the BitBake
|
|||
|
repository and the OpenEmbedded-Core repository. It may clone the
|
|||
|
Poky repository, as well as additional layers. It will use the data
|
|||
|
from the ``layerinfo.json`` file to help understand the
|
|||
|
configuration. It will also use a local cache of repositories to
|
|||
|
speed up the clone checkouts. For additional information, see
|
|||
|
:ref:`test-manual/understand-autobuilder:Autobuilder Clone Cache`.
|
|||
|
|
|||
|
This step has two possible modes of operation. If the build is part
|
|||
|
of a parent build, it's possible that all the repositories needed may
|
|||
|
already be available, ready in a pre-prepared directory. An "a-quick"
|
|||
|
or "a-full" build would prepare this before starting the other
|
|||
|
sub-target builds. This is done for two reasons:
|
|||
|
|
|||
|
- the upstream may change during a build, for example, from a forced
|
|||
|
push and this ensures we have matching content for the whole build
|
|||
|
|
|||
|
- if 15 Workers all tried to pull the same data from the same repos,
|
|||
|
we can hit resource limits on upstream servers as they can think
|
|||
|
they are under some kind of network attack
|
|||
|
|
|||
|
This pre-prepared directory is shared among the Workers over NFS. If
|
|||
|
the build is an individual build and there is no "shared" directory
|
|||
|
available, it would clone from the cache and the upstreams as
|
|||
|
necessary. This is considered the fallback mode.
|
|||
|
|
|||
|
#. *Call scripts/run-config*
|
|||
|
|
|||
|
This is another call into the Helper scripts where it's expected that
|
|||
|
the main functionality of this target will be executed.
|
|||
|
|
|||
|
Autobuilder Technology
|
|||
|
======================
|
|||
|
|
|||
|
The Autobuilder has Yocto Project-specific functionality to allow builds
|
|||
|
to operate with increased efficiency and speed.
|
|||
|
|
|||
|
clobberdir
|
|||
|
----------
|
|||
|
|
|||
|
When deleting files, the Autobuilder uses ``clobberdir``, which is a
|
|||
|
special script that moves files to a special location, rather than
|
|||
|
deleting them. Files in this location are deleted by an ``rm`` command,
|
|||
|
which is run under ``ionice -c 3``. For example, the deletion only
|
|||
|
happens when there is idle IO capacity on the Worker. The Autobuilder
|
|||
|
Worker Janitor runs this deletion. See :ref:`test-manual/understand-autobuilder:Autobuilder Worker Janitor`.
|
|||
|
|
|||
|
Autobuilder Clone Cache
|
|||
|
-----------------------
|
|||
|
|
|||
|
Cloning repositories from scratch each time they are required was slow
|
|||
|
on the Autobuilder. We therefore have a stash of commonly used
|
|||
|
repositories pre-cloned on the Workers. Data is fetched from these
|
|||
|
during clones first, then "topped up" with later revisions from any
|
|||
|
upstream when necessary. The cache is maintained by the Autobuilder
|
|||
|
Worker Janitor. See :ref:`test-manual/understand-autobuilder:Autobuilder Worker Janitor`.
|
|||
|
|
|||
|
Autobuilder Worker Janitor
|
|||
|
--------------------------
|
|||
|
|
|||
|
This is a process running on each Worker that performs two basic
|
|||
|
operations, including background file deletion at IO idle (see :ref:`test-manual/understand-autobuilder:Autobuilder Target Execution Overview`: Run clobberdir) and
|
|||
|
maintenance of a cache of cloned repositories to improve the speed
|
|||
|
the system can checkout repositories.
|
|||
|
|
|||
|
Shared DL_DIR
|
|||
|
-------------
|
|||
|
|
|||
|
The Workers are all connected over NFS which allows DL_DIR to be shared
|
|||
|
between them. This reduces network accesses from the system and allows
|
|||
|
the build to be sped up. Usage of the directory within the build system
|
|||
|
is designed to be able to be shared over NFS.
|
|||
|
|
|||
|
Shared SSTATE_DIR
|
|||
|
-----------------
|
|||
|
|
|||
|
The Workers are all connected over NFS which allows the ``sstate``
|
|||
|
directory to be shared between them. This means once a Worker has built
|
|||
|
an artifact, all the others can benefit from it. Usage of the directory
|
|||
|
within the directory is designed for sharing over NFS.
|
|||
|
|
|||
|
Resulttool
|
|||
|
----------
|
|||
|
|
|||
|
All of the different tests run as part of the build generate output into
|
|||
|
``testresults.json`` files. This allows us to determine which tests ran
|
|||
|
in a given build and their status. Additional information, such as
|
|||
|
failure logs or the time taken to run the tests, may also be included.
|
|||
|
|
|||
|
Resulttool is part of OpenEmbedded-Core and is used to manipulate these
|
|||
|
json results files. It has the ability to merge files together, display
|
|||
|
reports of the test results and compare different result files.
|
|||
|
|
|||
|
For details, see :yocto_wiki:`/Resulttool`.
|
|||
|
|
|||
|
run-config Target Execution
|
|||
|
===========================
|
|||
|
|
|||
|
The ``scripts/run-config`` execution is where most of the work within
|
|||
|
the Autobuilder happens. It runs through a number of steps; the first
|
|||
|
are general setup steps that are run once and include:
|
|||
|
|
|||
|
#. Set up any ``buildtools-tarball`` if configured.
|
|||
|
|
|||
|
#. Call "buildhistory-init" if buildhistory is configured.
|
|||
|
|
|||
|
For each step that is configured in ``config.json``, it will perform the
|
|||
|
following:
|
|||
|
|
|||
|
#. Add any layers that are specified using the
|
|||
|
``bitbake-layers add-layer`` command (logging as stepXa)
|
|||
|
|
|||
|
#. Call the ``scripts/setup-config`` script to generate the necessary
|
|||
|
``auto.conf`` configuration file for the build
|
|||
|
|
|||
|
#. Run the ``bitbake BBTARGETS`` command (logging as stepXb)
|
|||
|
|
|||
|
#. Run the ``bitbake SANITYTARGETS`` command (logging as stepXc)
|
|||
|
|
|||
|
#. Run the ``EXTRACMDS`` command, which are run within the BitBake build
|
|||
|
environment (logging as stepXd)
|
|||
|
|
|||
|
#. Run the ``EXTRAPLAINCMDS`` command(s), which are run outside the
|
|||
|
BitBake build environment (logging as stepXd)
|
|||
|
|
|||
|
#. Remove any layers added in step
|
|||
|
1 using the ``bitbake-layers remove-layer`` command (logging as stepXa)
|
|||
|
|
|||
|
Once the execution steps above complete, ``run-config`` executes a set
|
|||
|
of post-build steps, including:
|
|||
|
|
|||
|
#. Call ``scripts/publish-artifacts`` to collect any output which is to
|
|||
|
be saved from the build.
|
|||
|
|
|||
|
#. Call ``scripts/collect-results`` to collect any test results to be
|
|||
|
saved from the build.
|
|||
|
|
|||
|
#. Call ``scripts/upload-error-reports`` to send any error reports
|
|||
|
generated to the remote server.
|
|||
|
|
|||
|
#. Cleanup the build directory using
|
|||
|
:ref:`test-manual/understand-autobuilder:clobberdir` if the build was successful,
|
|||
|
else rename it to "build-renamed" for potential future debugging.
|
|||
|
|
|||
|
Deploying Yocto Autobuilder
|
|||
|
===========================
|
|||
|
|
|||
|
The most up to date information about how to setup and deploy your own
|
|||
|
Autobuilder can be found in README.md in the ``yocto-autobuilder2``
|
|||
|
repository.
|
|||
|
|
|||
|
We hope that people can use the ``yocto-autobuilder2`` code directly but
|
|||
|
it is inevitable that users will end up needing to heavily customise the
|
|||
|
``yocto-autobuilder-helper`` repository, particularly the
|
|||
|
``config.json`` file as they will want to define their own test matrix.
|
|||
|
|
|||
|
The Autobuilder supports wo customization options:
|
|||
|
|
|||
|
- variable substitution
|
|||
|
|
|||
|
- overlaying configuration files
|
|||
|
|
|||
|
The standard ``config.json`` minimally attempts to allow substitution of
|
|||
|
the paths. The Helper script repository includes a
|
|||
|
``local-example.json`` file to show how you could override these from a
|
|||
|
separate configuration file. Pass the following into the environment of
|
|||
|
the Autobuilder::
|
|||
|
|
|||
|
$ ABHELPER_JSON="config.json local-example.json"
|
|||
|
|
|||
|
As another example, you could also pass the following into the
|
|||
|
environment::
|
|||
|
|
|||
|
$ ABHELPER_JSON="config.json /some/location/local.json"
|
|||
|
|
|||
|
One issue users often run into is validation of the ``config.json`` files. A
|
|||
|
tip for minimizing issues from invalid json files is to use a Git
|
|||
|
``pre-commit-hook.sh`` script to verify the JSON file before committing
|
|||
|
it. Create a symbolic link as follows::
|
|||
|
|
|||
|
$ ln -s ../../scripts/pre-commit-hook.sh .git/hooks/pre-commit
|