jenkins use groovy jsonslurper lazmap to map

jenkins pipeline use map value

背景

最近计划升级下之前的分配器逻辑,之前的是遍历node表找出当前环境绑定的node是否在用(db里面标记),通过groovy的postman去获取,现在要调整成从一个池里面去找可用并记录

调整pipeline

原来的逻辑

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def getABNode() {
    def ab_node_url ="xxx";
    def postmanGet = new URL(ab_node_url);
    def getConnection = postmanGet.openConnection();
    getConnection.requestMethod = 'GET';
    getConnection.setRequestProperty('Accept', 'application/json');

    def apply_result = new JsonSlurper().parseText(getConnection.inputStream.text);
    if(apply_result['status']==200) {
        println(apply_result['message'])
        println(apply_result)
        println(apply_result['data'])
        get_node = 'true'
    } else {
       print(apply_result)
       get_node = 'false'
       return ''
    }
}

返回的就是当前环境绑定的节点是否在使用,我在pipeline里面写了个while循环

1
2
3
4
5
6
timeout('1') {
    while (getABNode()==''){
        println('10s refreshed, all nodes are used, you can check in http://xxx')
        sleep(10)
    }
}

要更新的逻辑其实不多,但是我希望能够返回的字典是一个动态的node,上一篇文章说到了node怎么取出来 这里我希望用返回的字典标记node的 disk ip label等信息

有一个简单的实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def getABNode() {
    def ab_node_url ="xxx";
    def postmanGet = new URL(ab_node_url);
    def getConnection = postmanGet.openConnection();
    getConnection.requestMethod = 'GET';
    getConnection.setRequestProperty('Accept', 'application/json');

    def apply_result = new JsonSlurper().parseText(getConnection.inputStream.text);
    if(apply_result['status']==200) {
        build_node = apply_result['build_node']
        build_node_disk = apply_result['build_node']['disk']
        build_node_ip = apply_result['build_node']['ip']
        get_node = 'true'
    } else {
       print(apply_result)
       get_node = 'false'
       return ''
    }
}

pipeline {
...
script {
    println("$build_node_disk")
}
}

这样是可以实现的,但是我想 在script里面引用这个build_node, 报错:

1
2
3
4
5
6
7
an exception which occurred:
in field groovy.lang.Closure.delegate
in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@4f0db171
in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@38a42b90
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@38a42b90
Caused: java.io.NotSerializableException: groovy.json.internal.LazyMap

发现尝试读取一个lazymap! stackoverflow得到如下答案大家都可以试试 https://stackoverflow.com/questions/37864542/jenkins-pipeline-notserializableexception-groovy-json-internal-lazymap 这些都是因为json parse的结果是一个lazy map需要to hash的 我突然想到,我可以在函数里面再声明一个map,这是我的代码,比较丑陋,也应该可以foreach循环的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def getABNode() {
    def ab_node_url ="http://xxx"
    def postmanGet = new URL(ab_node_url);
    def getConnection = postmanGet.openConnection();
    getConnection.requestMethod = 'GET';
    getConnection.setRequestProperty('Accept', 'application/json');

    def apply_result = new JsonSlurper().parseText(getConnection.inputStream.text);
    //def apply_result = jsonParse(getConnection.inputStream.text)
    println("apply result status is " +apply_result.getClass())
    if(apply_result['status']==200) {
    // 重写slave
        slave = apply_result['data']['build_node']['node_label']
        build_node = ["node_label": apply_result['data']['build_node']["node_label"], "ip": apply_result['data']['build_node']["ip"], "disk":apply_result['data']['build_node']["disk"]]
        rsync_ab_node = ["node_label": apply_result['data']['rsync_ab_node']["node_label"], "ip": apply_result['data']['rsync_ab_node']["ip"], "disk":apply_result['data']['rsync_ab_node']["disk"]]
        build_node_disk = build_node['disk']
        get_node = 'true'
    } else {
       print(apply_result)
       get_node = 'false'
       return ''
    }
}

这样发现就可以引用了哈哈! 引用的方式如下

1
2
3
script {
 echo "${build_node.disk}"
}

其实不用$也可以的,如下

1
 echo build_node.disk

还有一个需要补充说明的,在jenkins pipeline中会使用到NonCPS和administrator approve的一些东西, 关于NonCPS, 大家可以看看这个stackoverflow https://stackoverflow.com/questions/42295921/what-is-the-effect-of-noncps-in-a-jenkins-pipeline-script 等后面有空再说下,晚安~