如何在Jenkins中创建Python虚拟环境?

zfciruhq  于 2023-01-25  发布在  Jenkins
关注(0)|答案(7)|浏览(467)

我使用Makefile来提供一致的单个命令,用于设置virtualenv、运行测试等。我已将Jenkins示例配置为从Mercurial repo中提取,然后运行"make virtualenv",它执行以下操作:

virtualenv --python=/usr/bin/python2.7 --no-site-packages . && . ./bin/activate && pip install -r requirements.txt

但由于某种原因,它坚持使用系统安装的pip,并试图在系统站点中安装我的包依赖项packages而不是virtualenv:

error: could not create '/usr/local/lib/python2.7/dist-packages/flask': Permission denied

如果我添加一些调试命令并显式地指向virtualenv中的pip,事情会变得更加混乱:

virtualenv --python=/usr/bin/python2.7 --no-site-packages . && . ./bin/activate && ls -l bin && which pip && pwd && ./bin/pip install -r requirements.txt

它生成以下输出:

New python executable in ./bin/python2.7
Not overwriting existing python script ./bin/python (you must use ./bin/python2.7)
Installing setuptools, pip...done.
Running virtualenv with interpreter /usr/bin/python2.7

看来Jenkins并没有为每次构建从头开始重建环境,这让我觉得是一个奇怪的选择,但应该不会影响我的紧迫问题
"ls-l bin"的输出显示pip将安装在virtualenv中并可执行:

-rw-r--r-- 1 jenkins jenkins    2248 Apr  9 21:14 activate
-rw-r--r-- 1 jenkins jenkins    1304 Apr  9 21:14 activate.csh
-rw-r--r-- 1 jenkins jenkins    2517 Apr  9 21:14 activate.fish
-rw-r--r-- 1 jenkins jenkins    1129 Apr  9 21:14 activate_this.py
-rwxr-xr-x 1 jenkins jenkins     278 Apr  9 21:14 easy_install
-rwxr-xr-x 1 jenkins jenkins     278 Apr  9 21:14 easy_install-2.7
-rwxr-xr-x 1 jenkins jenkins     250 Apr  9 21:14 pip
-rwxr-xr-x 1 jenkins jenkins     250 Apr  9 21:14 pip2
-rwxr-xr-x 1 jenkins jenkins     250 Apr  9 21:14 pip2.7
lrwxrwxrwx 1 jenkins jenkins       9 Apr 10 19:31 python -> python2.7
lrwxrwxrwx 1 jenkins jenkins       9 Apr 10 19:31 python2 -> python2.7
-rwxr-xr-x 1 jenkins jenkins 3349512 Apr 10 19:31 python2.7

"which pip"的输出似乎想要使用正确的一个:

/var/lib/jenkins/jobs/Run Tests/workspace/bin/pip

我的当前工作目录是我所期望的:

/var/lib/jenkins/jobs/Run Tests/workspace

但是... wtf?

/bin/sh: 1: ./bin/pip: Permission denied
make: *** [virtualenv] Error 126
Build step 'Execute shell' marked build as failure
Finished: FAILURE
ahy6op9u

ahy6op9u1#

在过去的两年里,我每天都在使用python virtualenvs with Jenkins,在多家公司和一些小的附带项目中使用,我不能说我找到了“正确”的答案。尽管如此,我希望分享我的经验能帮助其他人保存时间。希望我能得到进一步的反馈,以便更容易地做出决定。

*避免使用ShiningPanda--它维护得不好,与Jenkins 2管道不兼容,并且妨碍了作业的并行执行。另外,它还有一个坏习惯,就是在磁盘上留下孤立的环境。
*DIY via bash and virtualenv是我目前的最爱。在$WORKSPACE中创建它,如果不总是清理,在激活它们之前运行relocatable。这是因为jenkins工作区文件夹磁盘位置可以在作业N和N+1的执行之间更改。

如果您使用多个构建器,而这些构建器确实需要相同的virtualenv,那么最简单的方法是将您的环境转储到一个文件中,并在新构建器开始时获取它。
为了方便维护,我计划调查以下内容:

  • 迪伦姆
  • 虚拟环境 Package 器(mkvirtualenv)
  • 别夫

如果你碰到了shebang命令行的限制,最好的办法就是把jenkins的主目录改成/j

dauxcl2d

dauxcl2d2#

Jenkins管道可以在虚拟环境中运行,但需要考虑多个因素。

  • Jenkins使用的默认shell是/bin/sh-这可以在管理Jenkins -〉配置系统-〉Shell -〉Shell可执行文件中配置。将其设置为/bin/bash将使source工作。
  • 一个激活的venv只会改变环境变量,而环境变量在jenkins的不同阶段之间不会持续存在。
  • 如果你使用的是版本控制的多分支管道,jenkins创建一个工作空间,在路径中包含分支名称和提交哈希值--这可能会很长。venv脚本(例如pip)都以一个hashbang行开始,其中包含venv中python解释器的完整路径(python解释器本身是一个符号链接)。
