Service Jenkins Runner

De EjnTricks

Jenkins Runner.png

Jenkins est une simple application web qui peut être déployée sur un serveur, comme Tomcat. Cependant ce mode d'installation peut causer des problèmes notamment avec les plugins qui ne gèrent pas toujours les accès avec une sous racine. Cet article présente l'utilisation de Jenkins Runner qui utilise Java Service Wrapper pour créer des services, quelque soit la plateforme, à partir d'application Java.


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Folder-icon.png Initialisation

L'application va être mise ne place dans le répertoire /var/opt/jenkins avec une organisation qui doit permettre de faciliter les montées de version.

#sudo mkdir -p /var/opt/jenkins

Warning-icon.png Attention, Jenkins utilise la variable d'environnement user.home pour stocker des informations. Un répertoire est donc créé sur la machine et sera utilisé comme répertoire Home du compte utilisateur.

#sudo mkdir -p /var/opt/jenkins/common/home


User-icon.png Compte de service

Cette installation ayant pour but d'être exécutée sous la forme d'un service, le compte root va être employé et ce n'est pas très sécurisé. Or il est possible de spécifier un compte utilisateur dans le script de démarrage de l'application. A l'instar d'application comme Tomcat, un compte technique est mis en place et sera exploité.

Warning-icon.png Attention le bash /bin/false est généralement utilisé pour les comptes de service. Du fait de l'implémentation du script de démarrage, il est nécessaire que le bash associé au compte soit un "vrai" bash, dans ce cas /bin/bash.

Le répertoire home préalablement créé est utilisé.

#sudo adduser --shell /bin/bash --system --home /var/opt/jenkins/common/home --group jenkins
Ajout de l'utilisateur système « jenkins » (UID 133) ...
Ajout du nouveau groupe « jenkins » (GID 142) ...
Ajout du nouvel utilisateur « jenkins » (UID 133) avec pour groupe d'appartenance « jenkins » ...
Création du répertoire personnel « /var/opt/jenkins/common/home »...
#sudo chown jenkins:jenkins /var/opt/jenkins
#sudo chmod -R go-rwx /var/opt/jenkins


Download-icon.png Téléchargement

Puis la version est téléchargée dans le répertoire /tmp.

#sudo wget -O /var/opt/jenkins/runner.zip https://github.com/mnadeem/JenkinsRunner/archive/master.zip


System-Install-icon.png Installation

Puis il faut décompresser l'archive dans la structure personnalisée sous /var/opt/jenkins.

#sudo mkdir -p /var/opt/jenkins/runner
#sudo unzip /var/opt/jenkins/runner.zip -d /var/opt/jenkins/runner
#sudo mv /var/opt/jenkins/runner/JenkinsRunner-master /var/opt/jenkins/runner/1.0

Le fichier téléchargé peut être supprimé.

#sudo rm /var/opt/jenkins/runner.zip


Icon File Owner.png Propriétaire fichiers

L'installation a été réalisée avec le compte root. Il est préférable de donner la propriété au compte de service, soit jenkins dans le cadre de cette installation.

#sudo chown -R jenkins:jenkins /var/opt/jenkins/runner


Icon ACL.png Sécurisation

Après avoir modifié le propriétaire des fichiers, il est conseillé de positionner des droits restrictifs afin que seul le propriétaire puisse accéder à ceux-ci.

#sudo chmod -R go-rwx /var/opt/jenkins/runner


Multiples-icon.png Gestion des versions

Le déploiement de nouvelles versions doit être le plus simple possible. Les scripts de service ne doivent pas contenir l'emplacement de l'instance, qui dans le cas de l'article contient le numéro de version, mais plutôt un lien générique qui sera modifié. Ce lien est créé sous /var/opt/jenkins/installed.

#sudo ln -s /var/opt/jenkins/runner/1.0 /var/opt/jenkins/installed
#sudo chown -h jenkins:jenkins /var/opt/jenkins/installed


Share-icon.png Fichiers communs

