Я пытаюсь использовать virtualenv
для программного управления средами Python для каждой задачи на сервере Jenkins, реализованном черезОбщая библиотекарасширение для активации сред на основе задания. Например:
/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
? Спасибо за всю помощь/предложения!
решение1
У меня была та же проблема. Поговорив с некоторыми опытными администраторами 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
, так что в конечном итоге не существует действительно хорошего или чистого способа сделать это.
Возможно, есть лучший способ использовать virtualenv с Jenkins, но я никогда не писал задания Jenkins, которые запускают задачи в virtualenv, поэтому я не могу сказать. Естьэтот плагин, ноеще один ответ stackoverflowпредполагает, что подход, который я привел в этом ответе, является предпочтительным методом работы с virtualenv в Jenkins.