Среды для отдельных заданий в Jenkins с virtualenv

Среды для отдельных заданий в Jenkins с virtualenv

Я пытаюсь использовать 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.

Связанный контент