From d35f5072f4ea5528c5cb9b3399f9d7e30c709c56 Mon Sep 17 00:00:00 2001 From: Ramy Asselin Date: Fri, 25 Sep 2015 17:44:00 -0700 Subject: [PATCH] Add initial files for jenkins, zuul, nodepool Depends on nodepool https://review.openstack.org/#/c/189762/ --- README.md | 53 ++++++++++++++++ jenkins/jobs/README.md | 2 + jenkins/jobs/defaults.yaml | 20 ++++++ jenkins/jobs/dsvm-cinder-driver.yaml | 75 ++++++++++++++++++++++ jenkins/jobs/examples.yaml | 50 +++++++++++++++ jenkins/jobs/macros-common.yaml | 95 ++++++++++++++++++++++++++++ jenkins/jobs/projects.yaml | 12 ++++ nodepool/elements/README.md | 3 + nodepool/nodepool.yaml | 58 +++++++++++++++++ nodepool/scripts/README.md | 5 ++ zuul/layout.yaml | 79 +++++++++++++++++++++++ zuul/openstack_functions.py | 38 +++++++++++ 12 files changed, 490 insertions(+) create mode 100644 README.md create mode 100644 jenkins/jobs/README.md create mode 100644 jenkins/jobs/defaults.yaml create mode 100644 jenkins/jobs/dsvm-cinder-driver.yaml create mode 100644 jenkins/jobs/examples.yaml create mode 100644 jenkins/jobs/macros-common.yaml create mode 100644 jenkins/jobs/projects.yaml create mode 100644 nodepool/elements/README.md create mode 100644 nodepool/nodepool.yaml create mode 100644 nodepool/scripts/README.md create mode 100644 zuul/layout.yaml create mode 100644 zuul/openstack_functions.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..2da1b55 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# Example project-config repository + +This is an example project-config repository for use as a +starting point to setup a 3rd party CI account. + +## Steps to begin customization + +The project-config repository is intended to contain custom configurations +needed by each CI system. + +## Customize Zuul + +The zuul layout configuration is located in `zuul/layout.yaml`. You can find +the full configuration details in the [Zuul manual](http://docs.openstack.org/infra/zuul/). + +1. Change 'myvendor' in the 'recheck' command to your CI's name. + +2. Configure the e-mail addresses for merge-failures and job notification. + +3. By default, the project zuul triggers on is `openstack-dev/ci-sandbox`. + After testing your CI system update this section to include other projects. + You are encouraged to use the 'silent' pipeline until your jobs are stable. + +## Customize Nodepool + +The nodepool configuration is located in `nodepool/nodepool.yaml`. You can +find the full configuration details in the [Nodepool manual](http://docs.openstack.org/infra/nodepool/). +There are a few configuration that need to be updated. + +1. There are some user names and passwords that need to be configured. + +2. Select a 'random time' for your nodepool images to be built in the + `image-update` property. By having 3rd party systems use different + times will help reduce the spike load on OpenStack's Git servers. + +3. Setup an intial set of nodepool scripts and elements. Start by cloning + OpenStack's [project-config](https://git.openstack.org/cgit/openstack-infra/project-config/) + and copy the contents of that repo's `nodepool/elements` to your repo's + `nodepool/elements`. Optionally do the same for the `nodepool/scripts` + folder. You may have to change these elements to work in your environment. + If so, see this [README](http://git.openstack.org/cgit/openstack-infra/project-config/tree/nodepool/elements/README.rst) + for help. + +## Customize Jenkins Jobs + +Adjust the jenkins jobs in `jenkins/jobs/` to your needs. You can find the full configuration details in the +[Jenkins Job Builder manual](http://docs.openstack.org/infra/jenkins-job-builder/) + +1. Change the value of the `$PUBLISH_HOST` to the host (without https:// prefix) you will publish + job artifacts to. This is also known as the Log server. You can set one up using [this script] + + + diff --git a/jenkins/jobs/README.md b/jenkins/jobs/README.md new file mode 100644 index 0000000..decd1ca --- /dev/null +++ b/jenkins/jobs/README.md @@ -0,0 +1,2 @@ +You can find many more examples of jobs in +[openstack-infra/project-config](http://git.openstack.org/cgit/openstack-infra/project-config/tree/jenkins/jobs) diff --git a/jenkins/jobs/defaults.yaml b/jenkins/jobs/defaults.yaml new file mode 100644 index 0000000..d9e6f0c --- /dev/null +++ b/jenkins/jobs/defaults.yaml @@ -0,0 +1,20 @@ +- defaults: + name: global + description: | +

This job is managed by puppet and will be overwritten.

+ +

