Ich versuche, virtualenv
Python-Umgebungen für jeden Job auf einem Jenkins-Server programmgesteuert zu verwalten, implementiert über eineGemeinsam genutzte BibliothekErweiterung zum Aktivieren von Umgebungen auf Jobbasis. Beispiel:
/vars/activateEnvironment.groovy
:
def call(String env = "/usr/local/etc/environments/jenkins-$JOB_NAME") {
sh """
mkdir ${env}
virtualenv ${env}
source ${env}/bin/activate
"""
}
Pipeline-Skript, in dem das virtualenv-scripts
Repository die obige Datei enthält:
@Library('virtualenv-scripts') _
pipeline {
agent any
stages {
stage("Test") {
steps {
activateEnvironment()
sh 'which pip'
sh 'echo \$PATH'
}
}
}
}
Wenn ich dieses Pipeline-Skript ausführe, erhalte ich die folgende Ausgabe:
[Pipeline] sh
[example-pipeline] Running shell script
+ echo /sbin:/usr/sbin:/bin:/usr/bin
/sbin:/usr/sbin:/bin:/usr/bin
[Pipeline] sh
[example-pipeline] Running shell script
+ which pip
/bin/pip
Ich habe versucht, mitdiese Antwortum Jenkins dazu zu bringen, eine Login-Shell zu verwenden, die die Umgebung aber trotzdem bei jedem sh
Aufruf neu lädt.
Ich habe auch gesehendiese AntwortDies würde das Einfügen von zusätzlichem Text bei jeder sh
Verwendung eines Schritts in einer Pipeline erfordern – nicht ideal.
Gibt es eine gute Möglichkeit, die Umgebung zwischen Befehlen beizubehalten sh
? Oder gibt es eine bessere Möglichkeit, Umgebungen für einzelne Jobs mit zu erstellen virtualenv
? Vielen Dank für alle Hilfe/Vorschläge!
Antwort1
Ich hatte das gleiche Problem. Nach Gesprächen mit einigen erfahrenen Jenkins-Administratoren bin ich zu dieser Lösung gekommen:
def runCommandInMyEnvironment(cmd) {
sh "setup_environment_command; source ./some/file; ${cmd}"
}
pipeline {
agent any
stages {
stage("My Stage") {
steps {
runCommandInMyEnvironment('first_command')
runCommandInMyEnvironment('second_command')
// and so on
}
}
}
}
Das sieht nicht schön aus und kann die Konsolenausgabe ziemlich durcheinanderbringen, aber es ist auch die zuverlässigste Methode, das Problem zu lösen.
Ein anderer Ansatz wäre, die Ausgabe eines Befehls zu analysieren, in eine Reihe von Umgebungsvariablen aufzuteilen und diese dann an einen withEnv
Block zu übergeben. Dies kann jedoch ein sehr schwieriger und unzuverlässiger Ansatz sein.
Wie Sie angedeutet haben, unterstützt Jenkins auf jeden Fall keine dauerhaften Umgebungen ohne withEnv
, sodass es letztendlich keine wirklich gute oder saubere Möglichkeit gibt, dies zu tun.
Es gibt vielleicht eine bessere Möglichkeit, virtuelle Umgebungen mit Jenkins zu verwenden, aber ich habe noch nie einen Jenkins-Job geschrieben, der Aufgaben in einer virtuellen Umgebung ausführt, also kann ich das nicht sagen. Es gibtdieses Plugin, Abereine weitere Stackoverflow-Antwortlegt nahe, dass der Ansatz, den ich in dieser Antwort gegeben habe, die bevorzugte Methode für die Arbeit mit virtuellen Umgebungen in Jenkins ist.