aboutsummaryrefslogtreecommitdiffstats
Setting up a Yocto Autobuilder Build Cluster
============================================

Most autobuilder setups are individual to the circumstances of the
user. This document outlines some of the configuration options/files,
autobuilder setup gotchas and general autobuilder best practices.

Setup to run headless sanity tests
===================================

If you plan on using the yocto autobuilder to run sanity testing,
you will need to:

1. Install tight-vnc client and server.

2. Set up tap devs by running poky/scripts/runqemu-setup-tapdev

3. Add "xterm*vt100*geometry: 80x50+10+10" to .Xdefaults

4. Setup and start vnc session as the autobuilder user.

5. You MUST manually connect to the vnc session at least once prior to
   running a qemu sanity test (Something is getting set during the initial
   connection that I haven't figured out yet. Manually connecting seems to
   set up the session correctly.)

Adding additional build workers
===============================

The production yocto autobuilder uses a cluster of build workers, all
sharing the same SSTATE_DIR and DL_DIR via an NFS4 mounted NAS. The main
nightly trigger prepopulates the DL_DIR, allowing the workers to not have
to deal with a lot of downloading. In theory you could also run your build
workers with NO_NETWORK to enforce a single point of populating DL_DIR.

Running multiple build workers is fairly simple, but does require some setup:

a. Ensure the settings in autobuilder.conf are valid for each buildworker,
   As certain variables are set within this file that are work with the
   local configuruation on each builder.

b. Within yocto-controller/controller.cfg add your worker to the
   c['workers'] list inside of the BUILDWORKERS section

c. For each build worker change the WORKER SETTINGS section of
   yocto-worker/buildbot.tac to match the settings in controller.cfg.

Setting up build history
========================

Build History is used to track changes to packages and images. By default
the autobuilder does not collect build history. The production autobuilder
does have this functionality enabled.

Setting up build history requires the following steps:

1. Create an empty git repo. Make a single commit to it and the create and
   push branches for each of the nightly core architectures (ie. mips, ppc,
   x86...)

2. Find a central location to create a clone for this. This works best if
   you have a set up similar to the production autobuilder (NAS with many
   builders)

3. Run the following:

    # This is an example of how to set up a local build history checkout. Paths
    # obviously are situation dependant.
    mkdir /nas/buildhistory
    cd /nas/buildhistory
    git clone ssh://git@git.myproject.org/buildhistory
    git clone ssh://git@git.myproject.org/buildhistory nightly-arm
    git clone ssh://git@git.myproject.org/buildhistory nightly-x86
    git clone ssh://git@git.myproject.org/buildhistory nightly-x86-64
    git clone ssh://git@git.myproject.org/buildhistory nightly-ppc
    git clone ssh://git@git.myproject.org/buildhistory nightly-mips
    for x in `ls|grep nightly` do cd $x; git checkout $x; cd /nas/buildhistory; done

4. Within the autobuilder.conf of EACH slave change the following:

    BUILD_HISTORY_COLLECT = True
    BUILD_HISTORY_DIR = "/nas/buildhistory"
    BUILD_HISTORY_REPO = "ssh://git@git.myproject.org/buildhistory"

Introduction
============

Prior versions of the yocto-autobuilder required an extensive knowledge of
buildbot as well as basic python. Over the years, as more targets were added
the main configuation file had become hard to maintain, harder to read and,
frankly, was not utilizing the power of buildbot. This document will explain
some of the rational behind the refactor, introduce end users to the new
configuration language, introduce the concept of customized buildsteps and
give some basic instruction on how to modify an autobuilder setup.

TODO
====

- buildhistory is not functional
- still missing some needed build targets
    - oe-core
    - fsl
    - p1022ds
    - bunch of meta-intel
    -
- minor UI cleanup for toggling of triggered layers
- bbpriority needs to work
- verify buildappsrcrev
- deploy stuff
- killing triggers. this has been a long standing issue. look into

What is it
==========

Yocto Autobuilder is essentially some extension to the vanilla build bot.
This extension mainly addresses configuration file handling and Yocto specific
build steps.
For better maintainability, the Autobuilder (see Autobuilder.py located at
lib/python2.7/site-packages/autobuilder/), handles configuration from multiple
files.
Additional build steps such as CheckOutLayers.py or CreateBBLayersConf are
Yocto specific and simplify the bulders configuration.

Setup
=====

git clone git://git.yoctoproject.org/yocto-autobuilder
cd yocto-autobuilder
. ./yocto-autobuilder-setup
yocto-start-autobuilder both

Configuration
=============

