Creating a multijob
Reference: Multijob Plugin – Jenkins – Jenkins Wiki
Why and when to use it?
- If you’d like to stop the mess with downstream / upstream jobs chains definitions
- When you want to add full hierarchy of Jenkins jobs that will be executed in sequence or in parallel
- Add context to your buildflow implementing parameter inheritance from the MultiJob to all its Phases and Jobs. Phases are sequential, whilst jobs inside each Phase are parallel
Example:


Jenkins Job Builder and Multijob
MultiJob Project — Jenkins Job Builder documentation
Builders — Jenkins Job Builder documentation
Note: Install Jenkins Job Builder 1.6.0 or higher. I added a feature for the copy artifact plugin that will allow you to copy artifacts from a current multijob build
Example:
#######################################
## MULTI-JOB TO WRAP AROUND ALL JOBS ##
#######################################
- job-template:
name: '{ocname}-0-multijob'
defaults: openshift-defaults
concurrent: false
node: master
project-type: multijob
scm:
- openshift-ansible-master-scm
triggers:
- timed: "H */6 * * *"
wrappers:
- openshift-wrappers
builders:
- multijob:
name: JslaveSetup
condition: SUCCESSFUL
projects:
- name: '{ocname}-1-provision-jslave'
kill-phase-on: FAILURE
abort-all-job: true
current-parameters: true
- multijob:
name: UnitTests
condition: SUCCESSFUL
projects:
- name: '{ocname}-2-unit-tests'
kill-phase-on: FAILURE
abort-all-job: true
current-parameters: true
- multijob:
name: Provision-Deploy-e2etests-upgrade
condition: SUCCESSFUL
projects:
- name: '{ocname}-3-test-matrix'
kill-phase-on: FAILURE
abort-all-job: true
current-parameters: true
Each multijob has phases that can have jobs that run in parallel in the example above these are all separate phases that run serially. I also reference defaults that are in other files. I will link to all the files at the bottom for you to inspect, but I just wanted to show the basic JJB I have for a multijob. The trigger can be anything like in other Jenkins Jobs. The other key that makes it a multijob besides these “-multijob” sections is the “project-type: multijob” at the top.
Creating a Matrix Job
Building a matrix project – Jenkins – Jenkins Wiki
Why and when to use it?
Often we have build steps in our projects that are identical, but we want to run these same steps on just different components. Maybe it is a topology, slave, version of Python, etc.
The matrix plugin allows you to do that with ease. You can create one job but have multiple backend test executions and results with one job definition. It also allows you restrict combinations of which axes can and can’t run together with the combination filter.
Configuration matrix
The Configuration Matrix allows you to specify what steps to duplicate, and create a multiple-axis graph of the type of builds to create.
You can define a User Defined Axis to create your matrix of combinations.
Features
The matrix project module handles creating Jenkins matrix projects. To create a matrix project specify matrix in the project-type attribute to the Job definition.
Axes:
Currently it supports four axes which share the same internal YAML structure:
- label expressions (
label-expression) - user-defined values (
user-defined) - slave name or label (
slave) - JDK name (
jdk)
Requires the Jenkins Matrix Project Plugin.
The module also supports additional, plugin-defined axes:
- DynamicAxis (
dynamic), requires the Jenkins DynamicAxis Plugin - GroovyAxis (
groovy), requires the Jenkins GroovyAxis Plugin - YamlAxis (
yaml), requires the Jenkins Yaml Axis Plugin
The module supports also ShiningPanda axes:
Example:
name: matrix-test003
project-type: matrix
axes:
- axis:
type: python
values:
- python-2.6
- python-2.7
- python-3.4
- axis:
type: tox
values:
- py26
- py27
- py34
Requires the Jenkins ShiningPanda Plugin.
Combination-filter:
This allows jobs to be restrictive on what axes run together.
Example:
combo-filter: > ((OSE_VER =~ "^3.[1-9]" && TOPOLOGY == "openshift-cluster-containerized" && CONTAINERIZED == "_containerized") || (OSE_VER =~ "^3.[1-9]" && TOPOLOGY == "openshift-cluster" && CONTAINERIZED == "_NOT_containerized"))
This says when environment variables OSE_VER is 3.1 to 3.9 we run TOPOLOGY “openshift-cluster-containerized “with CONTAINERIZED set to “_containerized” or we run a NON containerized combination.
Example:



