web-dev-qa-db-fra.com

Charger le fichier avec les variables d'environnement Jenkins Pipeline

Je fais un pipeline simple:

Construire -> Mise en scène -> Production

J'ai besoin de différentes variables d'environnement pour la mise en scène et la production, donc j'essaie de source variables.

sh 'source $JENKINS_HOME/.envvars/stacktest-staging.sh' 

Mais ça retourne Introuvable

[Stack Test] Running Shell script
+ source /var/jenkins_home/.envvars/stacktest-staging.sh
/var/jenkins_home/workspace/Stack Test@tmp/durable-bcbe1515/script.sh: 2: /var/jenkins_home/workspace/Stack Test@tmp/durable-bcbe1515/script.sh: source: not found

Le chemin est correct, parce que je lance la même commande lorsque je me connecte via ssh, et cela fonctionne bien.

Voici l’idée du pipeline:

node {
    stage name: 'Build'
    // git and gradle build OK
    echo 'My build stage'

    stage name: 'Staging'
    sh 'source $JENKINS_HOME/.envvars/stacktest-staging.sh' // PROBLEM HERE
    echo '$DB_URL' // Expects http://production_url/my_db
    sh 'gradle flywayMigrate' // To staging
    input message: "Does Staging server look good?"    

    stage name: 'Production'
    sh 'source $JENKINS_HOME/.envvars/stacktest-production.sh'
    echo '$DB_URL' // Expects http://production_url/my_db
    sh 'gradle flywayMigrate' // To production
    sh './deploy.sh'
}

Que devrais-je faire?

  • Je pensais ne pas utiliser de pipeline (mais je ne pourrai pas utiliser mon Jenkinsfile).
  • Ou faites différents travaux pour la mise en scène et la production, en utilisant EnvInject Plugin (Mais je perds ma vue de la scène)
  • Ou make withEnv (mais le code devient gros, parce qu'aujourd'hui je travaille avec 12 env vars)
15
Rafael

Pour charger des variables d'environnement à partir d'un fichier, vous pouvez notamment charger un fichier Groovy.

Par exemple:

  1. Supposons que vous avez un fichier groovy dans '$ JENKINS_HOME/.envvars' appelé 'stacktest-staging.groovy'.
  2. Dans ce fichier, vous définissez 2 variables d’environnement que vous souhaitez charger. 

    env.DB_URL="hello"
    env.DB_URL2="hello2"
    
  3. Vous pouvez ensuite charger cela en utilisant

    load "$JENKINS_HOME/.envvars/stacktest-staging.groovy"
    
  4. Ensuite, vous pouvez les utiliser dans les étapes suivantes echo/Shell.

Par exemple, voici un court script de pipeline:

node {
   load "$JENKINS_HOME/.envvars/stacktest-staging.groovy"
   echo "${env.DB_URL}"
   echo "${env.DB_URL2}"
}
25
Daniel Omoto

Des commentaires aux réponse acceptée

N'utilisez pas la méthode globale 'env' mais la construction 'withEnv', par exemple, consultez: Numéro 9: ne définissez pas les variables env avec la valeur globale env dans les 10 meilleures pratiques du plugin jenkins pipeline

Dans l'exemple suivant: VAR1 est une chaîne Java simple (pas d'expansion de variable groovy), VAR2 est une chaîne groovy (la variable 'someGroovyVar' est développée).

Le script transmis est une chaîne Java simple. Ainsi, $ VAR1 et $ VAR2 sont transmis littéralement au shell, et l'écho accède aux variables d'environnement VAR1 et VAR2.

stage('build') {
    def someGroovyVar = 'Hello world'
    withEnv(['VAR1=VALUE ONE',
             "VAR2=${someGroovyVar}"
            ]) {
        def result = sh(script: 'echo $VAR1; echo $VAR2', returnStdout: true)
        echo result
    }
}

Pour les secrets/mots de passe, vous pouvez utiliser plugin de liaison des informations d'identification

Exemple:

REMARQUE: CREDENTIALS_ID1 est un secret de nom d'utilisateur/mot de passe enregistré dans les paramètres Jenkins.

stage('Push') {
    withCredentials([usernamePassword(
                         credentialsId: 'CREDENTIALS_ID1',
                         passwordVariable: 'PASSWORD',
                         usernameVariable: 'USER')]) {
        echo "User name: $USER"
        echo "Password:  $PASSWORD"
    }
}

La sortie du journal de la console jenkisn cache les valeurs réelles:

[Pipeline] echo
User name: ****
[Pipeline] echo
Password:  ****

Jenkins et les informations d'identification est un gros problème, voir probablement: plugin accréditations

Pour être complet: la plupart du temps, nous avons besoin des secrets dans les variables d'environnement, car nous les utilisons à partir de scripts Shell. Nous combinons donc les éléments withCredentials et withEnv comme suit:

stage('Push') {
    withCredentials([usernamePassword(
                         credentialsId: 'CREDENTIALS_ID1',
                         passwordVariable: 'PASSWORD',
                         usernameVariable: 'USER')]) {
        withEnv(["ENV_USERNAME=${USER}",
                 "ENV_PASSWORD=${PASSWORD}"
            ]) {
                def result = sh(script: 'echo $ENV_USERNAME', returnStdout: true)
                echo result

        }
    }
}
14

Un autre moyen de résoudre cette installation du plug-in 'Pipeline Utility Steps' qui nous fournit la méthode readProperties (pour référence, veuillez consulter le lien https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#pipeline- utility-steps ) Ici, dans l'exemple, nous pouvons voir qu'ils stockent les clés dans un tableau et utilisent les clés pour récupérer la valeur. Mais dans ce cas, le problème en production sera comme si nous ajoutions une variable ultérieurement dans le fichier de propriétés, cette variable devait également être ajoutée dans le tableau du fichier Jenkins . Pour supprimer ce couplage étroit, nous pouvons écrire du code de manière à ce que l'environnement de génération Jenkins puisse obtenir automatiquement des informations sur toutes les clés existantes présentes dans le fichier Property. Voici un exemple pour la référence 

def loadEnvironmentVariables(path){
    def props = readProperties  file: path
    keys= props.keySet()
    for(key in keys) {
        value = props["${key}"]
        env."${key}" = "${value}"
    }
} 

Et le code client ressemble à 

path = '\\ABS_Output\\EnvVars\\pic_env_vars.properties'
loadEnvironmentVariables(path)
1
Sumanta Mondal

Si vous utilisez Jenkins 2.0, vous pouvez charger le fichier de propriétés (qui contient toutes les variables d’environnement requises ainsi que leurs valeurs correspondantes), lire automatiquement toutes les variables d’environnement répertoriées et les insérer dans l’entité env fournie par Jenkins.

Voici une méthode qui effectue l'action indiquée ci-dessus.

def loadProperties(path) {
    properties = new Properties()
    File propertiesFile = new File(path)
    properties.load(propertiesFile.newDataInputStream())
    Set<Object> keys = properties.keySet();
    for(Object k:keys){
    String key = (String)k;
    String value =(String) properties.getProperty(key)
    env."${key}" = "${value}"
    }
}

Pour appeler cette méthode, nous devons passer le chemin du fichier de propriétés sous forme de variable chaîne. Par exemple, dans notre fichier Jenkins utilisant un script groovy, vous pouvez appeler comme

path = "${workspace}/pic_env_vars.properties"
loadProperties(path)

S'il vous plaît demandez-moi si vous avez un doute

0
Sumanta Mondal