Afin d'éviter la reprise des fichiers de paramétrages lors des montées de versions, les répetoires sont externalisés dans un répertoire /var/opt/jenkins/commondans lequel l’arborescence standard est reproduite pour plus de clarté.

  • conf contient les fichiers de configuration;
  • data contient les données de l'application;
  • tmp contient les fichiers temporaires.

A noter que les emplacements du répertoire data et tmp peuvent être configurés dans le fichier wrapper.conf, préalablement déplacé sous /var/opt/jenkins/common/conf. Mais afin d'éviter au maximum la modification des fichiers, et car cela peut évoluer au fil des versions, l'utilisation de liens est préférée dans le cadre de cette installation.

Dans un premier temps, les répertoires sont créés sous common avec recopie des fichiers de l'instance.

#sudo mkdir -p /var/opt/jenkins/common/conf
#sudo mkdir -p /var/opt/jenkins/common/data
#sudo mkdir -p /var/opt/jenkins/common/tmp
#sudo cp -p /var/opt/jenkins/runner/1.0/conf/* /var/opt/jenkins/common/conf
#sudo chown -R jenkins:jenkins /var/opt/jenkins/common
#sudo chmod -R go-rwx /var/opt/jenkins/common

Puis les liens doivent être mis en place.

#sudo rm -rf /var/opt/jenkins/runner/1.0/conf
#sudo ln -s /var/opt/jenkins/common/conf /var/opt/jenkins/runner/1.0/conf
#sudo chown -h jenkins:jenkins /var/opt/jenkins/runner/1.0/conf
#sudo rm -rf /var/opt/jenkins/runner/1.0/data
#sudo ln -s /var/opt/jenkins/common/data /var/opt/jenkins/runner/1.0/data
#sudo chown -h jenkins:jenkins /var/opt/jenkins/runner/1.0/data
#sudo rm -rf /var/opt/jenkins/runner/1.0/tmp
#sudo ln -s /var/opt/jenkins/common/tmp /var/opt/jenkins/runner/1.0/tmp
#sudo chown -h jenkins:jenkins /var/opt/jenkins/runner/1.0/tmp

Le contenu de l'instance est alors le suivant.

#sudo ll /var/opt/jenkins/runner/1.0
total 52
drwx------  4 jenkins jenkins  4096 août  23 12:49 ./
drwxr-xr-x  4 jenkins jenkins  4096 août  23 12:44 ../
drwx------ 13 jenkins jenkins  4096 déc.   6  2013 bin/
lrwxrwxrwx  1 jenkins jenkins    28 août  23 12:48 conf -> /var/opt/jenkins/common/conf/
-rw-------  1 jenkins jenkins  7651 déc.   6  2013 COPYING
lrwxrwxrwx  1 jenkins jenkins    28 août  23 12:48 data -> /var/opt/jenkins/common/data/
-rw-------  1 jenkins jenkins 16906 déc.   6  2013 jenkins_logo.png
-rw-------  1 jenkins jenkins  3242 déc.   6  2013 jenkins_logo-small.png
drwx------  2 jenkins jenkins  4096 août  22 17:18 lib/
lrwxrwxrwx  1 jenkins jenkins    16 août  23 12:38 logs -> /var/log/jenkins/
-rw-------  1 jenkins jenkins  1791 déc.   6  2013 README.md
lrwxrwxrwx  1 jenkins jenkins    27 août  23 12:49 tmp -> /var/opt/jenkins/common/tmp/

Le contenu de la partie common est le suivant.

#sudo ll /var/opt/jenkins/common
total 20
drwx------ 5 jenkins jenkins 4096 août  23 12:44 ./
drwxr-xr-x 4 jenkins jenkins 4096 août  23 12:44 ../
drwx------ 2 jenkins jenkins 4096 août  23 12:44 conf/
drwx------ 2 jenkins jenkins 4096 août  23 12:44 data/
drwx------ 2 jenkins jenkins 4096 août  23 12:44 tmp/


Run-icon.png Permission exécution

L'utilisation du framework Java Service Wrapper nécessite un script, fichier bin/linux-x86-64/jenkins.sh dans ce cas, auquel il faut accorder les permissions d'exécution pour le compte utilisateur.