~/workspace/ink_feature-use-jenkinsfile-VGRPYD53GGGDDSBIJDLSUDYPJ34QR63ITGMC5VJNB56W6ID244AA/env/bin$ cat pip
#!/var/jenkins_home/workspace/ink_feature-use-jenkinsfile-VGRPYD53GGGDDSBIJDLSUDYPJ34QR63ITGMC5VJNB56W6ID244AA/env/bin/python3.5

Bash只读取任何可执行文件的前N个字符-我发现这并不完全包括完整的venv路径:

bash: ./pip: /var/jenkins_home/workspace/ink_feature-use-jenkinsfile-VGRPYD53GGGDDSBIJDLSU: bad interpreter: No such file or directory

这个问题可以通过使用Python执行脚本来避免。例如python3.5 ./pip

fiei3ece

fiei3ece3#

我建议你不要去ShiningPanda。
我用Anaconda/Miniconda设置了我的虚拟环境,当安装conda时,确保你是以jenkins用户的身份运行的。

your_user@$ sudo -u jenkins sh
jenkins@$ wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
jenkins@$ bash Miniconda3-latest-Linux-x86_64.sh

由于Jenkins运行的是sh而不是bash,因此我向/etc/profile添加了conda路径:

export PATH="/var/lib/jenkins/miniconda3/bin:$PATH"

然后在Jenkinsfile中你可以创建和删除conda环境。下面是一个为每个构建创建一个新环境的例子:

pipeline {
    agent any
    stages {
        stage('Unit tests') {
            steps {
            sh '''
                conda create --yes -n ${BUILD_TAG} python
                source activate ${BUILD_TAG}
                // example of unit test with nose2
                pip install nose2
                nose2
            '''
            }
        }
    }
    post {
        always {
            sh 'conda remove --yes -n ${BUILD_TAG} --all'
        }
    }
}
c3frrgcw

c3frrgcw4#

我也有同样的问题。正如我所看到的-你的项目命名为'运行测试'。所以,这个名称包含空格。这是我的问题。我刚刚重命名项目,如运行测试-和venv工作现在!注意-Jenkins问你有关确认重命名项目。

41zrol4v

41zrol4v5#

在不同的操作系统环境下,venv-python插件存在一些问题。
下面是我手动调用python方法的方法。虽然不是最佳实践,但它确实有效。

// Put this stage on top of pipeline
stage('Prepare venv') {
    steps {
        script {
            if (isUnix()) {
                env.ISUNIX = "TRUE" // cache isUnix() function to prevent blueocean show too many duplicate step (Checks if running on a Unix-like node) in python function below
                sh 'python3 -m venv pyenv'
                PYTHON_PATH =  sh(script: 'echo ${WORKSPACE}/pyenv/bin/', returnStdout: true).trim()                        
            }
            else {
                env.ISUNIX = "FALSE"
                powershell(script:"py -3 -m venv pyenv") // windows not allow call python3.exe with venv. https://github.com/msys2/MINGW-packages/issues/5001
                PYTHON_PATH =  sh(script: 'echo ${WORKSPACE}/pyenv/Scripts/', returnStdout: true).trim()
            }

            try  {
                // Sometime agent with older pip version can cause error due to non compatible plugin.
                Python("-m pip install --upgrade pip")
            } 
            catch (ignore) { } // update pip always return false when already lastest version
            // After this you can call Python() anywhere from pipeline
            Python("-m pip install -r requirements.txt")
        }                
    }
}

// Several plugins like WithPyenv is not working perfectly accross platform when using Virtual Env.
// Put this method outside pipeline
def Python(String command) {
    if (env.ISUNIX == "TRUE") {
        sh script:"source ${WORKSPACE}/pyenv/bin/activate && python ${command}", label: "python ${command}"
    }
    else {
        powershell script:"${WORKSPACE}\\pyenv\\Scripts\\Activate.ps1 ; python ${command}", label: "python ${command}"
    }
}
jaxagkaj

jaxagkaj6#

激活virtualenv后,尝试将pip作为模块运行:

python -m pip install ...

一月一日对一月一日

  • python -m pip:执行python解释器二进制文件,从站点包目录读取模块pip.py
  • pip:执行从$PATH获取的pip二进制文件/脚本

我发现使用python -m pip解决了遇到的大多数pip权限问题。

zaq34kh6

zaq34kh67#

@硬字节的回答

  • Jenkins使用的默认shell是/bin/sh-这可以在管理Jenkins-〉配置系统-〉shell-〉shell可执行文件中配置。将其设置为/bin/bash将使源代码正常工作。*

加:

让我工作

sudo apt install python3.10-venv

然后在jenkins的execute shell步骤中:

python3.10 -m venv .venv
source .venv/bin/activate
...

相关问题