Jenkinsfile和Python virtualenv

时间:2016-11-28 03:01:02

标签: python jenkins

我正在尝试设置一个使用闪亮的新Jenkins管道的项目,更具体地说是一个多分支项目。

我在测试分支中创建了一个Jenkins文件,如下所示:

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将更新pip

我收到如下错误:

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

看起来它正在尝试更新全局环境中的pip而不是内部virtualenv,并且看起来每个sh步骤都在其自己的上下文中,如何使它们在相同的上下文中执行?

3 个答案:

答案 0 :(得分:15)

你要做的事情是行不通的。每次调用sh命令时,jenkins都会创建一个新shell。

这意味着如果您在.env/bin/activate中使用sh,那么它将只是该shell会话中的来源。结果是,在新的sh命令中,您必须再次获取文件(如果仔细查看控制台输出,您将看到Jenkins实际上每次运行comman时都会创建临时shell文件。 / p>

所以你应该在每个shell命令的开头找到.env/bin/activate文件(你可以对多行​​字符串使用三个qoutes),就像这样

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

或在一个shell中运行它

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

答案 1 :(得分:4)

就像Rik发布的那样,virtualenvs在Jenkins管道环境中不能很好地工作,因为为每个命令创建了一个新的shell。

我创建了一个插件,让这个过程不那么痛苦,可以在这里找到:https://wiki.jenkins.io/display/JENKINS/Pyenv+Pipeline+Plugin。它基本上只是以一种在运行命令之前激活virtualenv的方式包装每个调用。这本身就很棘手,因为一些运行多个内联命令的方法被Jenkins分成两个单独的命令,导致激活的virtualenv不再适用。

答案 2 :(得分:-1)

我是詹金斯文件的新手。以下是我如何解决虚拟环境问题的方法。 (我正在运行Python3,Jenkins 2.73.1)

警告:为了清楚起见,我并不是说这是一个解决问题的好方法,我也没有足够的测试来支持这种方法,但今天对我有用的是:

我一直在玩绕过venv'激活'通过直接调用虚拟环境的python解释器。所以而不是:

source ~/venv/bin/activate    

可以使用:

~/venv/bin/python3 my_script.py

我通过shell的rc文件(在我的情况下,~/.bashrc)将路径传递给我的虚拟环境python解释器。理论上,Jenkins调用的每个shell都应该读取此资源文件。实际上,我必须在更改shell资源文件后重新启动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环境值。

注意这种方法的一个缺点是,现在Jenkins文件不包含正确运行脚本的所有必要信息。希望这会让你开始。