In the bad old days, the yocto-autobuilder configuration was stored in a single
file. This file contained both build target definitions as well as helper code/
custom buildsteps. This was obviously a "bad thing". We've now removed all
build target configuration out into the config/* directory

Files
=====

There are two needed files in this directory. One file, autobuilder.conf, is a
global definition file which sets various globals that slaves and master need
to know about. This hasn't really changed from prior versions.

One new file is yoctoAB.conf. This is the only required file needed for build
target definitions. However, as it would be a bad practice to have all build
targets within a single file, you may define build targets in other *.conf files.
As long as those conf files live within the config directory, the
yocto-autobuilder will automatically load them. This allows us to keep things
nice and neat.

Files used for Yocto-Autobuilder Configuration
==============================================

Name: conf/autobuilder.conf
Purpose:
This file is used to set autobuilder wide parameters, like where various build
artifacts are published to, DL_DIR, SSTATE_DIR or if build artifacts should be
published (needed for production autobuilders, not needed for desktop builders)

Name: conf/yoctoAB.conf
Purpose:
This is the main yocto autobuilder config. Documentation for this and associated
format is in README_CONFIG

yoctoAB.conf
============

The main BuildSets section required for the configuration contains a single
property:

[BuildSets]
order: ['nightly', 'nightly-x86']

The order property tells buildbot what order you wish to display build targets
in on the waterfall page. This can not be used with vanilla buildbot as there is
a small patch required to utilize this functionality.

buildset configuration
======================

Each buildset must start with a section name followed by at three to four
properties:

builders: A string or list of builders used to build the buildset

repos: A list of dicts. Each item will contain a dict entry:

        'name_of_repo':
                    {'repourl':'git://path.to/git_repo',
                     'bbpriority':'1',
                     'branch':'master'}}

NOTE: bbpriority is currently not used

props: A list of dicts. This is used when you need to add properties to a
       builder. An example of this would be build-appliance which needs to have
       a buildappsrcrev property passed so it knows which version from the poky
       repo to pull. prop_type is basically buildbot scheduler properties with
       the args sent as dict pairs. See:
       http://buildbot.net/buildbot/docs/0.8.6/manual/cfg-schedulers.html#forcesched-parameters

steps: A list of dicts. These steps can be either custom buildsteps or basic
       buildbot buildsteps with args passed as dict pairs. Custom buildsteps
       that we utilize are in lib/python2.7/site-packages/autobuilder/buildsteps.

       CreateBBLayersConf: This build step creates the bblayers.conf used by the
       build system to determine which layers to use and where to find them.

          {'CreateBBLayersConf': {'buildprovider' : 'yocto',
            'bsplayer':'True',
            'bspprovider':'intel',
            'bbtextprepend':'text_to_prepend',
            'bbtextappend':'text_to_append',
            'layerdirs': ['layerdir1', 'layerdir2', ...]}}

          buildprovider: Optional and defaults to 'yocto'.  If this is set to
          'yocto', then it adds the layers' 'meta', 'meta-yocto' and
          'meta-yocto-bsp' to BBLAYERS. If set to 'oe', then only 'meta' is
          added to BBLAYERS.

          bsplayer: Optional and defaults to False.  Set this to 'True' if you
          want to use an established BSP layer and include its default layers.

          bspprovider: Required if bsplayer is set to True.  Defines the BSP
          provider so the default layers can be included.  At this time only
          'intel', 'fsl-ppc' and 'fsl-arm' are recognized.

          bbtextprepend: Prepends the given text to bblayers.conf.  Use \n in
          the text to start a new line and always end the text with a \n.  For
          example:
              'bbtextprepend': '#Adding one comment line\n#Adding a second comment line\n'

          bbtextappend: Appends the given text to bblayers.conf.  Same format
          as bbtextprepend.

          layerdirs: Used to add layers to BBLAYERS.  Layers are added in the
          order specified and are added after the layers created by the
          buildprovider.  For example:
              'layerdirs': ['meta-openembedded/meta-oe',
                  'meta-openembedded/meta-networking',
                  'meta-openembedded/meta-gnome']
          will append the layers meta-openembedded/meta-oe,
          meta-openembedded/meta-networking, and meta-openembedded/meta-gnome
          to BBLAYERS.  Note that this will override any default layers from a
          bspprovider.

scheduler: A list of dicts. Each item defines a scheduler associated with this
       buildset:

       'name_of_scheduler':
                 {'type': 'Nightly'}

       The scheduler type is specified by the 'type' property, where supported
       values are 'Nightly' or 'SingleBranchScheduler', with 'Nightly' as the
       default. Additional properties are used to configure the scheduler and
       are type-specific:

          Nightly scheduler properties:
               month: The month in which to start the build, with January = 1.
                    This defaults to '*', meaning every month.
               dayOfWeek: The day of the week in which to start the build, with
                    Monday = 1.  This defaults to '*', meaning every day.
           hour: The hour of the day in which to start the build, with
                    12:00 AM = 0.  This must be set by the user.
           minute: The minute of the hour in which to start the build, with
                    0 to 59 as valid values.  This must be set by the user.

      SingleBranchScheduler properties:
               repository: the repository to attach the scheduler to; this
                    is the repo name from the 'repos' section; the branch which
                    the scheduler is attached to matches that in the repo
                    definition.

               stable-timer: how long (in seconds) to wait after change before
                    triggering build to allow for changes to settle.

           change-user: the user name which the remote hook will use; the
                    default value is the repository name as per the 'repository'
                    property.

               change-password: password which the remote hook will use; the
                    default is the buildbot default 'changepw' -- if your
                    autobuilder is publically accessible, you want to keep this
                    secret to avoid injection of arbitrary changes into your
                    autobuilder.

Extra Notes on SingleBranchScheduler setup
==========================================

There is one SBS scheduler for each repository in the buildset, i.e.,
if your buildset contains more repositories, and you want build
triggered by changes to any of them, you need to define a scheduler
for each. This also means that you can mix and match, e.g., only
do nightly rebuilds for some repos and immediate for others.

The scheduler change filter is set up to watch changes only in the
single repository specified, so you have to set up your repository
hook to sent the repository url in the change set with the
--repository argument to git_buildbot.py, e.g., your git post-receive
hook could look something like:

    #!/bin/sh
    echo "$1 $2 $3" | \
        git_buildbot.py --repository="git://some_repo..."

For local testing, you can use a post-merge hook instead, along
these lines:

    #!/bin/sh
    PRE=$(git rev-parse 'HEAD@{1}')
    POST=$(git rev-parse HEAD)
    SYMNAME=$(git rev-parse --symbolic-full-name HEAD)
    echo "$PRE $POST $SYMNAME" | \
        git_buildbot.py --repository="file:///where_your_repo_is"

Because of the way builbot change sources work, your change user
names must not colide with the user names used by your slaves.

Example:

    [nightly-x86]
    builders: 'builder1'
    repos: [{'poky':
                {'repourl':'git://git.yoctoproject.org/poky',
                 'bbpriority':'1',
                 'branch':'master'}},
            {'meta-qt3':
                {'repourl':'git://git.yoctoproject.org/meta-qt3',
                 'bbpriority':'2',
                 'branch':'master'}}]
    steps: [{'SetDest':{}},
            {'CheckOutLayers': {}},
            {'RunPreamble': {}},
            {'CreateAutoConf': {'machine': 'qemux86', 'SDKMACHINE' : 'i686',
                                'distro': 'poky'}},
            {'CreateBBLayersConf': {'buildprovider' : 'yocto'}},
            {'BuildImages': {'images': 'core-image-sato core-image-sato-dev'}},
            {'RunSanityTests': {'images': 'core-image-minimal core-image-sato'}},
            {'PublishArtifacts': {'artifacts': ['qemux86', 'atom-pc']}}]
    scheduler: [{'dev-branch-scheduler' :
                    {'type':'SingleBranchScheduler',
             'repository':'poky',
             'stable-timer':30,
                     'change-password':'secret_change_password'}}]

Adding Buildsteps
=================
I've included the basic buildsteps required to do general building as well as an
example buildstep called HelloWorld.py.

    from buildbot.steps.shell import ShellCommand

    class HelloWorld(ShellCommand):
        haltOnFailure = True
        flunkOnFailure = True
        name = "Hello World"
        def __init__(self, factory, argdict=None, **kwargs):
            self.firstname=""
            self.lastname=""
            self.factory = factory
            for k, v in argdict.iteritems():
                if k=="name":
                    self.firstname=v
                elif k=="lastname":
                    self.lastname=v
                else:
                    setattr(self, k, v)
            self.description = "Hello World"
            self.command = "echo 'Hello World " + self.firstname + " " + self.lastname + "'"
            ShellCommand.__init__(self, **kwargs)

        def describe(self, done=False):
            description = ShellCommand.describe(self,done)
            return description

We see that this is an inherited class (from ShellCommand) that overrides the
__init__ and describe methods of ShellCommand. All custom buildsteps MUST override
__init__ of the inherited class, adding the argdict and kwargs properties to the
class. This allows us to pass arguments specific to the custom buildstep in via
an argument dictionary while allowing us to pass arguments in that will get passed
up to the inherited class as a keyworded, variable length argument list.

We do this so that adding buildsteps is essentially drag and drop. By adding a
custom buildstep to lib/python2.7/site-packages/autobuilder/buildsteps you can
just reference it within your config file without making any changes to the core
Autobuilder codebase.