Do not edit this job through the web

+ project-type: freestyle + concurrent: true + + wrappers: + - timeout: + timeout: 30 + fail: true + - timestamps + + logrotate: + daysToKeep: 7 + numToKeep: -1 + artifactDaysToKeep: -1 + artifactNumToKeep: -1 diff --git a/jenkins/jobs/dsvm-cinder-driver.yaml b/jenkins/jobs/dsvm-cinder-driver.yaml new file mode 100644 index 0000000..347e042 --- /dev/null +++ b/jenkins/jobs/dsvm-cinder-driver.yaml @@ -0,0 +1,75 @@ +- job-template: + name: 'dsvm-tempest-my-cinder-driver' + node: '{node}' + + wrappers: + - timeout: + timeout: 125 + fail: true + - timestamps + + builders: + - link-logs + - net-info + - devstack-checkout + - shell: | + #!/bin/bash -xe + + function pre_test_hook {{ + echo "Install thirdparty client libraries" + #TODO: update your client here if needed, otherwise delete + sudo -H pip install mydriverclient + echo "Configure the local.conf file to properly setup hp lefthand driver in cinder.conf" + cat <$BASE/new/devstack/local.conf + + [[post-config|\$CINDER_CONF]] + [DEFAULT] + enabled_backends=mybackend + default_volume_type=myvolumetype + + [mybackend] + # add you driver configuration here + volume_driver=cinder.volume.drivers.MyDriver + volume_backend_name=mybackend + + # Use post-extra because the tempest configuration file is + # overwritten with the .sample after post-config. + [[post-extra|\$TEMPEST_CONFIG]] + [volume] + storage_protocol=iSCSI + vendor_name=MyVendor + EOF + + echo "Configure localrc file to properly setup CINDER_ENABLED_BACKENDS" + cat <>$BASE/new/devstack/localrc + CINDER_ENABLED_BACKENDS=mybackend:myvolumetype + EOF + + }} + + export -f pre_test_hook + + # To keep our CINDER_ENABLED_BACKENDS configuration in localrc + export KEEP_LOCALRC=true + + export PYTHONUNBUFFERED=true + export DEVSTACK_GATE_TIMEOUT=120 + export DEVSTACK_GATE_TEMPEST=1 + export DEVSTACK_GATE_TEMPEST_REGEX="volume" + + # Let's use the http protocol instead of git protocol + export GIT_BASE=https://git.openstack.org + + if [ -z $ZUUL_PROJECT ]; then + export ZUUL_PROJECT=openstack-dev/ci-sandbox + fi + if [ -z $ZUUL_BRANCH ]; then + export ZUUL_BRANCH=master + fi + + cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh + ./safe-devstack-vm-gate-wrap.sh + + publishers: + - devstack-logs + - console-log diff --git a/jenkins/jobs/examples.yaml b/jenkins/jobs/examples.yaml new file mode 100644 index 0000000..e8d2503 --- /dev/null +++ b/jenkins/jobs/examples.yaml @@ -0,0 +1,50 @@ +- job-template: + name: 'noop-check-communication' + node: '{node}' + + builders: + - shell: | + #!/bin/bash -xe + echo "Hello world, this is the {vendor} Testing System" + - link-logs + + publishers: + - devstack-logs + - console-log + + +- job-template: + name: 'dsvm-tempest-full' + node: '{node}' + + wrappers: + - timeout: + timeout: 185 # Timeout in *minutes* + fail: true # A job run that exceeds the timeout will cause a failure + - timestamps + + builders: + - net-info +# - devstack-checkout + - devstack-checkout-http + - shell: | + #!/bin/bash -xe + if [ -z $ZUUL_PROJECT ]; then + export ZUUL_PROJECT=openstack-dev/sandbox + fi + if [ -z $ZUUL_BRANCH ]; then + export ZUUL_BRANCH=master + fi + export PYTHONUNBUFFERED=true + export DEVSTACK_GATE_TIMEOUT=180 + export DEVSTACK_GATE_TEMPEST=1 + + export DEVSTACK_GATE_TEMPEST_REGEX="volume.api" + + cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh + ./safe-devstack-vm-gate-wrap.sh + - link-logs + + publishers: + - devstack-logs + - console-log diff --git a/jenkins/jobs/macros-common.yaml b/jenkins/jobs/macros-common.yaml new file mode 100644 index 0000000..10a7806 --- /dev/null +++ b/jenkins/jobs/macros-common.yaml @@ -0,0 +1,95 @@ +- builder: + name: devstack-checkout + builders: + - shell: | + #!/bin/bash -xe + if [[ ! -e devstack-gate ]]; then + git clone git://git.openstack.org/openstack-infra/devstack-gate + else + cd devstack-gate + git remote set-url origin git://git.openstack.org/openstack-infra/devstack-gate + git remote update + git reset --hard + if ! git clean -x -f ; then + sleep 1 + git clean -x -f + fi + git checkout master + git reset --hard remotes/origin/master + if ! git clean -x -f ; then + sleep 1 + git clean -x -f + fi + cd .. + fi + +- builder: + name: devstack-checkout-http + builders: + - shell: | + #!/bin/bash -xe + if [[ ! -e devstack-gate ]]; then + git clone http://git.openstack.org/openstack-infra/devstack-gate + else + cd devstack-gate + git remote set-url origin http://git.openstack.org/openstack-infra/devstack-gate + git remote update + git reset --hard + if ! git clean -x -f ; then + sleep 1 + git clean -x -f + fi + git checkout master + git reset --hard remotes/origin/master + if ! git clean -x -f ; then + sleep 1 + git clean -x -f + fi + cd .. + fi + +- builder: + name: link-logs + builders: + - shell: | + #!/bin/sh + # TODO: Update these links if using a different gerrit server + echo "Triggered by: https://review.openstack.org/$ZUUL_CHANGE patchset $ZUUL_PATCHSET" + + # TODO: Update this link to point to your log server + echo "Detailed logs: http:///$LOG_PATH/" + +- publisher: + name: console-log + publishers: + - scp: + site: 'LogServer' + files: + - target: 'logs/$LOG_PATH' + copy-console: true + copy-after-failure: true + +- publisher: + name: devstack-logs + publishers: + - scp: + site: 'LogServer' + files: + - target: 'logs/$LOG_PATH' + source: 'logs/**' + keep-hierarchy: true + copy-after-failure: true + +- builder: + name: net-info + builders: + - shell: | + #!/bin/sh + export PATH=$PATH:/sbin + echo "Network interface addresses..." + ip address show + echo "Network routing tables..." + ip route show + ip -6 route show + echo "Network neighbors..." + ip neighbor show diff --git a/jenkins/jobs/projects.yaml b/jenkins/jobs/projects.yaml new file mode 100644 index 0000000..b2bdd7a --- /dev/null +++ b/jenkins/jobs/projects.yaml @@ -0,0 +1,12 @@ +- project: + name: sandbox + github-org: openstack-dev + node: master + vendor: myvendor + + jobs: + - noop-check-communication + - dsvm-tempest-full: + node: 'devstack_slave || devstack-precise-check || d-p-c' + - dsvm-tempest-my-cinder-driver: + node: 'd-p-c' diff --git a/nodepool/elements/README.md b/nodepool/elements/README.md new file mode 100644 index 0000000..4a27559 --- /dev/null +++ b/nodepool/elements/README.md @@ -0,0 +1,3 @@ +Empty elements. Use these elements as a starting point: +[openstack-infra/project-config](http://git.openstack.org/cgit/openstack-infra/project-config/tree/nodepool/elements) + diff --git a/nodepool/nodepool.yaml b/nodepool/nodepool.yaml new file mode 100644 index 0000000..e109ffd --- /dev/null +++ b/nodepool/nodepool.yaml @@ -0,0 +1,58 @@ +script-dir: /etc/nodepool/scripts +elements-dir: /etc/nodepool/elements +images-dir: /opt/nodepool_dib + +cron: + cleanup: '*/1 * * * *' + check: '*/15 * * * *' +# TODO: Please choose a random hour for nodepool image updates. +# This will help reduce the load on upstream git farms & mirros where all 3rd +# party ci systems start building images at the same time. +# Doing so is easy: update the first '17' below with a random number between 0 to 23 +# This references the hour of the day when images will be built. + image-update: '0 0 * * *' + +zmq-publishers: + - tcp://localhost:8888 + +gearman-servers: + - host: 127.0.0.1 + +labels: + - name: d-p-c + image: dpc + min-ready: 1 + providers: + - name: local_01 + +diskimages: + - name: dpc + elements: + - ubuntu + - vm + - openstack-repos + - puppet + - nodepool-base + - node-devstack + release: trusty + env-vars: + TMPDIR: /opt/dib_tmp + DIB_IMAGE_CACHE: /opt/dib_cache + +providers: + - name: local_01 +#TODO: Update the provider username, password, and authurl + username: '<%= provider_username %>' + password: '<%= provider_password %>' + auth-url: 'http://:5000/v2.0' + project-name: 'admin' + max-servers: 2 + images: + - name: dpc + min-ram: 8192 + diskimage: dpc + username: jenkins + private-key: '/home/nodepool/.ssh/id_rsa' + +targets: + - name: jenkins1 diff --git a/nodepool/scripts/README.md b/nodepool/scripts/README.md new file mode 100644 index 0000000..cc13405 --- /dev/null +++ b/nodepool/scripts/README.md @@ -0,0 +1,5 @@ +These scripts will be copied to the nodepool slave image's +/etc/nodepool/scripts folder. + +The are optional. You can reference these: +[openstack-infra/project-config](http://git.openstack.org/cgit/openstack-infra/project-config/tree/nodepool/scripts) diff --git a/zuul/layout.yaml b/zuul/layout.yaml new file mode 100644 index 0000000..fba83a2 --- /dev/null +++ b/zuul/layout.yaml @@ -0,0 +1,79 @@ +includes: + #TODO: Rename this file. These functions are what enables single use nodes in nodepool. + - python-file: openstack_functions.py + +pipelines: + - name: check + description: Newly uploaded patchsets enter this pipeline to receive an initial +/-1 Verified vote from Jenkins. + failure-message: "Build failed. For 3rd party CI contact info: https://wiki.openstack.org/wiki/ThirdPartySystems" + manager: IndependentPipelineManager + trigger: + gerrit: + - event: patchset-created + - event: change-restored + # TODO: Change "myvendor" below to your vendor's name to add a custom + # recheck trigger that runs the check pipeline jobs when someone + # adds a comment to a review that says "recheck myvendor". + - event: comment-added + comment: (?i)^(Patch Set [0-9]+:)?( [\w\\+-]*)*(\n\n)?\s*recheck myvendor\s*$ + success: + gerrit: + verified: 1 + smtp: + #TODO: Update these to real e-mail addresses + to: third_party_ci@example.com + from: zuul@example.com + subject: 'Silent check of {change.project} {change.number},{change.patchset} passed' + failure: + gerrit: + verified: -1 + smtp: + #TODO: Update these to real e-mail addresses + to: third_party_ci@example.com + from: zuul@example.com + subject: 'Silent check of {change.project} {change.number},{change.patchset} failed' + merge-failure: + smtp: + #TODO: Update these to real e-mail addresses + to: third_party_ci@example.com + from: zuul@example.com + subject: Upstream change {change} has a merge failure + + + - name: silent + description: Newly uploaded patchsets enter this pipeline to check jobs whose results are NOT to be posted (because e.g. they are not yet stable) + manager: IndependentPipelineManager + trigger: + gerrit: + - event: patchset-created + - event: change-restored + - event: comment-added + comment: (?i)^(Patch Set [0-9]+:)?( [\w\\+-]*)*(\n\n)?\s*recheck myvendor\s*$ + success: + smtp: + #TODO: Update these to real e-mail addresses + to: third_party_ci@example.com + from: zuul@example.com + subject: 'Silent check of {change.project} {change.number},{change.patchset} passed' + failure: + smtp: + #TODO: Update these to real e-mail addresses + to: third_party_ci@example.com + from: zuul@example.com + subject: 'Silent check of {change.project} {change.number},{change.patchset} failed' + + +jobs: + - name: ^dsvm-tempest.*$ + parameter-function: single_use_node + +projects: + - name: openstack-dev/ci-sandbox + check: + # Remove this after successfully verifying communication with upstream + # and seeing a posted successful review. + - noop-check-communication + silent: + # Uncomment this job when you have a jenkins slave running and want to + # test a full Tempest run within devstack. + - dsvm-tempest-full diff --git a/zuul/openstack_functions.py b/zuul/openstack_functions.py new file mode 100644 index 0000000..ffc51cb --- /dev/null +++ b/zuul/openstack_functions.py @@ -0,0 +1,38 @@ +# Copyright 2013 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +def set_log_url(item, job, params): + if hasattr(item.change, 'refspec'): + path = "%s/%s/%s/%s" % ( + params['ZUUL_CHANGE'][-2:], params['ZUUL_CHANGE'], + params['ZUUL_PATCHSET'], params['ZUUL_PIPELINE']) + elif hasattr(item.change, 'ref'): + path = "%s/%s/%s" % ( + params['ZUUL_NEWREV'][:2], params['ZUUL_NEWREV'], + params['ZUUL_PIPELINE']) + else: + path = params['ZUUL_PIPELINE'] + params['BASE_LOG_PATH'] = path + params['LOG_PATH'] = path + '/%s/%s' % (job.name, + params['ZUUL_UUID'][:7]) + + +def single_use_node(item, job, params): + set_log_url(item, job, params) + params['OFFLINE_NODE_WHEN_COMPLETE'] = '1' + + +def reusable_node(item, job, params): + set_log_url(item, job, params)