web-dev-qa-db-fra.com

Comment attendre une entrée utilisateur dans un pipeline déclaratif sans bloquer un exécuteur poids lourd

Je reconstruis un pipeline de construction existant en tant que pipeline déclaratif jenkins (pipeline à branches multiples) et je rencontre un problème de gestion de la propagation de la génération.

Après avoir empaqueté et stocké tous les fichiers pertinents, le pipeline est censé attendre que l’entrée de l’utilisateur déclenche le déploiement.

Si je viens d'ajouter une étape d'entrée, le noeud de construction actuel est bloqué. Comme cet exécuteur est assez lourd, j'aimerais passer à une machine plus légère. 

Initialement, je faisais ce travail en tant que pipeline et je venais de créer deux blocs node('label') différents. Existe-t-il un moyen pour moi de faire quelque chose de similaire avec la syntaxe déclarative?

node('spine') { 
    stage('builder') {
        sh 'mvn clean compile'
        stash name: 'artifact', includes: 'target/*.war'
    }
}
node('lightweight') {
    stage('wait') {
        timeout(time:5, unit:'DAYS') {
            input message:'Approve deployment?'
        }
    }
    // add deployment stages
}

J'ai déjà essayé plusieurs choses:

la configuration de l'agent au niveau supérieur et l'ajout d'une configuration d'agent supplémentaire à l'étape de propagation, mais j'ai alors deux exécutants bloquants car le noeud de génération défini au niveau supérieur n'est pas arrêté.

Paramétrez agent none au niveau supérieur et configurez les agents par étape. alors le git checkout n'est pas présent sur le premier noeud.

EDIT 1

j'ai reconfiguré mon pipeline en suivant vos conseils, il se présente comme suit:

pipeline {
agent none
tools {
    maven 'M3'
}
stages {
    stage('Build') {
        agent { label 'spine' }
        steps {
            checkout scm // needed, otherwise the workspace on the first step is empty
            sh "mvn clean compile"
        }
    }
    stage('Test') {
        agent { label 'spine' }
        steps {
            sh "mvn verify" // fails because the workspace is empty aggain
            junit '**/target/surefire-reports/TEST-*.xml'
        }
    }
}
}

cette génération échouera car l'espace de travail ne sera pas reporté entre les étapes car elles ne s'exécutent pas sur le même exécuteur.

EDIT 2

apparemment, parfois, les étapes se déroulent sur le même exécuteur et parfois non. (Nous produisons des esclaves de construction sur notre cluster mesos/dcos à la demande, donc changer le build intermédiaire de l'exécuteur serait un problème)

Je m'attendais à ce que jenkins s'exécute simplement avec l'exécuteur actuel tant que le libellé de la définition de l'agent ne change pas.

14
Laures

Voir Meilleure pratique 7 : Ne pas utiliser: utilisez une entrée dans un bloc de nœuds. Dans un pipeline déclaratif, la sélection de nœud est effectuée via la directive agent.

La documentation ici décrit comment vous pouvez définir none pour la hiérarchie, puis utiliser une directive agent au niveau de l'étape pour exécuter les étapes sur les nœuds requis. J'ai aussi essayé le contraire (définir un agent global sur un nœud, puis none au niveau de la scène pour l'entrée), mais cela ne fonctionne pas. Si le pipeline a affecté un esclave, vous ne pouvez pas le libérer pour une ou plusieurs étapes spécifiques.

Voici la structure de notre pipeline :

pipeline {
  agent none
  stages {
    stage('Build') {
      agent { label 'yona' }
      steps {
        ...
      }
    }
    stage('Decide tag on Docker Hub') {
      agent none
      steps {
        script {
          env.TAG_ON_DOCKER_HUB = input message: 'User input required',
              parameters: [choice(name: 'Tag on Docker Hub', choices: 'no\nyes', description: 'Choose "yes" if you want to deploy this build')]
        }
      }
    }
    stage('Tag on Docker Hub') {
      agent { label 'yona' }
      when {
        environment name: 'TAG_ON_DOCKER_HUB', value: 'yes'
      }
      steps {
        ...
      }
    }
  }
}

Généralement, les étapes de construction s'exécutent sur un esclave appelé "yona", mais l'étape d'entrée s'exécute sur le maître.

25
Bert

utilisez l'agent none en haut et définissez l'agent pour chaque étape, à l'exception de l'étape incluant l'étape d'entrée.

source: discussion dans Utiliser un exécuteur léger pour une étape de pipeline déclarative (agent none)

Mise à jour: qu'entendez-vous par "le git checkout n'est pas présent sur le premier noeud"? s'il vous plaît montrer ce que vous avez jusqu'à présent pour le pipeline déclaratif.

1
Roman Pickl

Une autre façon de le faire consiste à utiliser la directive expression et beforeAgent, qui ignorent l'étape "décider" et évitent de jouer avec le "env" global:

pipeline {
    agent none

    stages {
        stage('Tag on Docker Hub') {
            when {
                expression {
                    input message: 'Tag on Docker Hub?'
                    // if input is Aborted, the whole build will fail, otherwise
                    // we must return true to continue
                    return true
                }
                beforeAgent true
            }

            agent { label 'yona' }

            steps {
                ...
            }
        }
    }
}
1
emerino