#sudo chmod 700 /var/opt/jenkins/runner/1.0/bin/linux-x86-64/jenkins.sh
#sudo chmod 700 /var/opt/jenkins/runner/1.0/bin/linux-x86-64/wrapper


Icon-log.png Fichiers log

Par défaut, les logs sont placés dans le répertoire logs de l’instance.

  • /var/opt/jenkins/runner/logs/jenkins.log

La définition se situe dans le fichier conf/wrapper.conf.

#********************************************************************
# Wrapper Logging Properties
#********************************************************************
# Format of output for the console.  (See docs for formats)
wrapper.console.format=PM

# Log Level for console output.  (See docs for log levels)
wrapper.console.loglevel=INFO

# Log file to use for wrapper output logging.
wrapper.logfile=../../logs/jenkins.log

# Format of output for the log file.  (See docs for formats)
wrapper.logfile.format=LPTM

# Log Level for log file output.  (See docs for log levels)
wrapper.logfile.loglevel=INFO

# Maximum size that the log file will be allowed to grow to before
#  the log is rolled. Size is specified in bytes.  The default value
#  of 0, disables log rolling.  May abbreviate with the 'k' (kb) or
#  'm' (mb) suffix.  For example: 10m = 10 megabytes.
#wrapper.logfile.maxsize=0

# Maximum number of rolled log files which will be allowed before old
#  files are deleted.  The default value of 0 implies no limit.
#wrapper.logfile.maxfiles=0

# Log Level for sys/event log output.  (See docs for log levels)
wrapper.syslog.loglevel=NONE


Afin de centraliser les logs, les messages sont redirigés vers /var/log/jenkins en mettant en place des liens symboliques. Ceci permet de ne pas modifier les fichiers de configurations, limitant les modifications lors des futures montées de version. Le répertoire /var/opt/jenkins/runner/logs existe déjà et sera supprimé.

#sudo mkdir -p /var/log/jenkins
#sudo chown jenkins:adm /var/log/jenkins
#sudo chmod 770 /var/log/jenkins
#sudo rm -rf /var/opt/jenkins/runner/1.0/logs
#sudo ln -s /var/log/jenkins /var/opt/jenkins/runner/1.0/logs
#sudo chown -h jenkins:jenkins /var/opt/jenkins/runner/1.0/logs


Warning-icon.png Attention, il peut être nécessaire de modifier la configuration des fichiers trace comme explicité dans l'article suivant.


Configuration App Web-Icon.png Numéro port

Par défaut, le port utilisé est 8080, ce qui peut rentrer en conflit avec des applications déjà installées, comme Tomcat, qui utilisent déjà ce port. Il est possible de configurer le port d'écoute dans le fichier wrapper.conf. Dans le cadre de cette installation, le port 8090 est utilisé.

# Application parameters.  Add parameters as needed starting from 1
wrapper.app.parameter.1=Main
#wrapper.app.parameter.2=--httpPort=8080
wrapper.app.parameter.2=--httpPort=8090


Update icon.png Montées de version Jenkins

