web-dev-qa-db-ja.com

virtualenvを使用したJenkinsのジョブごとの環境

virtualenvを使用して、Jenkinsサーバー上の各ジョブのPython環境をプログラムで管理しようとしています。環境をアクティブ化するために 共有ライブラリ 拡張機能を介して実装されていますジョブごとに。例:

/vars/activateEnvironment.groovy

def call(String env = "/usr/local/etc/environments/jenkins-$JOB_NAME") {

    sh """
    mkdir ${env}
    virtualenv ${env}
    source ${env}/bin/activate
    """
}

パイプラインスクリプト。virtualenv-scriptsリポジトリには上記のファイルが含まれています。

@Library('virtualenv-scripts') _

pipeline {
    agent any
    stages {
        stage("Test") {
            steps {
                activateEnvironment()
                sh 'which pip'
                sh 'echo \$PATH'
            }
        }
    }
}

このパイプラインスクリプトを実行すると、次の出力が得られます。

[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

この回答 を使用してJenkinsにログインシェルを使用させようとしましたが、それでもsh呼び出しごとに環境がリロードされます。

また、パイプラインでshステップが使用されるたびに追加のテキストを貼り付ける必要がある この答え も見ました-理想的ではありません。

shコマンド間で環境を持続させる良い方法はありますか?あるいは、virtualenvを使用してジョブごとの環境を実現するためのより良い方法はありますか?すべてのヘルプ/提案をありがとう!

2
cwh

同じ問題がありました。ベテランのJenkins管理者と話した後、これが私が到達した解決策です。

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
      }
    }
  }
}

それはきれいではなく、コンソール出力をかなり濁らせる可能性がありますが、これを行うための最も信頼できる方法でもあります。

別のアプローチは、コマンドの出力を解析し、それを環境変数の束に切り刻んでから、それらをwithEnvブロックに渡すことですが、これは非常にトリッキーで信頼性の低いアプローチになる可能性があります。

いずれにせよ、先ほど触れたように、JenkinsはwithEnvのない永続化環境をサポートしていないため、最終的にそれを実行するための本当の方法またはクリーンな方法はありません。

Jenkinsでvirtualenvsを使用するより良い方法があるかもしれませんが、virtualenvでタスクを実行するJenkinsジョブを作成したことがないので、言えません。 このプラグイン がありますが、 別のスタックオーバーフローの回答 は、この回答で私が与えたアプローチが、Jenkinsでvirtualenvを操作するための推奨される方法であることを示唆しています。

3
jayhendren