Pro-Job-Umgebungen in Jenkins mit virtualenv

Pro-Job-Umgebungen in Jenkins mit virtualenv

Ich versuche, virtualenvPython-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-scriptsRepository 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 shAufruf neu lädt.

Ich habe auch gesehendiese AntwortDies würde das Einfügen von zusätzlichem Text bei jeder shVerwendung 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 withEnvBlock 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.

verwandte Informationen