![Ambientes por trabalho no Jenkins com virtualenv](https://rvso.com/image/717773/Ambientes%20por%20trabalho%20no%20Jenkins%20com%20virtualenv.png)
Estou tentando usar virtualenv
para gerenciar programaticamente ambientes Python para cada trabalho em um servidor Jenkins, implementado por meio de umBiblioteca Compartilhadaextensão para ativar ambientes por trabalho. Por exemplo:
/vars/activateEnvironment.groovy
:
def call(String env = "/usr/local/etc/environments/jenkins-$JOB_NAME") {
sh """
mkdir ${env}
virtualenv ${env}
source ${env}/bin/activate
"""
}
Script de pipeline, no qual o virtualenv-scripts
repositório contém o arquivo acima:
@Library('virtualenv-scripts') _
pipeline {
agent any
stages {
stage("Test") {
steps {
activateEnvironment()
sh 'which pip'
sh 'echo \$PATH'
}
}
}
}
Executando este script de pipeline, obtenho a seguinte saída:
[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
Eu tentei usaresta respostapara fazer o Jenkins usar um shell de login, mas que ainda recarrega o ambiente a cada sh
chamada.
eu também viesta respostao que exigiria a colagem de texto extra sempre que uma sh
etapa fosse usada em um pipeline - o que não é o ideal.
Existe uma boa maneira de manter o ambiente entre sh
os comandos? Como alternativa, existe uma maneira melhor de obter ambientes por trabalho com virtualenv
? Obrigado por toda ajuda/sugestões!
Responder1
Eu tive o mesmo problema. Depois de conversar com alguns administradores veteranos do Jenkins, esta é a solução que cheguei:
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
}
}
}
}
Não é bonito e pode atrapalhar um pouco a saída do console, mas também é a maneira mais confiável de fazer isso.
Outra abordagem seria analisar a saída de algum comando e dividi-la em um monte de variáveis de ambiente e depois passá-las para um withEnv
bloco, mas esta pode ser uma abordagem muito complicada e não confiável.
De qualquer forma, como você mencionou, o Jenkins não oferece suporte a ambientes persistentes sem withEnv
, então, em última análise, não há uma maneira realmente boa ou limpa de fazer isso.
Pode haver uma maneira melhor de usar virtualenvs com Jenkins, mas nunca escrevi um trabalho do Jenkins que execute tarefas em um virtualenv, então não posso dizer. Háeste plug-in, masoutra resposta stackoverflowsugere que a abordagem que dei nesta resposta é o método preferido para trabalhar com virtualenvs no Jenkins.