有没有一种方法可以动态设置代理标签而不是设置为纯字符串?
该工作分为两个阶段:
我的(无效)尝试如下所示:
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}" } } } }
第一个回声可以正常工作,并打印“ my_node_label”。第二阶段无法在标有“ my_node_label”的代理上运行,控制台将输出:
没有标签为“ null”的节点
也许会有所帮助-如果我只是在标签字段中输入“ $ {env}”,则可以看到这是一个Java类,它可以打印:
没有标签为’org.jenkinsci.plugins.workflow.cps.EnvActionImpl@79c0ce06’的节点
要查看其工作原理,请使用GString对象执行a println并同时返回agentName的变量。您可以从输出中看到,该行在任何其他管道代码之前的评估效果都很好。
GString
println
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 } } } } }
控制台输出(请注意,在此实例上我实际上没有节点标记为Windows,因此在找不到该节点后中止了操作):
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
请注意,该行在Right Now the Agent Name is Windows输出中很早就出现了。这说明了为什么您的值为空。在您的脚本修改变量之前很久就对该语句进行了评估。
Right Now the Agent Name is Windows
我可能稍后会尝试使用惰性GString来获取变量。
agentLabel = "${-> println 'Right Now the Agent Name is ' + agentName; return agentName}"
不幸的是,这会引发错误,因为它期望使用String类型。显然,它可以自行将非惰性GString强制转换为String,而不是强制性版本。因此,当我强制强制使用String时,它会在那时(也就是在管道代码实际运行之前)对变量进行求值。
agent { label agentLabel as String }
您可以通过使用旧的节点分配方法来解决此问题:
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 } } } } }
您可以从此控制台输出中看到,它现在可以正确找到Linux节点并完成管道。Windows永远不会发生agentName == Windows的早期评估:
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
如果没有延迟GString和类型强制,这可能会起作用,但是我没有尝试过。