Jenkins Job Builder and Matrix
Matrix Project – Jenkins Job Builder Documentation
Simple Example:
########################
## MATRIX JOB TESTING ##
## TOPOLOGY ##
## SLAVE ##
########################
- job-template:
name: '{ocname}-3-test-matrix'
defaults: openshift-defaults
concurrent: false
node: '{jslave_name}'
project-type: matrix
axes:
- axis:
type: user-defined
name: TOPOLOGY
values:
- openshift-cluster
- openshift-cluster-containerized
- axis:
type: slave
name: nodes
values:
- '{jslave_name}'
scm:
- openshift-ci-scms
- openshift-ansible-master-scm
wrappers:
- openshift-wrappers
builders:
- shining-panda:
build-environment: virtualenv
python-version: System-CPython-2.7
nature: shell
command: |
pip install ansible==1.9.6
pip install taskrunner lxml configobj requests foreman python-foreman python-{{glanceclient,keystoneclient,neutronclient,novaclient}}
export PYTHONPATH="$PYTHONPATH:/usr/lib/python2.7/site-packages/bkr"
{provision-cluster}
clear: true
- shell: |
#!/bin/bash
set -xeuo pipefail
# Run some shell stuff or ansible
chmod 600 $WORKSPACE/{ssh_keyfile}
ansible-playbook \
-i $WORKSPACE/ci-factory/utils/central_ci_dynamic_hosts.py \
--private-key=$WORKSPACE/{ssh_keyfile} \
--extra-vars "topology=${{topology}}" \
$WORKSPACE/setup.yml
publishers:
- archive:
artifacts: '*.txt'
allow-empty: 'false'
Complex Example:
combo-filter: > ((OSE_VER =~ "^3.[1-9]" && TOPOLOGY == "openshift-cluster-containerized" && CONTAINERIZED == "_containerized") || (OSE_VER =~ "^3.[1-9]" && TOPOLOGY == "openshift-cluster" && CONTAINERIZED == "_NOT_containerized"))
########################
## MATRIX JOB TESTING ##
## OSE_VER ##
## CONTANERIZED ##
## TOPOLOGY ##
## SLAVE ##
## PYTHON ##
########################
- job-template:
name: '{ocname}-3-test-matrix'
defaults: openshift-defaults
concurrent: false
node: '{jslave_name}'
project-type: matrix
execution-strategy:
combination-filter: |
{combo-filter}
axes:
- axis:
type: user-defined
name: OSE_VER
values:
- 3.2
- axis:
type: user-defined
name: CONTAINERIZED
values:
- _containerized
- _NOT_containerized
- axis:
type: user-defined
name: TOPOLOGY
values:
- openshift-cluster
- openshift-cluster-containerized
- axis:
type: slave
name: nodes
values:
- '{jslave_name}'
- axis:
type: python
values:
- System-CPython-2.7
scm:
- openshift-ci-scms
- openshift-ansible-master-scm
wrappers:
- openshift-wrappers
builders:
- copyartifact:
project: '{ocname}-1-provision-jslave'
filter: '*.txt'
target: $WORKSPACE
which-build: multijob-build
- inject:
properties-file: $WORKSPACE/RESOURCES.txt
properties-content: |
TOPOLOGY_PATH={topology_path}
PROJECT_DEFAULTS={project_defaults}
SSH_KEYFILE={ssh_keyfile}
JSLAVE_TOPOLOGY_PATH={jslave_topology_path}
JSLAVE_TOPOLOGY={jslave_topology}
JSLAVE_USERNAME={jslave_username}
JSLAVE_TEARDOWN={jslave_teardown}
- shining-panda:
build-environment: virtualenv
python-version: System-CPython-2.7
nature: shell
command: |
pip install ansible==1.9.6
pip install taskrunner lxml configobj requests foreman python-foreman python-{{glanceclient,keystoneclient,neutronclient,novaclient}}
export PYTHONPATH="$PYTHONPATH:/usr/lib/python2.7/site-packages/bkr"
{provision-cluster}
clear: true
- inject:
properties-file: $WORKSPACE/RESOURCES.txt
- shell: |
{prep-cluster}
- shell: |
{run-install}
- shell: |
{run-e2e-tests}
publishers:
- archive:
artifacts: '*.txt'
allow-empty: 'false'
- openshift-email
- teardown-resources
Running Axes on a slave
Note: If you want the axes to run on a slave then you must specify that by a label or node name
Example:
- axis:
type: slave
name: nodes
values:
- '{jslave_name}'
Running in a python or shell virtual environment
Note: Using the Shiningpanda plugin for python virtual environments
- axis:
type: python
values:
- System-CPython-2.7
builders:
- shining-panda:
build-environment: virtualenv
python-version: System-CPython-2.7
nature: shell
command: |
pip install ansible==1.9.6
pip install taskrunner lxml configobj requests foreman python-foreman python-{{glanceclient,keystoneclient,neutronclient,novaclient}}
export PYTHONPATH="$PYTHONPATH:/usr/lib/python2.7/site-packages/bkr"
{provision-cluster}
Full Jenkins Job Builder file example
The openshift-defaults.yaml file contains all the defaults to use for the jobs. The openshift-committed.yaml contains the job templates and the project macros are defined in the openshift-ansible-committed.yaml.
Note: These could all be in one file but a separated them for clarity.
openshift-defaults.yaml
openshift-committed.yaml
openshift-ansible-committed.yaml