jenkins自动加载node label

最近由于编译资源有限,希望动态设置jenkins agent的label,所以一直在尝试变量修改这种形式

需求

希望有一个节点变量(通过我的分配中心获取),这个变量能够让我的剩下的stage使用这个节点

before pipeline

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!groovy
import jenkins.model.Jenkins
pipeline {
    agent {
            label 'xxx'
    }
    stages {
        stage ('test') {
            steps {
                script {
                    echo "test"
                }
            }
       }
    }
}

思路

思路1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!groovy
import jenkins.model.Jenkins
//add node param
node = 'yyy'
pipeline {
    agent {
            label node
    }
    stages {
        stage ('test') {
            steps {
                script {
                    echo "test"
                }
            }
       }
    }
}

报错:

1
2
3
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.String.call() is applicable for argument types: (java.lang.String, org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [yyy, org.jenkinsci.plugins.workflow.cps.CpsClosure2@288eb82f]
Possible solutions: wait(), any(), trim(), find(), grep(), split()
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)

怀疑是不是写错了,继续写

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!groovy
import jenkins.model.Jenkins
//add node param
node = 'yyy'
pipeline {
    agent {
            label "$node"
    }
    stages {
        stage ('test') {
            steps {
                script {
                    echo "test"
                }
            }
       }
    }
}

报错:

1
2
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.String.call() is applicable for argument types: (java.lang.String, org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [yyy, org.jenkinsci.plugins.workflow.cps.CpsClosure2@62def0a5]
Possible solutions: wait(), any(), trim(), find(), grep(), split()

尝试通过环境变量修改NODE_LABEL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!groovy
import jenkins.model.Jenkins
//add node param

pipeline {
    agent {
            label "$node"
    }
    stages {
        stage ('test') {
            steps {
                script {
                    env.NODE_LABEL="yyy"
                    echo "test"
                }
            }
       }
    }
}

报错:

1
2
3
4
groovy.lang.MissingPropertyException: No such property: node for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:264)
at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:289)

尝试把agent写到stage里面

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!groovy
import jenkins.model.Jenkins
//add node param
node = 'yyy'
pipeline {
    agent none
    stages {
        agent {
            label node
        }
        stage ('test') {
            steps {
                script {
                    echo "test"
                }
            }
       }
    }
}

报错:

1
2
3
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 8: Expected a stage @ line 8, column 9.
           agent {}

把它放到stage里面试试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!groovy
import jenkins.model.Jenkins
//add node param
node = 'yyy'
pipeline {
    agent none
    stages {
        stage ('test') {
            agent {
                 label node
             }
            steps {
                script {
                    echo "test"
                }
            }
       }
    }
}

依然报错,目测还是label不识别

1
2
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.String.call() is applicable for argument types: (java.lang.String, org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [yyy, org.jenkinsci.plugins.workflow.cps.CpsClosure2@4b281d16]
Possible solutions: wait(), any(), trim(), find(), grep(), split()

加个def试试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!groovy
import jenkins.model.Jenkins
//add node param
def node = 'yyy'
pipeline {
    agent none
    stages {
        stage ('test') {
            agent {
                 label node
             }
            steps {
                script {
                    echo "test"
                }
            }
       }
    }
}

可以了!其实后来发现agent放到前面也是可以的,只是要加def

总结如下

在pipeline外面使用变量需要加def,在非script块中引用直接用变量名即可