Existe-t-il un moyen de définir le libellé de l'agent de manière dynamique et non comme une chaîne?
Le travail comporte 2 étapes:
Ma tentative (qui ne fonctionne pas) ressemble à ceci:
pipeline {
agent { label 'master' }
stages {
stage('Stage1') {
steps {
script {
env.node_name = "my_node_label"
}
echo "node_name: ${env.node_name}"
}
}
stage('Stage2') {
agent { label "${env.node_name}" }
steps {
echo "node_name: ${env.node_name}"
}
}
}
}
Le premier écho fonctionne correctement et "my_node_label" est imprimé . La deuxième étape ne peut pas s'exécuter sur un agent nommé "my_node_label" et la console affiche:
Il n’existe pas de nœuds portant l’étiquette ‘null’
Peut-être que cela peut aider - si je viens de mettre "$ {env}" dans le champ de l'étiquette, je peux voir qu'il s'agit d'une classe Java telle qu'elle est imprimée:
Il n’existe pas de nœuds portant l’étiquette «org.jenkinsci.plugins.workflow.cps.EnvActionImpl@79c0ce06».
Pour voir comment cela fonctionne, utilisez un objet GString
pour créer une println
et renvoyer la variable correspondant au nom de l'agent en même temps. Vous voyez sur la sortie que cette ligne est évaluée bien avant tout autre code de pipeline.
agentName = "Windows"
agentLabel = "${println 'Right Now the Agent Name is ' + agentName; return agentName}"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
agentName = "Linux"
}
}
}
stage('Checking') {
steps {
script {
println agentLabel
println agentName
}
}
}
stage('Final') {
agent { label agentLabel }
steps {
script {
println agentLabel
println agentName
}
}
}
}
}
Sortie de la console (notez que je n'ai pas de noeud sur cette instance nommée Windows, alors j'ai abandonné après l'avoir trouvée):
Started by user Admin
[Pipeline] echo
Right Now the Agent Name is Windows
[Pipeline] stage
[Pipeline] { (Prep)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Checking)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Windows
[Pipeline] echo
Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Final)
[Pipeline] node
Still waiting to schedule task
There are no nodes with the label ‘Windows’
Aborted by Admin
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
ERROR: Queue task was cancelled
Finished: ABORTED
Notez que la ligne Right Now the Agent Name is Windows
apparaît très tôt dans la sortie. Cela explique pourquoi votre valeur est nulle. Cette instruction est évaluée bien avant que votre script modifie la variable.
Je pourrais essayer d'utiliser une variable GString
paresseuse pour obtenir la variable plus tard.
agentLabel = "${-> println 'Right Now the Agent Name is ' + agentName; return agentName}"
Malheureusement, cela génère une erreur car il attend un type de chaîne. Apparemment, il peut contraindre le GString non paresseux à une chaîne tout seul, mais pas à la version paresseuse. Ainsi, lorsque je force la contrainte sur une chaîne, bien sûr, il évalue la variable à ce moment-là (c'est-à-dire avant que le code de pipeline ne soit réellement exécuté).
agent { label agentLabel as String }
Vous pouvez résoudre le problème en retenant l'ancienne méthode d'allocation de nœud:
agentName = "Windows"
agentLabel = "${-> println 'Right Now the Agent Name is ' + agentName; return agentName}"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
agentName = "Linux"
}
}
}
stage('Checking') {
steps {
script {
println agentLabel
println agentName
}
}
}
stage('Final') {
steps {
node( agentLabel as String ) { // Evaluate the node label later
echo "TEST"
}
script {
println agentLabel
println agentName
}
}
}
}
}
Vous pouvez voir à partir de cette sortie de console qu'elle trouve maintenant correctement le nœud Linux et termine le pipeline. La première évaluation alors que agentName == Windows ne se produit jamais:
Started by user Admin
[Pipeline] stage
[Pipeline] { (Prep)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Checking)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Right Now the Agent Name is Linux
[Pipeline] echo
Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Final)
[Pipeline] echo
Right Now the Agent Name is Linux
[Pipeline] node
Running on Slave 1 in /home/jenkinsslave/jenkins/workspace/test
[Pipeline] {
[Pipeline] echo
TEST
[Pipeline] }
[Pipeline] // node
[Pipeline] script
[Pipeline] {
[Pipeline] echo
Right Now the Agent Name is Linux
[Pipeline] echo
Linux
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS
Cela fonctionnerait probablement sans la variable paresseuse GString
et le type de contrainte plus tard, mais je n'ai pas essayé cela.
Voici comment je l'ai fait: mélange de pipeline scripté et déclaratif. J'ai d'abord utilisé la syntaxe scriptée pour trouver, par exemple, la branche sur laquelle je suis. Définissez ensuite la variable AGENT_LABEL. Cette variable peut être utilisée n'importe où sur le pipeline déclaratif
def AGENT_LABEL = null
node('master') {
stage('Checkout and set agent'){
checkout scm
### Or just use any other approach to figure out agent label: read file, etc
if (env.BRANCH_NAME == 'master') {
AGENT_LABEL = "prod"
} else {
AGENT_LABEL = "dev"
}
}
}
pipeline {
agent {
label "${AGENT_LABEL}"
}
stages {
stage('Normal build') {
steps {
echo "Running in ${AGENT_LABEL}"
sh "hostname"
}
}
stage ("Docker build") {
agent{
dockerfile {
dir 'Dockerfiles'
label "${AGENT_LABEL}"
}
}
steps{
sh "hostname"
}
}
}
}
cela pourrait être quelque chose à propos du contexte du bloc de script.
cela fonctionne, en utilisant une étiquette de 'docker' dans la deuxième étape:
def hotLabel = 'docker'
pipeline {
agent { label 'master' }
stages {
stage('Stage1') {
steps {
echo "node_name: ${hotLabel}"
}
}
stage('Stage2') {
agent { label "${hotLabel}" }
steps {
echo "node_name: ${hotLabel}"
}
}
}
}
cela n’est pas le cas (il en va de même. Il n’existe pas de nœuds portant l’erreur «null»)
def hotLabel = null
pipeline {
agent { label 'master' }
stages {
stage('Stage1') {
steps {
script {
hotLabel = "docker"
}
}
}
stage('Stage2') {
agent { label "${hotLabel}" }
steps {
echo "node_name: ${hotLabel}"
}
}
}
}
Cela a fonctionné pour moi:
env.agentName = ""
branch_name = "10.1.0"
pipeline {
agent none
stages {
stage('Prep') {
steps {
script {
println branch_name
if ("${branch_name}" == "9.2.0") {
env.agentName = "9.2agent"
} else {
env.agentName = "10.1agent"
}
}
}
}
stage('Finish') {
steps {
node (agentName as String) { println env.agentName }
script {
println agentName
}
}
}
}
}
Output:
SuccessConsole Output
Started by user build
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] stage
[Pipeline] { (Prep)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
10.1.0
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Finish)
[Pipeline] node
Running on 10.1agent in /home/build/jenkins/workspace/testlabel
[Pipeline] {
[Pipeline] echo
rbreg6
[Pipeline] }
[Pipeline] // node
[Pipeline] script
[Pipeline] {
[Pipeline] echo
rbreg6
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS
Changing the branch name to 9.2.0:
Started by user build
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] stage
[Pipeline] { (Prep)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
9.2.0
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Finish)
[Pipeline] node
Running on 9.2agent in /shared/build/workspace/testlabel
[Pipeline] {
[Pipeline] echo
rbregistry
[Pipeline] }
[Pipeline] // node
[Pipeline] script
[Pipeline] {
[Pipeline] echo
rbregistry
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS