Ambientes por trabalho em Jenkins com virtualenv

2

Estou tentando usar virtualenv para gerenciar programaticamente os ambientes Python de cada trabalho em um servidor Jenkins, implementado por meio de um Biblioteca compartilhada 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 repositório virtualenv-scripts contém o arquivo acima:

@Library('virtualenv-scripts') _

pipeline {
    agent any
    stages {
        stage("Test") {
            steps {
                activateEnvironment()
                sh 'which pip'
                sh 'echo \$PATH'
            }
        }
    }
}

Ao executar este script de pipeline, recebo 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 usar esta resposta para fazer o Jenkins usar um shell de login, mas isso ainda recarrega o ambiente com cada sh de chamadas.

Eu também vi esta resposta que exigiria colar texto extra toda vez que uma etapa sh fosse usada em um Pipeline - não ideal.

Existe uma boa maneira de manter o ambiente entre os comandos sh ? Como alternativa, existe uma maneira melhor de atingir ambientes por trabalho com virtualenv ? Obrigado por toda ajuda / sugestões!

    
por cwh 16.02.2018 / 23:45

1 resposta

3

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 bastante 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-lo em várias variáveis de ambiente e, em seguida, passá-las para um bloco withEnv , mas isso pode ser uma abordagem muito complicada e não confiável.

De qualquer forma, como você aludiu, o Jenkins não suporta ambientes persistentes sem withEnv , então, afinal, não há uma maneira boa ou limpa de fazê-lo.

Pode haver uma maneira melhor de usar o virtualenvs com o Jenkins, mas eu nunca escrevi um trabalho do Jenkins que executa tarefas em um virtualenv, então não posso dizer. Existe este plugin , mas outra resposta do stackoverflow sugere que a abordagem que eu dei nesta resposta é o método preferido para trabalhar com o virtualenvs no Jenkins.

    
por 19.02.2018 / 19:35