web-dev-qa-db-fra.com

Manière propre de lancer un script Shell en arrière-plan à partir de Jenkins

Quelle est la bonne façon de lancer un script à partir de Jenkins, de ne pas suspendre la construction et de laisser le processus en cours? Je n'arrive pas à le faire fonctionner. Soit le script ne s'exécute pas, soit la build se bloque.

Si je mets à l'étape "Execute Shell" de la génération bash relaunch.sh & ou relaunch.sh > output.log & ou Nohup bash relaunch.sh &, Rien ne se passe; la construction se termine, mais le processus ne s'exécute pas. Je suppose que cela peut être lié au fait que Jenkins attend le canal d'erreur à fermer .

Si je fais Nohup bash relaunch.sh 2>&1 > output.log comme suggéré ici , la sortie est correctement redirigée, mais la build se bloque (ne se termine pas), et le processus meurt lorsque je tue la build.

Ajouter export BUILD_ID=dontKillMe, comme suggéré ici , ici et ici , soit à l'étape "Exécuter le shell", soit le script lui-même n'aide pas non plus . La build se bloque et le processus meurt lorsque je tue la build. Inutile de dire que ma connaissance de Linux est très limitée.

Comment les gens font-ils cela d'une manière propre?

21
garci560

Un moyen pratique d'y parvenir consiste à modifier la variable d'environnement BUILD_ID sous Exécuter Shell qui Jenkins'sProcessTreeKiller recherche.

En faisant,

BUILD_ID=dontKillMe Nohup bash relaunch.sh &

Jenkins supposera que le travail d'arrière-plan n'est pas généré par la génération et ne les tuera pas après avoir terminé le travail.

Merci à Joshua pour son observation que vous pouvez également utiliser JENKINS_NODE_COOKIE as

JENKINS_NODE_COOKIE=dontKillMe
26
Inian

J'avais exactement le même problème. J'ai fini par corriger cela en plaçant ce qui suit dans la boîte Jenkins execute Shell:

BUILD_ID=dontKillMe ./grid.sh

J'ai déplacé le & à l'intérieur du fichier de script. Voici à quoi ressemble le script:

#!/bin/bash
Java -jar Selenium-server-standalone-3.0.1.jar -role hub &

Espérons que cela aide quelqu'un!

9
user2671131

Solutions intéressantes. Quelqu'un at-il essayé l'écran?

Voici comment je l'exécute (pour la simulation RTL à l'aide de ModelSim-ASE):

screen -S $testname -d -m -L bash -c 'cd build_sim ; make; make sim'
echo Waiting for simulator ...

J'attends ensuite que notre simulateur se mette en attente en regardant le journal de l'écran.

until ((`fgrep -c 'Ready for simulation' screenlog.0`)) ;do
    sleep 1
done

Ensuite, lorsque les autres travaux nécessitant la simulation sont exécutés (ou que Jenkins détecte une défaillance), dans la publication, exécutez:

screen -S $testname -X kill

La seule mise en garde est que si Jenkins meurt d'une manière ou d'une autre avant que le travail ne se nettoie, en théorie, vous pourriez avoir un simulateur mâchant des ressources en attendant que quelque chose se produise.

Pour le décomposer un peu: avec l'écran, "-S" attribue un titre à la session (ou adresse une session en cours d'exécution avec ce titre), "-d" s'exécute séparément, "-m" génère d'abord une fourche (qui se cache de Jenkins surveille les yeux), et -L active la journalisation (ce qui est également pratique au cas où quelque chose se casserait dans le simulateur - vous avez maintenant un artefact de fichier journal avec la sortie). Le reste est simplement bash à l'intérieur de la session d'écran.

1
GrueMaster