Jenkins Workflow plugin lets you write Jenkins jobs as pipelines using the Groovy programming language
Talk given in french at the Lyon JUG - 15/12/2015
17. PROBLÈME
Complexe à mettre en oeuvre
On finit par avoir des jobs "étapes"
File d'exécution impossible à lire
Un job a des successeurs prédéterminés
Le paramétrage se fait dans Jenkins
Solution peu utilisable pour du déploiement continu
18. DÉPLOIEMENT CONTINU
Le but du déploiement continu est d'avoir une application
stable en production.
La chaine de livraison doit être automatisée au maximum
pour réduire l'intervention humaine entre une modification
de code et sa livraison en production.
L'erreur est humaine
19. QUEL INTERVALE DE TEMPS ENTRE
DEUX MEP ?
Ce n'est pas le but premier du déploiement continu.
Pouvoir livrer rapidement ne veut pas dire livrer
régulièrement.
20. GO DELIVERY
Un build est composé d'étapes
Chaque build peut être appliqué à un environnement
Fan-out-in (parallelisation des étapes)
22. BONNES IDÉES
Parallèlisation des étapes
Environnements de déploiement
Visualisation du build et de l'étape en cours
Possibilité d'avoir plusieurs repositories en entrée
PROBLÈMES
Configuration gérée dans l'outil
Pas de possibilité de scripter le job
Difficulté pour gérer plusieurs versions nécessitant des
jobs différents
28. JENKINSFILE
Fichier de build en Groovy
Du build au deploy dans un fichier compréhensible
Permet une orchestration plus avancée
Convention de nommage : Jenkinsfile
node {
git url: 'https://github.com/spring-projects/spring-petclinic.git'
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B verify"
}
29. JENKINSFILE
Le base de code déclare elle-même comment s'installer
Différentes versions (tags/branches/commits) peuvent
avoir des manières différentes de s'installer
node {
git url: 'https://github.com/spring-projects/spring-petclinic.git'
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B verify"
}
36. VALIDATION HUMAINE
input 'Est-ce que la page ${url} est correcte ?'
Si cette validation intervient avant le déploiement, on fait de
la livraison continue
40. PARALLEL
for (int i = 0; i < splits.size(); i++) {
branches["split${i}"] = {
node('remote') {
sh 'rm -rf *'
sh "${tool 'M3'}/bin/mvn -B -Dmaven.test.failure.ignore test"
}
}
}
parallel branches
parallel prend une map en paramètre
la clé représente le nom de la branche
la valeur correspond au bloc de code à exécuter
42. STAGE
Permet de séparer le phases du job
Permet de limiter le nombre d'exécutions parallèles
stage 'build'
sh "${tool 'M3'}/bin/mvn clean install"
stage concurrency: 1, name: 'deploy'
sh 'mv target/app.war /tmp/webapps/'
43. STAGE
stage 'build'
sh "${tool 'M3'}/bin/mvn clean install"
stage name: 'deploy', concurrency: 1
sh 'mv target/app.war /tmp'
Tant que le stage deploy n'est pas terminé, les exécutions
suivantes s'arrêtent avant deploy
Si plusieurs exécutions sont en attente de deploy, c'est la
dernière qui est retenue.
45. CHARGEMENT D'UN FICHIER DE
SCRIPT
node{
def install = load 'install.groovy'
install.main()
}
Permet de diviser le script de build en plusieurs parties
46. SUIVI À L'IHM : OPEN SOURCE
Liens pour afficher les logs de chaque étape
48. LONGUE INSTALLATION
Les builds de Workflow survivent à un redémarrage de
Jenkins
Le thread d'orchestration ne s'exécute que pour lancer la
prochaine tache
49. RÉSUMÉ
Une orchestration intégrée à la base de code
Un langage expressif (DSL workflow et Groovy)
Parallèlisation et distribution des tâches
Pipeline de déploiement continu
52. MULTIBRANCH
Pour chaque branche à la racine de ce repository doit se
trouver le fichier Jenkinsfile
Les branches sont scrutées régulièrement et mises à jour et
lancées
On peut utiliser un hook pour lancer les builds
54. DOCKER TO THE RESCUE !
Docker est la solution à tout de toutes manières
55. WORKFLOW DANS UNE IMAGE
DOCKER
docker.image('maven:3.3.3-jdk-8').inside {
sh 'mvn -B clean install'
}
Le répertoire courant dans docker est le workspace Jenkins
Montage du workspace dans un volume docker
Plus de problèmes d'outils, mis à part Docker qui doit être
installé sur les slaves
Le container est supprimé après son exécution
58. DOCKER BUILD
node {
git scm // Récupérer le repository git en mode multibranch
def myEnv = docker.build "my-environment:${env.BUILD_TAG}"
myEnv.push()
}
Utilisation du tag git pour pousser dans le registry
59. DOCKER POUR TESTER
node {
git scm
docker.image('mysql').withRun('-p 81:3126') {c ->
sh './test-with-local-db'
}
}
On veut exécuter le corps du withRun alors que l'image
mysql tourne
Le withRun prend optionnellement les paramètres du
docker run
Adapté aux tests d'intégration
61. DOCKER SERVER
docker.withServer('tcp://swarm.mycorp.com:2376', 'swarm-certs'){
docker.image('httpd').withRun('-p 8080:80') {c ->
sh "curl -i http://${hostIp(c)}:8080/"
}
}
def hostIp(container) {
sh "docker inspect -f {{.Node.Ip}} ${container.id} > hostIp"
readFile('hostIp').trim()
}
Possibilité de déléguer à un serveur docker (swarm ou autre)
Le client docker doit être installé
A utiliser si le slave ne peut pas supporter l'application à
tester