(ошибка) конвейер jenkins, вызовите sh в цикле + сериализация json - PullRequest
2 голосов
/ 24 октября 2019

Я не понимаю, почему возникает ошибка:

stage('name') {
    steps {
        script {
            def jsonObj = new JsonSlurper().parseText( env.work_servers )
            for(item in jsonObj){
                cmd("my command --param1=${item.srv} --param2=${item.port}")
            }
        }
    }
}

получение ошибки, стек ошибок https://pastebin.com/V09ZXrif

, даже если вы замените вызов метода cmd на shничего не меняется

Если вы вызываете команды без цикла, все работает

stage('name') {
    steps {
        script {
            def srv = "..."
            def port = "..."
            cmd("my command --param1=${srv} --param2=${port}")

            srv = "..."
            port = "..."
            cmd("my command --param1=${srv} --param2=${port}")
        }
    }
}

это также работает

stage('name') {
    steps {
        script {
            def jsonObj = new JsonSlurper().parseText( env.work_servers )
            for(item in jsonObj){
                echo item 
            }
        }
    }
}
def cmd(command) {
    result = ""
    if (isUnix()) {
        result = sh(
            script: command,
            returnStdout: true
        ).trim()
    } else {
        bat "chcp 65001\n${command}"
    }
    return result
}

1 Ответ

1 голос
/ 24 октября 2019

Вы видите эту проблему, потому что new JsonSlurper().parseText(text) возвращает карту типа groovy.json.internal.LazyMap, которая не сериализуема. Любой код, который вы запускаете внутри этапов, должен работать с сериализуемыми объектами. (Исключение может применяться к извлеченным методам, помеченным @NonCPS.)

Решение этой проблемы простое - замените JsonSlurper на JsonSlurperClassic, который возвращает HashMap изparseText(text) method.

stage('name') {
    steps {
        script {
            def jsonObj = new JsonSlurperClassic().parseText( env.work_servers )
            for(item in jsonObj){
                cmd("my command --param1=${item.srv} --param2=${item.port}")
            }
        }
    }
}

В качестве альтернативы, если вам нужно остаться с JsonSlurper, вы можете извлечь часть, которая анализирует JSON и выполняет любые операции с JSON-объектом, в отдельный метод и аннотировать его@NonCPS. Вы можете рассмотреть этот альтернативный вариант, если ваш JSON огромен и использование LazyMap имеет некоторый смысл. В противном случае переключение на JsonSlurperClassic - лучший способ решить вашу проблему.

...