Skip to content

Commit

Permalink
Add Jenkins state
Browse files Browse the repository at this point in the history
- install Jenkins from deb package
- install plugins
- run jimmy
  • Loading branch information
bookwar committed Feb 15, 2017
0 parents commit 97b7c16
Show file tree
Hide file tree
Showing 15 changed files with 535 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
\#*
.*~
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Salt states for CI infrastructure

This states are not generic and this is done on purpose. The goal is to have maintainable configuration management code and prioritize readability over flexibility.

## States

### states/jenkins

Jenkins state for Debian Jessie.

Install Jenkins, add plugins according to the hardcoded list, run jimmy to setup basic authentication.

## Secrets

Passwords and credentials are stored directly in the repository, but encrypted with gpgkeys.

To encrypt data one may use utils/encrypt.py script. For it to work you need access to the salt-master gpgkeys.
69 changes: 69 additions & 0 deletions pillars/_secret/jenkins/init.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!yaml|gpg

jenkins:
jjb_password: |
-----BEGIN PGP MESSAGE-----
hQIMA4rOOq35JDJjAQ//b0lbfmzIRpCA2cq9OP55J6T5a4NUn9SbyNn8H/N0AiOB
yEYVyyHflpqBtlk+nUNFw2VgaxisJVf9drBpWGnDF9/tfNoBcKXYJXwusEYt1+3+
ZoWgqhEEQomIjxQ8l6oVW65k4EXkBdZoEJrRf0nVUULuCY9c+p2AVh73NEi0WEIs
Cta5IG9TZo/uKgzMElZLC9NcYC1jeG/rmi/zUWlc7Su2l2/U3ptn6jXyOhdhR4lh
BS1GfFpOD1l/SX9XW2XhUkj3WdwUxoO/slmDfNJ1i9kIjRhZB0axLUrN/1dDo1Ap
bzZ+gz/5sm2UmwwRFzoVxncbVUzWApo76CRIv6Zs2cPtNNMI0+jS2/rwx7pqbStN
ObIkN2GVW9MUmrcSMGP1B84Ds705wYMtvXfAUbwQqNPsYaQEqhfdEM+vZBX4j4Vj
LwRIIqiVJpU8TPjfJH42IdrSw5Hx0BjiBSdQ3lkKO95mybGmLprnvd4cYf6f22DS
RwHetsbUNIojlnDrhv2rUCzrJceDbpc7JPapVaIby+HnoYtPiZphwqJzLNKwAHPB
9Alji/1nMQPNDn7rJJu3PUXZTG2NBXxd
=GM3V
-----END PGP MESSAGE-----
cli_user_password: |
-----BEGIN PGP MESSAGE-----
hQIMA4rOOq35JDJjAQ/8Djz9+14Q3203wVnBFBM0hmayv6ZbuDHHVoWdVyl4fIpZ
Y3U7eGWt2OeKljxmVw0LxsHtUWb46ISGeepUf2MoBnfal41AHuehNpoZFWXATfuZ
XXXEEi+FbA2lsd3Ys7VwK7dDq5UH6Dy+o/XYP2BqViq5IUhJ1weHimsIPe79gnep
jKyywXY6UF3PQ+Vbmdw+Q/T/xiayZ940rmgbFDXbfhqX/cNZyTUPn21uet+xGn5Z
HuSfMi86BLpYIRNAt03Gegpte/2ZzwsOtt5t5/XutjWgHB5hTO8kOkH4gtQEz2fH
HjkmI0Akw+gSQ/GssbFUqqeOjrISA/hMTqwfIPvR2gC/gkQqn8mMfwMEDkvtCLBJ
3E5ZOmZAdJ/BVu8r+DRqEyaJwcI3Dumj4TRyaMuhsOUBxVjSrpl6DXkzAJdaBS8Q
bkmtb9uSJR3NjaM+sZsMLV8+d0m53nBqpBx6JgcUqO+7HZZtNBWKnDGGQ/m4jFvS
RwFAUdeZJMl6oFfhSmFLvtEMgGaygfoa+04T8/MjGdxwxBatJAS6kt7oCs4WfVGY
7ulcD6s4XD0haYhqsEc4aRJWTYRxBVpM
=WtyQ
-----END PGP MESSAGE-----