Toutes les modifications faites ci dessus concerne l'installation de Jenkins Runner permettant de démarrer l'application Jenkins. Par défaut, le fichier WAR de Jenkins doit être placé dans le sous répertoire lib, emplacement configuré dans le fichier wrapper.conf.

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=../../lib/jenkins.war
wrapper.java.classpath.2=../../lib/*.jar

Afin de faciliter les montées de versions, une structure est mise en place dans le répertoire common pour stocker les versions disponibles ainsi que la version activée.

#sudo mkdir -p /var/opt/jenkins/common/versions
#sudo chown jenkins:jenkins /var/opt/jenkins/common/versions
#sudo chmod 700 /var/opt/jenkins/common/versions

Par exemple, pour la version 2.138, l'instance est téléchargée /var/opt/jenkins/common/versions avec le nom de fichier 2.138.war

#sudo wget -O /var/opt/jenkins/common/versions/2.138.war http://mirrors.jenkins-ci.org/war/2.138/jenkins.war
#sudo chown jenkins:jenkins /var/opt/jenkins/common/versions/2.138.war
#sudo chmod 600 /var/opt/jenkins/common/versions/2.138.war

Puis un lien est mis en place avec le nom jenkins.war

#sudo ln -s /var/opt/jenkins/common/versions/2.138.war /var/opt/jenkins/common/versions/jenkins.war
#sudo chown -h jenkins:jenkins /var/opt/jenkins/common/versions/jenkins.war

Enfin, un lien jenkins.war est mis dans le répertoire lib afin de pointer sur le lien mis dans le répertoire versions. Ainsi, lors des montées de versions, il suffira de changer le lien /var/opt/jenkins/common/versions/jenkins.war.

#sudo ln -s /var/opt/jenkins/common/versions/jenkins.war /var/opt/jenkins/installed/lib/jenkins.war
#sudo chown -h jenkins:jenkins /var/opt/jenkins/runner/lib/jenkins.war

Le principe de mise à jour est décrit dans l'article suivant.


Configuration App Web-Icon.png Publication Apache

Les précédentes versions étaient déployées sur un serveur Tomcat et mis à disposition sous Apache. Or avec cette nouvelle installation, l'instance est à présente indépendante et la configuration Apache devient la suivante.

    ProxyRequests Off
    AllowEncodedSlashes NoDecode
    ProxyPass / http://localhost:8090/ nocanon
    ProxyPassReverse / http://localhost:8090/


Start-icon.png Installation service

Run-icon.png Service init.d

Historiquement, les services Linux sont déclarés dans le répertoire /etc/init.d. Il suffit de créer le fichier /etc/init.d/jenkins pour référencer Jenkins en tant que service, avec le contenu suivant.

#!/bin/sh
#
# rc file for Jenkins
#
# chkconfig: 345 96 10
# description: Jenkins (jenkins.io)
#
### BEGIN INIT INFO
# Provides: jenkins
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: Jenkins
# Description: Jenkins (jenkins.io)
### END INIT INFO

/var/opt/jenkins/installed/bin/linux-x86-64/jenkins.sh $*

exit $?

Le fichier doit être exécutable.

#sudo chmod 755 /etc/init.d/jenkins

Le service est installé avec les paramètres par défaut.

#sudo update-rc.d jenkins defaults

L’utilisation de systemd nécessite de recharger les configurations générées.

#sudo systemctl daemon-reload

Warning-icon.png Attention, en utilisant ce principe, il faut modifier le script de démarrage afin d'indiquer le compte d'exécution. De plus, une modification est réalisée pour s'assurer que le répertoire /run/jenkins est disponible lors du démarrage. Le fichier /var/opt/jenkins/runner/bin/linux-x86-64/jenkins.sh est modifié ainsi.

# Location of the pid file.
#PIDDIR="."
PIDDIR="/run/jenkins"

# If uncommented, causes the Wrapper to be shutdown using an anchor file.
#  When launched with the 'start' command, it will also ignore all INT and
#  TERM signals.
#IGNORE_SIGNALS=true

# If specified, the Wrapper will be run as the specified user.
# IMPORTANT - Make sure that the user has the required privileges to write
#  the PID file and wrapper.log files.  Failure to be able to write the log
#  file will cause the Wrapper to exit without any way to write out an error
#  message.
# NOTE - This will set the user which is used to run the Wrapper as well as
#  the JVM and is not useful in situations where a privileged resource or
#  port needs to be allocated prior to the user being changed.
#RUN_AS_USER=
RUN_AS_USER=jenkins
if [ ! -d "$PIDDIR" ]; then
        mkdir -p "$PIDDIR"
        [ -z "$RUN_AS_USER" ] || chown "$RUN_AS_USER:$RUN_AS_USER" "$PIDDIR"
fi

Start-icon.png Service systemd

Le système init.d est progressivement remplacé par l’outil systemd qui utilise un autre système de configuration. Il suffit de créer le fichier /lib/systemd/system/jenkins.service avec le contenu suivant.

[Unit]
Description=Jenkins

[Service]
RuntimeDirectory=jenkins
Type=forking
User=jenkins
Group=jenkins
ExecStart=/var/opt/jenkins/installed/bin/linux-x86-64/jenkins.sh start
ExecStop=/var/opt/jenkins/installed/bin/linux-x86-64/jenkins.sh stop
ExecReload=/var/opt/jenkins/installed/bin/linux-x86-64/jenkins.sh restart
PIDFile=/run/jenkins/Jenkins.pid
Restart=always

[Install]
WantedBy=multi-user.target

Warning-icon.png Avec l'utilisation du Java Service Wrapper, un sous processus est démarré. Le script jenkins.sh se termine après exécution. Donc il est important de spécifier la valeur forking dans le paramètre Type. Ainsi systemd ne considérera pas que le service s'est arrêté.

Avec le type forking, il est généralement conseillé d'indiquer l'emplacement du fichier PID, qui est configuré dans la variable PIDFile. Attention, cet emplacement doit être en accord avec la configuration de PIDDIR dans le script de démarrage.

Afin d'être homogène avec une plateforme Linux, le répertoire pour le fichier PID est spécifié à /run/jenkins dans le fichier /var/opt/jenkins/runner/bin/linux-x86-64/jenkins.sh.

# Location of the pid file.
#PIDDIR="."
PIDDIR="/run/jenkins"

Contrairement à la méthode avec init.d, il n'est pas nécessaire de s'assurer de l'existance du répertoire. En effet, la valeur jenkins de la variable RuntimeDirectory, dans la configuration du service, indique à systemd de s'en assurer.

Il est nécessaire de recharger les configurations générées.

#sudo systemctl daemon-reload

Puis le service doit être activé.

#sudo systemctl enable jenkins
Created symlink /etc/systemd/system/multi-user.target.wants/jenkins.service → /lib/systemd/system/jenkins.service.


Strategy-icon.png Stratégie de Backup

La stratégie de backup est simplifiée par rapport à un déploiement sous Tomcat. Il suffit de sauvegarder le répertoire /var/opt/jenkins.

La mise en place de cette sauvegarde est explicitée ici.


Vues-icon.png Utilisation Maven

Icon ACL.png Permissions

Jenkins permet de construire, en autre, des jobs Maven. Il est possible de configurer une instance propre à Jenkins. Cependant cela entraîne de la consommation espace disque inutile sur le serveur si plusieurs applications utilisent Maven. Dans le cadre de cette installation, Maven est installé sous /var/opt/maven et le dépôt sous /usr/share/maven/repository. Les permissions du dépôt permettent au compte root et aux membres du groupe maven de modifier les fichiers.

#sudo chown -R root:maven /usr/share/maven/repository

Il est nécessaire de rajouter le compte jenkins dedans afin de pouvoir enrichir le dépôt.

#sudo usermod -a -G maven jenkins

Icon-Configuration-Settings.png Configuration

Maven fonctionne avec un fichier de configuration settings.xml qui est généralement placé dans le sous répertoire .m2 du répertoire Home de l'utilisateur. Afin de centraliser l'installation, le fichier settings.xml est mutualisé et il faut mettre en place la configuration pour Jenkins. Ceci est facilement réalisable à l'aide de lien symboliques sur un système Linux.

Dans un premier temps, le répertoire .m2 est créé sous /var/opt/jenkins/common/home.

#sudo mkdir -p /var/opt/jenkins/common/home/.m2
#sudo chown jenkins:jenkins /var/opt/jenkins/common/home/.m2
#sudo chmod 700 /var/opt/jenkins/common/home/.m2

Puis le lien vers le fichier settings.xml est créé.

#sudo ln -s /var/opt/maven/conf/settings.xml /var/opt/jenkins/common/home/.m2/settings.xml
#sudo chown -h jenkins:jenkins /var/opt/jenkins/common/home/.m2/settings.xml


Copy-icon.png Reprise instance

Dans le cas où l'installation en mode autonome est réalisée avec une installation déjà existante, il est nécessaire de déplacer et modifier les données existantes, comme décrit dans l'article suivant.

Dans le cadre de cette implémentation, les données sont déplacées depuis le répertoire /var/lib/tomcat8/.jenkins vers dans le répertoire /var/opt/jenkins/common/home. Il est également nécessaire de modifier le contenu d'un ensemble de fichier afin de référencer le nouvel emplacement. Cela met en évidence qu'il est important que cet espace de travail ne contienne aucune adhérence avec l'environnement d'exécution.

Folder-icon.png Déplacement

Dans le cadre de cette mise en place, le répertoire home est déplacé depuis le répertoire /var/lib/tomcat8/.jenkins vers /var/opt/jenkins/common/data.

#sudo cp -Rp /var/lib/tomcat8/.jenkins/* /var/opt/jenkins/common/data/

Icon File Owner.png Propriétaire fichiers

L'instance étant démarré avec le compte jenkins, il est nécessaire de mettre à jour le propriétaire des fichiers.

#sudo chown -R jenkins:jenkins /var/opt/jenkins/common/data

Update icon.png Mise à jour

Les fichiers contiennent les emplacements des fichiers, en absolu. IL faut modifier les contenus pour prendre en compte ce nouveau répertoire. Sur une machine Linux, ceci est facilement réalisable à l'aide des commandes find et sed. Pour cet exemple, toutes les valeurs /var/lib/tomcat8/.jenkins/ sont remplacées par /var/opt/jenkins/common/data pour les fichiers XML.

#sudo find /var/opt/jenkins/common/data -name '*.xml' -exec sed -i 's/\/var\/lib\/tomcat8\/.jenkins/\/var\/opt\/jenkins\/common\/data/g' {} \;	

A noter, l'utilisation du caractère \ pour échapper le caractère / dans l'expression régulière de sed.

Certificate Server icon.png Certificats CVS

La configuration CVS de Jenkins permet de spécifier l'emplacement des certificats. La précédente installation étant sur un serveur Tomcat, les répertoires se trouvaient sous /usr/share/tomcat8/.ssh.

Dans un premier temps, des répertoires externalisés sont mis en place.

#sudo mkdir -p /var/opt/jenkins/common/home/.ssh/id_rsa
#sudo mkdir -p /var/opt/jenkins/common/home/.ssh/known_hosts

Puis les potentiels fichiers sont recopiés.

#sudo cp -R /usr/share/tomcat8/.ssh/id_rsa/* /var/opt/jenkins/common/home/.ssh/id_rsa
#sudo cp -R /usr/share/tomcat8/.ssh/known_hosts/* /usr/share/tomcat8/home/.ssh/known_hosts/

Les permissions sont mises à jour afin de n'authoriser que le compte d'exécution de Jenkins, soit jenkins pour cette implémentation.

#sudo chown -R jenkins:jenkins /var/opt/jenkins/common/home/.ssh
#sudo chmod -R go-rwx /var/opt/jenkins/common/home/.ssh

Enfin, il faut modifier la configuration pour prendre en compte ce nouvel emplacement. Il est possible de le faire depuis l'interface d'administration ou en ligne de commande avec find et sed sur le contenu du fichier hudson.scm.CVSSCM.xml.

#sudo sed -i 's/\/usr\/share\/tomcat8\/.ssh\//\/var\/opt\/jenkins\/common\/home\/.ssh\//g' /var/opt/jenkins/common/data/hudson.scm.CVSSCM.xml

Network Admin.png URL accès

L'accès à l'application est modifié pour être sur un site dédié. IL est possible de modifier la configuration depuis l'interface d'administration ou en ligne de commande avec find et sed sur le contenu du fichier jenkins.model.JenkinsLocationConfiguration.xml.

#sudo sed -i 's/https:\/\/www.jenkins.jouvinio.net\/jenkins\//https:\/\/www.jenkins.jouvinio.net\//g' /var/opt/jenkins/common/data/jenkins.model.JenkinsLocationConfiguration.xml



Viewer icon.png Voir Aussi

Documentation officielle: https://github.com/mnadeem/JenkinsRunner

Procédure Jenkins: https://wiki.jenkins.io/display/JENKINS/Installing+Jenkins+as+a+Unix+daemon