system-config/doc/source/jjb.rst
Monty Taylor 258abe1a23 Use cgit server instead of github for everything
We have a cgit server now, which means we should replace
all references to github with references to git.openstack.org.

Change-Id: I68ad1ce514fb4326c7d9940b5a84999af5b58562
2013-08-19 10:19:47 -07:00

282 lines
8.1 KiB
ReStructuredText

:title: Jenkins Job Builder
.. _jjb:
Jenkins Job Builder
###################
Jenkins Job Builder is a system for configuring Jenkins jobs using
simple YAML files stored in Git.
At a Glance
===========
:Hosts:
* http://jenkins.openstack.org
* http://jenkins-dev.openstack.org
:Puppet:
* :file:`modules/jenkins/manifests/job_builder.pp`
:Configuration:
* :file:`modules/openstack_project/files/jenkins_job_builder/config/`
:Projects:
* https://git.openstack.org/cgit/openstack-infra/jenkins-job-builder
:Bugs:
* http://bugs.launchpad.net/openstack-ci
:Resources:
* `Reference Manual <http://ci.openstack.org/jenkins-job-builder>`_
Overview
========
In order to make the process of managing hundreds of Jenkins jobs
easier, Jenkins Job Builder was designed to take YAML based
configurations and convert those into jobs that are injected into
Jenkins.
The documentation below describes how the OpenStack Infrastructure
team uses the Jenkins Job Builder in our environment.
Configuring Projects
====================
The YAML scripts to make this work are stored in the
:file:`modules/openstack_project/files/jenkins_job_builder/config/`
directory. In this directory you can have four different types of
yaml config files:
* Jenkins Jobs Defaults in ``defaults.yaml``.
* Jenkins Jobs Macros to give larger config sections meaningful names in
``macros.yaml``.
* Project specific configurations in ``project_name.yaml``.
* Job template configurations. Need a ``projects.yaml`` file to specify how
the templates should be filled out and templates go in ``template_name.yaml``.
YAML Format
===========
Defaults
--------
Example defaults config:
.. code-block:: yaml
- defaults:
name: global
description: |
<p><b>This job is managed by puppet and will be overwritten.</b></p>
<p><b>Do not edit this job through the web</b></p>
<p>If you would like to make changes to this job, please see:
<a href="https://git.openstack.org/cgit/openstack-infra/config">
https://git.openstack.org/cgit/openstack-infra/config
</a>
In modules/openstack_project/files/jenkins_jobs
</p>
project-type: freestyle
concurrent: true
wrappers:
- timeout:
timeout: 30
fail: true
- timestamps
logrotate:
daysToKeep: 1
numToKeep: -1
artifactDaysToKeep: -1
artifactNumToKeep: -1
This config starts with the ``- defaults::`` line. This specifies that this
section contains default values rather than job specifications. In this
section we specify a useful set of defaults including a default description
indicating Puppet manages these jobs, jobs are allowed to run concurrently,
and a thirty minute job timeout.
Macros
------
Macros exist to give meaningful names to blocks of configuration that can be
used in job configs in place of the blocks they name. For example:
.. code-block:: yaml
- builder:
name: git-prep
builders:
- shell: "/slave_scripts/git-prep.sh"
- builder:
name: docs
builders:
- shell: "/slave_scripts/run-docs.sh"
- publisher:
name: console-log
publishers:
- scp:
site: 'scp-server'
files:
- target: 'logs/$JOB_NAME/$BUILD_NUMBER'
copy-console: true
copy-after-failure: true
In this block of code we define two builder macros and one publisher macro.
Each macro has a name and using that name in a job config is equivalent to
having the yaml below the name in place of the name in the job config. The next
section shows how you can use these macros.
Job Config
----------
Example job config:
.. code-block:: yaml
- job:
name: example-docs
node: node-label
triggers:
- zuul
builders:
- git-prep
- docs
publishers:
- scp:
site: 'scp-server'
files:
- target: 'dir/ectory'
source: 'build/html/foo'
keep-hierarchy: true
- console-log
Each job specification begins with ``-job:``. Under this section you can
specify the job details like name, node, etc. Any detail defined in the
defaults section that is not defined under this job will be included as well.
In addition to attribute details you can also specify how jenkins should
perform this job. What trigger methods should be used, the build steps,
jenkins publishing steps and so on. The macros defined earlier make this easy
and simple.
Job Templates
-------------
Job templates allow you to specify a job config once with arguments that are
replaced with the values specified in ``projects.yaml``. This allows you to
reuse job configs across many projects. First you need a templated job config:
.. code-block:: yaml
- job-template:
name: '{name}-docs'
triggers:
- zuul
builders:
- git-prep
- docs
publishers:
- scp:
site: 'scp-server'
files:
- target: 'dir/ectory'
source: 'build/html/foo'
keep-hierarchy: true
- console-log
node: '{node}'
- job-group:
name: python-jobs
jobs:
- '{name}-docs'
This takes the previous ``example-docs`` job and templatizes it. This will
allow us to easily create ``example1-docs`` and ``example2-docs`` jobs.
Each job template begins with ``- job-template:`` and the job specification is
identical to the previous one, but we have introduced variable arguments. In
this case ``{name}`` is a variable value that will be replaced. The values for
name will be defined in the ``projects.yaml`` file.
The ``- job-group:`` section is not strictly necessary but allows you to group
many job templates with the same variable arguments under one name.
The ``projects.yaml`` pulls all of the magic together. It specifies the
arguments to and instantiates the job templates as real jobs. For example:
.. code-block:: yaml
- project:
name: example1
node: precise
jobs:
- python-jobs
- project:
name: example2
node: oneiric
jobs:
- {name}-docs
Each project using templated jobs should have its own ``- project:`` section.
Under this sections there should be a ``jobs:`` section with a list of job
templates or job groups to be used by this project. Other values under the
``- project:`` section define the arguments to the templates lised under
``jobs:``. In this case we are giving the docs template ``name`` and ``node``
values.
Notice that example1 makes use of the job group and example2 makes use of the
job template.
Job Caching
-----------
The Jenkins Jobs builder maintains a special YAML file in
``~/.jenkins_jobs_cache.yml``. This contains an MD5 of every generated XML that
it builds. If it finds the XML is different then it will proceed to send this
to Jenkins, otherwise it is skipped. If a job is accidentally deleted then this
file should be modified or removed.
Sending a Job to Jenkins
------------------------
The Jenkins Jobs builder talks to Jenkins using the Jenkins API. This
means that it can create and modify jobs directly without the need to
restart or reload the Jenkins server. It also means that Jenkins will
verify the XML and cause the Jenkins Jobs builder to fail if there is
a problem.
For this to work a configuration file is needed. There is an erb
template for this configuration file at
:file:`modules/jenkins/templates/jenkins_jobs.ini.erb`. The contents
of this template are:
.. code-block:: ini
[jenkins]
user=<%= username %>
password=<%= password %>
url=<%= url %>
The values for user and url are hardcoded in the Puppet repo in
:file:`modules/openstack_project/manifests/jenkins.pp`, but the
password is stored in hiera. Make sure you have it defined as
``jenkins_jobs_password`` in the hiera DB.
The password can be obtained by logging into the Jenkins user,
clicking on your username in the top-right, clicking on `Configure`
and then `Show API Token`. This API Token is your password for the
API.