First commit
This commit is contained in:
commit
e54b5a5663
24 changed files with 3047 additions and 0 deletions
24
roles/jenkins-php-v1/tasks/00_precheck.yml
Normal file
24
roles/jenkins-php-v1/tasks/00_precheck.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
|
||||
# Etckeeper is a small fondness of mine, it semi-automatically
|
||||
# keep track of /etc with git.
|
||||
# Feel free to remove all this if you'rs not interested.
|
||||
- name: detect etckeeper presence
|
||||
shell: "which etckeeper"
|
||||
ignore_errors: True
|
||||
register: tmp
|
||||
changed_when: False
|
||||
|
||||
- name: Set fact about etckeeper presence
|
||||
set_fact:
|
||||
etckeeper_installed: "{{ tmp.rc == 0 }}"
|
||||
|
||||
- name: Check that /etc is clean
|
||||
shell: etckeeper unclean && echo "Uncommitted changes." && return 1 || return 0
|
||||
ignore_errors: True # we add a 'fail' task to tell the problem more explictly.
|
||||
register: tmp
|
||||
changed_when: False
|
||||
when: etckeeper_installed
|
||||
- fail:
|
||||
msg: "Etckeeper is installed but there is uncommitted changes in /etc."
|
||||
when: etckeeper_installed and tmp.rc != 0
|
65
roles/jenkins-php-v1/tasks/10_jenkins-repository.yml
Normal file
65
roles/jenkins-php-v1/tasks/10_jenkins-repository.yml
Normal file
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
|
||||
# Add Jenkins repository for Debian
|
||||
- name: Add Jenkins-stable.io repository key
|
||||
apt_key:
|
||||
id: "150FDE3F7787E7D11EF4E12A9B7D32F2D50582E6"
|
||||
data: "{{ lookup('file', 'jenkins-stable.io.pem') }}"
|
||||
state: present
|
||||
register: tmp
|
||||
- name: New APT sources - commit
|
||||
command: "etckeeper commit 'apt: Jenkins repository key added by Ansible'"
|
||||
when: tmp.changed and etckeeper_installed
|
||||
|
||||
- name: Check if /etc/apt/sources.list.d/jenkins.list is managed by ansible
|
||||
shell: "grep -ic '# This file is managed by Ansible' /etc/apt/sources.list.d/jenkins.list || true"
|
||||
register: result
|
||||
changed_when: false
|
||||
- name: Config /etc/apt/sources.list.d/jenkins.list file
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: /etc/apt/sources.list.d/jenkins.list
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
backup: no
|
||||
force: "{{ result.stdout is defined and result.stdout == '1' }}" # Only manage the file if the header is present
|
||||
with_first_found:
|
||||
- "jenkins.list.{{ ansible_fqdn }}.j2"
|
||||
- "jenkins.list.j2"
|
||||
register: tmp
|
||||
- name: New APT sources - commit
|
||||
command: "etckeeper commit 'apt: Jenkins repository added/changed by Ansible'"
|
||||
when: tmp.changed and etckeeper_installed
|
||||
- name: Update APT cache
|
||||
apt:
|
||||
update_cache: yes
|
||||
when: tmp.changed
|
||||
|
||||
# Install Jenkins
|
||||
# (note: the Jenkins package doesn't wait for Java to be installed
|
||||
# before trying to launch itself, so we install them separately)
|
||||
# (note2: in case we go back downloading the .war, here is a command to
|
||||
# verify it: jarsigner -verbose -certs -verify /tmp/jenkins.war
|
||||
- name: Install Java
|
||||
apt:
|
||||
name:
|
||||
- default-jdk
|
||||
state: present
|
||||
- name: Install Jenkins package
|
||||
apt:
|
||||
name:
|
||||
- jenkins
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: Loop until Jenkins is available
|
||||
get_url:
|
||||
url: "http://localhost:8080/login"
|
||||
dest: "/dev/null"
|
||||
force: True
|
||||
register: tmp
|
||||
until: tmp.status_code is defined and tmp.status_code == 200 or result.changed == False
|
||||
retries: 10
|
||||
delay: 5
|
||||
changed_when: False
|
50
roles/jenkins-php-v1/tasks/20_install-plugins.yml
Normal file
50
roles/jenkins-php-v1/tasks/20_install-plugins.yml
Normal file
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
|
||||
# Install plugins
|
||||
# inspired by https://github.com/geerlingguy/ansible-role-jenkins MIT (Expat) / BSD)
|
||||
# but we couldn't use jenkins_plugin's Ansible module because of crumb (CSRF) problems with our version
|
||||
|
||||
# Get current plugin list
|
||||
# Warning : it may not be up to date if Jenkins hasn't been restarted after last plugin install
|
||||
- name: Get the current plugin list
|
||||
shell: "{{ jenkins_cli_command }} list-plugins | awk '{ print $1 }'"
|
||||
changed_when: False
|
||||
check_mode: no
|
||||
register: current_plugin_list
|
||||
|
||||
## Update Jenkins so that plugin updates don't fail.
|
||||
#- name: Create Jenkins updates directory.
|
||||
# file:
|
||||
# path: "{{ jenkins_home }}/updates"
|
||||
# state: directory
|
||||
# owner: jenkins
|
||||
# group: jenkins
|
||||
#
|
||||
#- name: Download current plugin updates from Jenkins update site.
|
||||
# get_url:
|
||||
# url: "{{ jenkins_updates_url }}/update-center.json"
|
||||
# dest: "{{ jenkins_home }}/updates/default.json"
|
||||
# owner: jenkins
|
||||
# group: jenkins
|
||||
# mode: 0440
|
||||
# changed_when: false
|
||||
# register: get_result
|
||||
# until: get_result is success
|
||||
# retries: 3
|
||||
# delay: 2
|
||||
#
|
||||
#- name: Remove first and last line from json file.
|
||||
# replace:
|
||||
# path: "{{ jenkins_home }}/updates/default.json"
|
||||
# regexp: "1d;$d"
|
||||
|
||||
- name: Install Jenkins plugins.
|
||||
shell: "{{ jenkins_cli_command }} install-plugin {{ item | quote }}"
|
||||
with_items: "{{ jenkins_plugins }}"
|
||||
when: item not in current_plugin_list.stdout_lines
|
||||
notify: safe-restart jenkins and wait
|
||||
|
||||
- name: Install system package needed by Jenkins plugins
|
||||
apt:
|
||||
name: "{{ jenkins_plugins_system_dependency }}"
|
||||
state: present
|
29
roles/jenkins-php-v1/tasks/30_users.yml
Normal file
29
roles/jenkins-php-v1/tasks/30_users.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
|
||||
- name: Check if Gitea user has already been created
|
||||
stat:
|
||||
path: "{{ jenkins_gitea_password_file }}"
|
||||
register: result
|
||||
|
||||
- name: Do we have to create the Gitea user
|
||||
set_fact:
|
||||
createGiteaUser: "{{ result.stat.exists is undefined or result.stat.exists == False }}"
|
||||
|
||||
- name: Generate a password for the Gitea user
|
||||
set_fact:
|
||||
giteaPassword: "{{ lookup('password', '/dev/null chars=ascii_letters') }}"
|
||||
when: createGiteaUser
|
||||
|
||||
- name: Create Gitea user
|
||||
shell: echo 'jenkins.model.Jenkins.instance.securityRealm.createAccount("gitea", "{{ giteaPassword | quote }}")' | "{{ jenkins_cli_command }}" groovy =
|
||||
when: createGiteaUser
|
||||
|
||||
- name: Upload the new password
|
||||
copy:
|
||||
content: "{{ giteaPassword }}"
|
||||
dest: "{{ jenkins_gitea_password_file }}"
|
||||
owner: jenkins
|
||||
group: jenkins
|
||||
mode: 0600
|
||||
when: createGiteaUser
|
||||
#no_log: yes # FIXME: actually, we want to know it to tell the user to set a URL with it in Gitea. Add a debug msg maybe ?
|
85
roles/jenkins-php-v1/tasks/40_configure-jenkins.yml
Normal file
85
roles/jenkins-php-v1/tasks/40_configure-jenkins.yml
Normal file
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
|
||||
# Needed to write a config.xml which is not changed at each Ansible run
|
||||
- name: Get current Jenkins version
|
||||
shell: "{{ jenkins_cli_command }} version"
|
||||
changed_when: False
|
||||
check_mode: no
|
||||
register: result
|
||||
- name: Set fact about current Jenkins version
|
||||
set_fact:
|
||||
current_jenkins_version: "{{ result.stdout_lines[0] }}"
|
||||
|
||||
- name: Upload main config.xml
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ jenkins_home }}/config.xml"
|
||||
owner: jenkins
|
||||
group: jenkins
|
||||
mode: 0644
|
||||
backup: yes
|
||||
with_first_found:
|
||||
- "config.xml.{{ ansible_fqdn }}.j2"
|
||||
- "config.xml.j2"
|
||||
notify: safe-restart jenkins and wait
|
||||
|
||||
- name: Upload JenkinsLocationConfiguration.xml
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ jenkins_home }}/jenkins.model.JenkinsLocationConfiguration.xml"
|
||||
owner: jenkins
|
||||
group: jenkins
|
||||
mode: 0644
|
||||
backup: yes
|
||||
with_first_found:
|
||||
- "jenkins.model.JenkinsLocationConfiguration.xml.{{ ansible_fqdn }}.j2"
|
||||
- "jenkins.model.JenkinsLocationConfiguration.xml.j2"
|
||||
notify: safe-restart jenkins and wait
|
||||
|
||||
# Generate a SSH RSA key pair if not already present
|
||||
# (we do it without the Ansible module which is only available starting 2.8)
|
||||
# (and we don't use become/become_user because it fails with a permission denied on /tmp/.ansible...)
|
||||
- name: Generate SSH RSA key pair
|
||||
command: su -c 'ssh-keygen -q -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""' - jenkins
|
||||
args:
|
||||
creates: "{{ jenkins_home }}/.ssh/id_rsa"
|
||||
#become_user: jenkins # permission denied
|
||||
#become: yes
|
||||
register: result
|
||||
- name: Retrieve the SSH private key
|
||||
slurp:
|
||||
src: "{{ jenkins_home }}/.ssh/id_rsa.pub"
|
||||
register: tmp
|
||||
when: result.changed
|
||||
- name: Ouput public key
|
||||
debug:
|
||||
msg: "Don't forget to set the public key on the Git repository and the deploy target : {{ tmp.content | b64decode | trim }}"
|
||||
when: result.changed
|
||||
|
||||
# Upload this new key to the Jenkins credentials plugin system
|
||||
# (the create/update/import-credential-as-xml is kinda cumbersome for our
|
||||
# usecase. No way to export the key or get a MD5/SHA256 of it, so we just
|
||||
# go for the credentials.xml file directly :)
|
||||
- name: Retrieve the SSH private key
|
||||
slurp:
|
||||
src: "{{ jenkins_home }}/.ssh/id_rsa"
|
||||
register: tmp
|
||||
no_log: yes
|
||||
- name: Set fact about SSH key
|
||||
set_fact:
|
||||
ssh_private_key: "{{ tmp.content | b64decode | trim }}"
|
||||
no_log: yes
|
||||
- name: Upload SSH RSA key pair as credential in Jenkins
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ jenkins_home }}/credentials.xml"
|
||||
owner: jenkins
|
||||
group: jenkins
|
||||
mode: 0600
|
||||
force: yes
|
||||
backup: yes
|
||||
with_first_found:
|
||||
- "credentials.xml.{{ ansible_fqdn }}.j2"
|
||||
- "credentials.xml.j2"
|
||||
notify: safe-restart jenkins and wait
|
||||
#shell: cat /tmp/tmp.xml | java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://localhost:8080/ -auth admin:$( cat /var/lib/jenkins/secrets/initialAdminPassword ) create-credentials-by-xml system::system::jenkins _
|
18
roles/jenkins-php-v1/tasks/50_create-jobs.yml
Normal file
18
roles/jenkins-php-v1/tasks/50_create-jobs.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
|
||||
# We need Jenkins to reboot if new plugins were installed.
|
||||
- meta: flush_handlers
|
||||
|
||||
- name: Get the list of jobs that already exist
|
||||
shell: "{{ jenkins_cli_command }} list-jobs"
|
||||
changed_when: False
|
||||
check_mode: no
|
||||
register: current_jobs_list
|
||||
|
||||
# Loop on every job we maintain
|
||||
- name: Manage each job
|
||||
include_tasks:
|
||||
file: include_jobinstall.yml
|
||||
loop: "{{ lookup('dict', jobs ) }}"
|
||||
loop_control:
|
||||
loop_var: job
|
28
roles/jenkins-php-v1/tasks/include_jobinstall.yml
Normal file
28
roles/jenkins-php-v1/tasks/include_jobinstall.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
|
||||
# When the job doesn't exist, we provide an empty XML, and then work
|
||||
# directly on the jenkins_home/jobs/JOB/config.xml file
|
||||
- name: Create a empty job
|
||||
shell: "echo '<project />' | {{ jenkins_cli_command }} create-job {{ job.key | quote }}"
|
||||
when: job.key not in current_jobs_list.stdout_lines
|
||||
|
||||
- name: Upload job config template
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
# if job exists, we write directly to jobs/JOBNAME/config.xml, else we write to the tmp file.
|
||||
dest: "{{ jenkins_home + '/jobs/' + job.key + '/config.xml' }}"
|
||||
mode: 0600
|
||||
owner: jenkins
|
||||
group: jenkins
|
||||
backup: yes
|
||||
force: yes
|
||||
with_first_found:
|
||||
- "jobs/config.xml.{{ ansible_fqdn }}.{{ job.key }}.j2"
|
||||
- "jobs/config.xml.{{ job.key }}.j2"
|
||||
- "jobs/config.xml.{{ ansible_fqdn }}.j2"
|
||||
- "jobs/config.xml.j2"
|
||||
register: jobconfig
|
||||
|
||||
- name: Reload the job
|
||||
shell: "{{ jenkins_cli_command }} reload-job {{ job.key | quote }}"
|
||||
when: jobconfig.changed
|
16
roles/jenkins-php-v1/tasks/include_saferestartandwait.yml
Normal file
16
roles/jenkins-php-v1/tasks/include_saferestartandwait.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
|
||||
- name: safe-restart jenkins and wait (include)
|
||||
block:
|
||||
- name: safe-restart jenkins
|
||||
shell: "{{ jenkins_cli_command }} safe-restart"
|
||||
- name: Loop until Jenkins is available
|
||||
get_url:
|
||||
url: "http://localhost:8080/login"
|
||||
dest: "/dev/null"
|
||||
force: True
|
||||
register: result
|
||||
until: result.status_code is defined and result.status_code == 200
|
||||
retries: 10
|
||||
delay: 5
|
||||
changed_when: False
|
41
roles/jenkins-php-v1/tasks/main.yml
Normal file
41
roles/jenkins-php-v1/tasks/main.yml
Normal file
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
|
||||
# Usually, we only install Jenkins and let it live its life,
|
||||
# so if it seems to be already installed, we skip this task.
|
||||
- name: Check if /var/lib/jenkins exists
|
||||
stat:
|
||||
path: "{{ jenkins_home }}"
|
||||
register: result
|
||||
- name: No going further if jenkinsonlyinstall is set and Jenkins is already installed
|
||||
set_fact:
|
||||
gogogo: "{{ jenkins_installonly is undefined or jenkins_installonly == False or result.stat.isdir is undefined or result.stat.isdir == False }}"
|
||||
|
||||
- name: Warning about confidentiality
|
||||
pause:
|
||||
prompt: "Warning: this role will manage and display a lot of passwords and keys readable through the Ansible log and the process infos on each host. Sorry..."
|
||||
seconds: 1 # TODO: 10
|
||||
when: gogogo
|
||||
|
||||
|
||||
# Pre-check
|
||||
- include_tasks: roles/jenkins-php-v1/tasks/00_precheck.yml
|
||||
when: gogogo
|
||||
|
||||
# Install Jenkins via the upstream repository
|
||||
- include_tasks: roles/jenkins-php-v1/tasks/10_jenkins-repository.yml
|
||||
when: gogogo
|
||||
|
||||
- include_tasks: roles/jenkins-php-v1/tasks/20_install-plugins.yml
|
||||
when: gogogo
|
||||
|
||||
# At the moment, groups or roles are kinda overkill
|
||||
# (but it probably will get back on us at the end...)
|
||||
- include_tasks: roles/jenkins-php-v1/tasks/30_users.yml
|
||||
when: gogogo
|
||||
|
||||
# Big configuration step : ACL, SSH keys aka. credentials, etc.
|
||||
- include_tasks: roles/jenkins-php-v1/tasks/40_configure-jenkins.yml
|
||||
when: gogogo
|
||||
|
||||
- include_tasks: roles/jenkins-php-v1/tasks/50_create-jobs.yml
|
||||
when: gogogo
|
Reference in a new issue