プレーン文字列としてではなく、エージェントラベルを動的に設定する方法はありますか?
ジョブには2つの段階があります。
私の(動作していない)試みは次のようになります。
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」が出力されます。 2番目のステージは、「my_node_label」というラベルのエージェントでの実行に失敗し、コンソールに次のメッセージが表示されます。
「null」というラベルのノードはありません
多分それが役立つかもしれません-ラベルフィールドに「$ {env}」を入れると、これはJavaクラスであることがわかります:
「org.jenkinsci.plugins.workflow.cps.EnvActionImpl@79c0ce06」というラベルのノードはありません
これがどのように機能するかを確認するには、GString
オブジェクトを使用してprintln
を実行し、agentNameの変数を同時に返します。出力から、この行が他のパイプラインコードよりもかなり前に評価されることがわかります。
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
が出力の非常に早い段階で表示されることに注意してください。これはなぜあなたの値がnullであるかを説明しています。そのステートメントは、スクリプトが変数を変更するずっと前に評価されます。
遅延変数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ノードが適切に検出され、パイプラインが終了したことがわかります。 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
これはおそらく、怠zyなGString
とタイプ強制なしで機能しますが、私はそれを試しませんでした。
スクリプトと宣言型のパイプラインを組み合わせてください。まず、スクリプト構文を使用して、たとえば自分がいるブランチを見つけました。次に、AGENT_LABEL変数を定義します。この変数は、宣言パイプラインに沿ってどこでも使用できます
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"
}
}
}
}
スクリプトブロックのコンテキストに関する何かかもしれません。
これは、第2段階で「docker」のラベルを使用して機能します。
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}"
}
}
}
}
これは同じではありません(ラベル「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}"
}
}
}
}
これは私のために働いた:
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