2016-11-28 11 views
11

光沢のある新しいJenkinsパイプライン、より具体的にはマルチブランチプロジェクトを使用するプロジェクトをセットアップしようとしています。JenkinsfileとPython virtualenv

私はJenkinsfileは、以下のようにテストブランチに作成した:

node { 
    stage 'Preparing VirtualEnv' 
    if (!fileExists('.env')){ 
     echo 'Creating virtualenv ...' 
     sh 'virtualenv --no-site-packages .env' 
    } 
    sh '. .env/bin/activate' 
    sh 'ls -all' 
    if (fileExists('requirements/preinstall.txt')){ 
     sh 'pip install -r requirements/preinstall.txt' 
    } 
    sh 'pip install -r requirements/test.txt' 
    stage 'Unittests' 
    sh './manage.py test --noinput' 
} 

をそれは私が以下のようにエラーを取得していますpreinstall.txtはピップ

を更新することは注目に値します:

OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/pip' 

それは内部のvirtualenvの代わりにグローバルなenvでピップを更新しようとしているように見え、それぞれshのステップが独自のコンテキストにあるように見えますが、どうすればそれらをウィット同じ文脈では?

+0

'activate'は、実行されているシェルインスタンスにのみ適用されます。 venvで 'pip'をフルパスで実行し、' manage.py'で(フルパス) 'python'を実行してみてください。 –

答えて

5

何をしようとしても動作しません。 shコマンドを呼び出すたびに、jenkinsは新しいシェルを作成します。

これは、をshに使用すると、そのシェルセッションのソースのみになります。その結果、新しいshコマンドでファイルを再度ソースする必要があります(コンソール出力を詳しく見ると、実際にJenkinsがコマンドを実行するたびに一時的なシェルファイルを作成することがわかります)

Soあなたはとても

if (fileExists('requirements/preinstall.txt')) { 
    sh """ 
    . .env/bin/activate 
    pip install -r requirements/preinstall.txt 
    """ 
} 
... 
sh """ 
. .env/bin/activate 
pip install -r requirements/test.txt 
""" 
} 
stage("Unittests") { 
    sh """ 
    . .env/bin/activate 
    ./manage.py test --noinput 
    """ 
} 

のように、各シェルコマンド(あなたが複数行の文字列のトリプルqoutesを使用することができます)の先頭に.env/bin/activateファイルをソースまたは1つのシェルでそれをすべて実行する必要がありますいずれか

sh """ 
. .env/bin/activate 
if [[ -f requirements/preinstall.txt ]]; then 
    pip install -r requirements/preinstall.txt 
fi 
pip install -r requirements/test.txt 
./manage.py test --noinput 
""" 
+4

悲しいことに、この回避策は、パイプラインのメンテナンスを悪夢にさせるため、パイプラインDSLを拡張して、このユースケースを可能にし、これで終わるのを避ける必要があります。この回避策は単純なパイプラインでは機能しますが、複雑なものに成長すると、アクティベーションは悪夢になります。 virtualenvの作成が失敗した場合に実行される例外やブロックについて考えることができます。 – sorin

+0

残念ながら私は@sorinに同意する必要があります。それはますます良くなっていますが、しばしば休憩や回避策が必要です。その一方で、誰もが自分の時間を費やすために余裕を持って貢献するかもしれない。この問題に関しては、トゥーはいつもロジックを使ってレポにスクリプトを入れて、 – Rik

1

リクe Rikが投稿したvirtualenvsは、コマンドごとに新しいシェルが作成されるため、Jenkins Pipeline Environmentではうまく機能しません。

このプロセスを少し難しくするプラグインを作成しました。このプラグインは、ここではhttps://wiki.jenkins.io/display/JENKINS/Pyenv+Pipeline+Pluginです。基本的には、コマンドを実行する前にvirtualenvをアクティブにする方法で各呼び出しをラップします。複数のコマンドをインラインで実行するいくつかの方法は、Jenkinsによって2つの別々のコマンドに分割され、アクティブ化されたvirtualenvはもはや適用されなくなるため、これ自体は難しいです。

0

私はJenkinsファイルを初めて使用しています。ここで私が仮想環境の問題を取り組んできた方法を紹介します。 (私はPython3、Jenkins 2.73.1を実行しています)

警告:これは問題を解決する良い方法ではないと私はこのアプローチの背後に立つためにこれを十分にテストしているわけではありません、ここで私にとって今日働いているもの:

私は、仮想環境のPythonインタプリタを直接呼び出してvenv 'activate'をバイパスして遊んでいました。だから、代わりに:

source ~/venv/bin/activate  

1を使用することができます。

~/venv/bin/python3 my_script.py 

私はシェルのrcファイルを経由して、私の仮想環境Pythonインタプリタへのパスを渡す理論的には、すべてのシェルを(私の場合は、~/.bashrc。) Jenkinsの呼び出しでは、このリソースファイルを読み込む必要があります。実際には、シェルリソースファイルを変更した後でJenkinsを再起動する必要があります。

HOME_DIR=~ 
export VENV_PATH="$HOME_DIR/venvs/my_venv" 
export PYTHON_INTERPRETER="${VENV_PATH}/bin/python3" 

私Jenkinsfileは、次のようになります。

pipeline { 
    agent { 
     label 'my_slave' 
    } 

    stages { 
     stage('Stage1') { 
      steps { 
       // sh 'echo $PYTHON_INTERPRETER' 
       // sh 'env | sort' 
       sh "$PYTHON_INTERPRETER my_script.py " 
      } 
     } 
    } 
} 

パイプラインが実行されたときに、SHがセット$ PYTHON_INTERPRETER環境値を持っています。

このアプローチの1つの欠点は、Jenkinsファイルに、スクリプトを正しく実行するために必要なすべての情報が含まれていないことです。うまくいけば、これはあなたを地面から離れさせます。

関連する問題