private_key: |
-----BEGIN PGP MESSAGE-----
7zT7IvlLa9xX/9lGCfB6WXoRYm+fS4lYMPfbd4aoj5I9+LZGKoIPK/n6PW+Zgh2Y
EPyJzZCRWTDnwzuw3oSE+T+DvJ+JqJ+qkgwUgSx+Sc1vtGiiw+LxXVJ9dJofI3Nl
Q7VMt2sj1cnU3wjQdnuqN5+yT8mnmF4PL+rb2EyTGG7AMx+Q5gspFJngMA0h4JhN
IeK0tqNpn5USztalh5b1Ha4JzyPmyFsVGXzTyRY2npHerebXQBt/R+j0ROVDCdal
wsJFjbBb3bFY7e1IZLxAh1rqSe7sswc37dDseh8ja7AbUglqu98NqfNdUuKfSb9C
r+Zr3qS6DnuFhgFMOmaDArdS7eaE0GkuvTh4G8mJFkFAfaks8W46wYOKZVWdtpat
m/ONAy62qXl1tsCHhwE5ZYxNHvZvf+8iWJ9vThLw1RtdTPBIllqjMvLIhBgi10nu
+HjB9zFOHezOvwjfs/O7cEa/HSJ1CNGo5QpMW3SPb1IpZdL1WiUmuK40B2ZFB7g1
7Hl2dkpkRuwkYE94FoszI/UXApYjpCndnAv62PP8Aa3Lxi4gwVCJUaSdHdC0kzoK
3Hrw5euNj34ONTZvpBGNdGwrU5LkwFdu5bP5xvdWIuMOentH4ELmq+bsFSYapnlU
d0QPBECR57Xc8tXiOk9D/SvWFOwc0xeKmrcdNbL1y96ApX6IGNhzx9wbSWkKH7jX
Idb5JlpkB7rgcFw7R557XZPfNSqdG0ovlJTF/zhB0JqCyeZQeh3sNdCgr711Iwmt
zXMOqa8Hfe/zkhuT58t9xrC9PX2HFrsJPCFR0JMXHTwRK8q0fzzrUREeot/g7mqP
ebPgV3MwqUm8kW3RbMovHygxPB0RGWONqJvoqv1LkfAHJRO5v2xvgHuv4yPmF73H
Qu/15cmNpr0Hdqv114o7zMajQwFrjx0hQASjCQQmJA+dl/o7k+FirO6Cu0ZjswGx
j6SeTpxNuoJrsTc+lHwqqcbQUC1GAtqo4uJ+b0UNpUId7EiCZpeH++PMdqC5l8V9
bVPnVzLtPqc68ajXqvv7hR//mzM+wVlraYJROQh19ZVT7ZG3hZj4sMAFhnbNbeh6
wpeaT9PC7RqZ8jWDHyMCUOkwiTdZz+kmH1K8+2n3Y/4WLgTR7b+qqiWPWvKksBRT
zojzGs7tUk6AgTFNyHUJqR1zqDy/GHdCFi+XBVHDCUrcKmt4fWTygSHOwibEPeJt
NOtp26cJ8vXYLZ7SA3VcWOPfNc9VRUxpfgFzYMqdVwg+kUdDKl7oXLIiMFUvTUDm
/C94NjFgaEm9ojo3WjMQgovAjeCrPrMV6FOCdOuHkJuSrMQTxDw7L1U3qmb9jfwX
/2gx2yNF6UyiVIutJLu3opvTjFLFD7AOW5FgWPQVC1jrrouoEwv0oiT16bLeYtRZ
4dtVbbeqroyAXFbqDQ1eEQSj2j/zT7ROrkd5Uyy2dhp+4A6oTNFhWzbXKaqFHE8N
fMnDRjhNXOJIF4jD2/faoCWGH6PDtK1xKi6nnzHKaetuwZxqKePhMnNatC1WRKIu
63ydQOluukYlPBjDdivUMYu2yRpEHFINpk6eBdD7JRvGoOeCJa+EATZxiLQX0qXb
e+6YyZGrVYmfWXrIJRNZ3aBuxI/lRDPj/V/xSsqZgttik5FPjSL74SX7fojS8ohC
KnX2bczWODpPkpTTxB+vNsYbGzDXv0qA00uFPrR8K3mBBjHKSER4NCkS6GWUsFr+
lxVIZakLrM42tVM/0bwI/g==
=W3Kv
-----END PGP MESSAGE-----
public_key: |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDv7Wnvougo06T55CL95NC7E53pdMtNQnxtghwZZivFRVICq6UzE3dQaJlVPhq0ITT0B9hLEHpi3GWG5YWXm+9QkfZkcB5WvDafrKTBrk6YfwIeMyhOCnH89R+T6GXfSDXef6ua0dIR5mVEP9hnZKESJzGDe0d+C4/jAIUSgoZ45l90HJP0LK1+WVWHhnJuHPRfWdUQw445dtKsJB4489c8hIAxnEbQRrmaiiu4nlRmdW96ErmgEImJHOA/r6eS8EbjV6pz/kCukniVRkStwaubPHMWlfyXWIPT8L jenkins
6 changes: 6 additions & 0 deletions pillars/top.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
base:

