【发布时间】:2017-12-05 20:39:56
【问题描述】:
目标
在同一节点上运行声明式 Jenkins 管道的多个阶段。
设置
这只是显示问题的一个最小示例。有 2 个 Windows 节点“windows-slave1”和“windows-slave2”都标有“windows”标签。
注意:我真正的 Jenkinsfile 不能使用全局代理,因为有一组阶段需要在不同的节点上运行(例如 Windows 与 Linux)。
预期行为
Jenkins 根据标签选择“Stage 1”中的节点之一,并在“Stage 2”中使用相同的节点,因为变量 windowsNode 已更新为“Stage 1”中选择的节点。
实际行为
“Stage 2”有时在与“Stage 1”相同的节点上运行,有时在不同的节点上运行。请参阅下面的输出。
Jenkinsfile
#!groovy
windowsNode = 'windows'
pipeline {
agent none
stages {
stage('Stage 1') {
agent {
label windowsNode
}
steps {
script {
// all subsequent steps should be run on the same windows node
windowsNode = NODE_NAME
}
echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
}
}
stage('Stage 2') {
agent {
label windowsNode
}
steps {
echo "windowsNode: $windowsNode, NODE_NAME: $NODE_NAME"
}
}
}
}
输出
[Pipeline] stage
[Pipeline] { (Stage 1)
[Pipeline] node
Running on windows-slave2 in C:\Jenkins\workspace\test-agent-allocation@2
[Pipeline] {
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] echo
windowsNode: windows-slave2, NODE_NAME: windows-slave2
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Stage 2)
[Pipeline] node
Running on windows-slave1 in C:\Jenkins\workspace\test-agent-allocation
[Pipeline] {
[Pipeline] echo
windowsNode: windows-slave2, NODE_NAME: windows-slave1
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
Finished: SUCCESS
您知道设置有什么问题吗?我猜这就是 Jenkinsfile 的解析和执行方式。
其他建议?最初设置 windowsNode 时,可能有一个 Jenkins API 可以根据“windows”标签选择一个节点。
【问题讨论】:
-
您的第 2 阶段没有拾取重命名的变量。如果您将
windowsNode = 'windows'更改为windowsNode = 'asdf',那么您应该会看到“没有带有标签‘asdf’的节点”错误,这意味着您的第2 阶段仍在运行label 'windows'而不是label 'windows-slave2'。 -
但是,我尝试了
stage("Stage 2" ) { environment { someVariable = "$windowsNode" } agent { label env.someVariable } ..,尽管它分配了一个节点并且没有给出“缺少属性”错误(这意味着agent至少知道 someVariable 存在),但它不起作用。如果我打印env.someVariable的值,它是节点名称,所以虽然它可以看到正确的windowsNode变量,但我怀疑someVariable在agent指令中处于某种空白状态,导致它运行类似agent label ''而不是agent label 'windows-slave2'。 -
我也尝试了
environment { someVariable = "\'$windowsNode\'" },它使变量'windows-slave2'而不仅仅是windows-slave2,但它仍然在我的两个测试节点之间随机分配(尽管变量或标签名称仍然没有错误) .