'G@roles:jenkins':
- _secret.jenkins


5 changes: 5 additions & 0 deletions states/jenkins/master/init.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include:
- ./install
- ./setup
- ./plugins
- ./jimmy
31 changes: 31 additions & 0 deletions states/jenkins/master/install.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Install jenkins package from official Jenkins LTS repositories

{% set jenkins_version = "2.32.1" %}


apt-transport-https:
pkg.installed

jenkins_repo:
pkgrepo.managed:
- name: deb https://pkg.jenkins.io/debian-stable binary/
- file: /etc/apt/sources.list.d/jenkins.list
- key_url: https://pkg.jenkins.io/debian-stable/jenkins.io.key
- require:
- pkg: apt-transport-https

prevent_startup_on_install:
file.managed:
- name: /usr/sbin/policy-rc.d
- contents: |
#!/bin/bash
exit 101
- mode: 0700

jenkins:
pkg.installed:
- version: {{ jenkins_version }}
- require:
- pkgrepo: jenkins_repo
- file: prevent_startup_on_install
49 changes: 49 additions & 0 deletions states/jenkins/master/jimmy.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Setup and run Jimmy (https://github.com/ci-team/jimmy.git) - tool to perform Jenkins master configuration

{% set jenkins = salt['pillar.get']('jenkins') %}

{% set venv_path = "/opt/jimmy" %}
{% set jimmy_sources = "git+https://github.com/ci-team/jimmy.git" %}
{% set config_prefix = "/var/lib/jenkins/jimmy" %}
{% set jimmy_config = "{0}/jimmy.yaml".format(config_prefix) %}
{% set jenkins_config = "{0}/jenkins.yaml".format(config_prefix) %}

python-tox:
pkg.installed

virtualenv:
pkg.installed

jimmy_venv:
virtualenv.managed:
- name: {{ venv_path }}
- pip_pkgs:
- {{ jimmy_sources }}

jimmy_config:
file.managed:
- name: {{ jimmy_config }}
- source: salt://jenkins/master/templates/jimmy.yaml.j2
- template: jinja
- context:
jenkins_config: {{ jenkins_config }}
- makedirs: True

jenkins_config:
file.managed:
- name: {{ jenkins_config }}
- source: salt://jenkins/master/templates/jenkins.yaml.j2
- template: jinja
- context:
cli_user_pub_key: {{ jenkins.public_key }}
cli_user_password: {{ jenkins.cli_user_password }}
jjb_password: {{ jenkins.jjb_password }}
- makedirs: True
- replace: True

run_jimmy:
cmd.run:
- cwd: {{ venv_path }}
- runas: jenkins
- shell: /bin/bash # needed for the source command
- name: "source {{ venv_path }}/bin/activate && jimmy --conf-path {{ jimmy_config }} -e main"
36 changes: 36 additions & 0 deletions states/jenkins/master/pillars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Secrets pillar

jenkins:
jjb_password: admin
cli_user_password: admin
private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAv+667OhUMm+y3Ry+CyoNpuP4WMiC/zPRNgtF9CmZx1OuOWFY
hkXq3aAcKRHfLRStUHQEmfOQYAcFdCmzCAJ3DBQAqE2mOEaHIlFXY1M8O6wsqzPY
sO/ltosJwWSWCTuY7SBU6XTsTSpgwl2w0kssYEGN5h1fdW25E3mXuXp8HmBF7fjK
OLnDxwsye/9abwqVxD/rwAyxvRRwR4mLnzdD2tuJI9Klme4cZ/NWBd4ZJNGUavuB
jRK2fUytxVxDgghfsML2eXU72CoRxW+3hxpRHlk+lsLY0yF+KZSszWVZstwISf7s
oqE3WTCemi2d9Me1b0i0MTbxcpKz0tAV7aLnHwIDAQABAoIBAHsuL1/OuALqt0O7
p6ioo7xhgUkR3ykEy5fA4nOSo3RPG3kOJe9/Pf5hPNGK+84GADmrTCy2KgnHV9O2
04Und9oTmFxsAWsKsL3wsII5sGWn2b9C9iaQwMBIOcmZ0cU5L6u4XWa7uNDJivIT
iWFeB6v7RqPSZCqMcgSyvBK5LqGbEEtIbz54bmY9zVQV9nspvcUXFzeMpKK3mpX1
R8RbL98Xy3OfMFQLx3+1TaclppzBuC6OJM8hYMHG5hijj+FUrZUeIu6Qyv/TAp2U
Ki1+AGTZ/YaKRL1L/b7So1Y5Pcclavz8ZNod8sq+PgqNXqr2qZCkHZYz5g8Cxg/O
jfWOTXkCgYEA9CVQFgma0ZnImCEJo3dUtwwvay7SO9VDGbmfi8Mdn+bXqVMFLyh5
tJVuKqpZwAnKvcPvwOe0Cm4WDY/JufrpRJ3Ubg5rkCXrvuJEyYnFRL8m2ziDvtAi
PAhfu7BcRyTvYk3GqJsZWyh+H70HSyEV+iSJAnJ9rmL3nYERA7hakQsCgYEAyUBq
p+iLhBaIRs1Kgcit8idl0Dpv6pFC+CUSEWDuFCXs9jYHFTlFQDvC5TouEAq+Wx8O
Nx21fTrP9hKptHlecor2nYV/PPsdp8hwBJDtIT42WR2MoOICrbnn91jDipzBeguJ
dAR+q5Lud1YT7dn/bWcKUwhanetU9yELm+f4tr0CgYEA3Mm9kiBffPuIt2LxN34c
A2mmnFR8VRW4l9QRH7B04v08vOjSQGJnJdMZDMZ/Yba5PUGrWRVw8Rm7IcqN0H3D
ZIUi7eBmj7ZranVvZZ8M4e3H8uo54l6RBx8/jBmiachSH+FcLXANzy1gWc11ghDK
sitGKAtn80OW0D4/J9EZPh8CgYEAkK8q/oQEqXW5i41Tn3Ky+4CvhcA9bZn5V4Tv
NGdHQlzxuyCkfvGpg8BzIXFuZEIVEFWHVsCZFesOT46jSwhmilq1ahHro9+1Nka3
odC/akLbt72yuIdD/bnFtuGt0x1XS3K34xzIJHmBz3Gm6jzrka+ekItU+muRrgmn
2vIusNECgYBxaGFHbyP6mctGeiFkjzEAHWu6gx1K7A8tvIplL39tlYR0m+zRsFjG
i9XlZPgWx4Q49IB95MCEeW6JBepMYLNfsRYLEy62iPdzpvV0ruSYxF4wMNcI+6YC
SnkZ1sr6uE7GVD/dF0v5ric2CHe1HIMvnWHT1N0YRaD4qaNcbnmgyg==
-----END RSA PRIVATE KEY-----
public_key: |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/7rrs6FQyb7LdHL4LKg2m4/hYyIL/M9E2C0X0KZnHU645YViGRerdoBwpEd8tFK1QdASZ85BgBwV0KbMIAncMFACoTaY4RociUVdjUzw7rCyrM9iw7+W2iwnBZJYJO5jtIFTpdOxNKmDCXbDSSyxgQY3mHV91bbkTeZe5enweYEXt+Mo4ucPHCzJ7/1pvCpXEP+vADLG9FHBHiYufN0Pa24kj0qWZ7hxn81YF3hkk0ZRq+4GNErZ9TK3FXEOCCF+wwvZ5dTvYKhHFb7eHGlEeWT6WwtjTIX4plKzNZVmy3AhJ/uyioTdZMJ6aLZ30x7VvSLQxNvFykrPS0BXtoucf jenkins

117 changes: 117 additions & 0 deletions states/jenkins/master/plugins.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Contains list of plugins to be installed.
#
# Each plugin is defined by dictionary
# {
# 'name': 'short-name',
# 'version': '0.0.1',
# 'url': 'http://example.com/full/path/to/plugin.hpi', # optional
# }
#
# To obtain list of plugins from working Jenkins installation one can use the following script:
#
###################################################################################################
# #!/usr/bin/env python
#
# import argparse
# import ConfigParser
# import jenkins
# import pprint
# import toposort
#
# parser = argparse.ArgumentParser()
# parser.add_argument("-c", "--conf", required=True,
# help="Path to jenkins-job-builder config file")
# args = parser.parse_args()
#
# config = ConfigParser.RawConfigParser()
# config.read(args.conf)
#
# jenkinsurl = config.get('jenkins', 'url')
# username = config.get('jenkins', 'user')
# password = config.get('jenkins', 'password')
#
# j = jenkins.Jenkins(jenkinsurl, username, password)
#
# data = j.get_plugins()
#
# graph = {}
# for (key, long_key) in data.keys():
# graph[key] = set([ item['shortName'] for item in data[key]['dependencies']])
#
# sorted_list = toposort.toposort_flatten(graph)
#
# plugins = []
#
# for plugin in sorted_list:
# plugins.append(
# {
# 'name': plugin,
# 'version': str(data[plugin]['version']),
# }
# )
#
# pprint.pprint(plugins)
#
###################################################################################################

{% set plugins = [
{'name': 'bouncycastle-api', 'version': '2.16.0'},
{'name': 'StashBranchParameter', 'version': '0.2.0'},
{'name': 'ace-editor', 'version': '1.1'},
{'name': 'credentials', 'version': '2.1.10'},
{'name': 'external-monitor-job', 'version': '1.6'},
{'name': 'gradle', 'version': '1.25'},
{'name': 'icon-shim', 'version': '2.0.3'},
{'name': 'javadoc', 'version': '1.4'},
{'name': 'jquery-detached', 'version': '1.2.1'},
{'name': 'scm-api', 'version': '1.3'},
{'name': 'script-security', 'version': '1.25'},
{'name': 'structs', 'version': '1.5'},
{'name': 'token-macro', 'version': '2.0'},
{'name': 'windows-slaves', 'version': '1.2'},
{'name': 'ant', 'version': '1.4'},
{'name': 'cloudbees-folder', 'version': '5.15'},
{'name': 'junit', 'version': '1.19'},
{'name': 'plain-credentials', 'version': '1.3'},
{'name': 'ssh-credentials', 'version': '1.12'},
{'name': 'workflow-step-api', 'version': '2.6'},
{'name': 'antisamy-markup-formatter', 'version': '1.5'},
{'name': 'branch-api', 'version': '1.11.1'},
{'name': 'config-file-provider', 'version': '2.15.1'},
{'name': 'credentials-binding', 'version': '1.10'},
{'name': 'display-url-api', 'version': '0.5'},
{'name': 'git-client', 'version': '2.2.0'},
{'name': 'matrix-auth', 'version': '1.4'},
{'name': 'matrix-project', 'version': '1.7.1'},
{'name': 'pam-auth', 'version': '1.3'},
{'name': 'timestamper', 'version': '1.8.7'},
{'name': 'workflow-api', 'version': '2.8'},
{'name': 'workflow-scm-step', 'version': '2.3'},
{'name': 'description-setter', 'version': '1.10'},
{'name': 'mailer', 'version': '1.18'},
{'name': 'mercurial', 'version': '1.57'},
{'name': 'multi-slave-config-plugin', 'version': '1.2.0'},
{'name': 'slack', 'version': '2.1'},
{'name': 'workflow-support', 'version': '2.11'},
{'name': 'git', 'version': '3.0.1'},
{'name': 'ivy', 'version': '1.26'},
{'name': 'ldap', 'version': '1.13'},
{'name': 'maven-plugin', 'version': '2.14'},
{'name': 'rebuild', 'version': '1.25'},
{'name': 'workflow-cps', 'version': '2.23'},
{'name': 'analysis-core', 'version': '1.82'},
{'name': 'anything-goes-formatter', 'version': '1.0'},
{'name': 'artifactory', 'version': '2.8.2'},
{'name': 'build-timeout', 'version': '1.18'},
{'name': 'cloudbees-bitbucket-branch-source', 'version': '1.9'},
{'name': 'greenballs', 'version': '1.15'},
{'name': 'jobConfigHistory', 'version': '2.15'},
{'name': 'jquery', 'version': '1.11.2-0'},
{'name': 'simple-theme-plugin', 'version': '0.3'},
{'name': 'stash-pullrequest-builder', 'version': '1.7.0'},
{'name': 'stashNotifier', 'version': '1.11.4'},
{'name': 'checkstyle', 'version': '3.47'},
{'name': 'findbugs', 'version': '4.69'},
]
%}

25 changes: 25 additions & 0 deletions states/jenkins/master/plugins.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Install set of plugins on local Jenkins instance via Jenkins cli
{% from 'jenkins/master/plugins.jinja' import plugins with context %}
{% set jenkins_cli = "/var/cache/jenkins/war/WEB-INF/jenkins-cli.jar" %}
{% set default_url = "http://updates.jenkins-ci.org/download/plugins/{plugin_name}/{plugin_version}/{plugin_name}.hpi" %}
{% for plugin in plugins %}
{% set plugin_url = plugin.get('url', default_url.format(plugin_name=plugin.name, plugin_version=plugin.version)) %}
jenkins_plugin {{ plugin.name }}:
cmd.run:
- name: "java -jar {{ jenkins_cli }} -s http://localhost:8080/ install-plugin {{ plugin_url }}"
- unless: |
version_string=`java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://localhost:8080/ list-plugins {{ plugin.name }}` && version=`echo ${version_string%(*)} | awk '{print $NF}'` && [ "$version" == "{{ plugin.version }}" ]
- runas: jenkins
- shell: /bin/bash
- watch_in:
- service: jenkins_restart
{% endfor %}
jenkins_restart:
service.running:
- name: jenkins
- init_delay: 60 # Jenkins start is slow
Loading

0 comments on commit 97b7c16

Please sign in to comment.