jenkinsfile, загрузка и область видимости переменных - PullRequest
0 голосов

В прошлую пятницу я получил ошибку при попытке использовать load в конвейере Jenkinsfile и не могу понять, почему это не работает.

В моей настройке есть мастер Дженкинс и несколько рабов. У меня есть внешний скрипт Groovy, который обрабатывает файлы JSON в зависимости от некоторых условий. Изучая документацию, вы должны загрузить Groovy-сценарий в мастер-файл перед отправкой задания агенту.

Обновлен должный запрос

Я предоставляю более реалистичный тест здесь. Я проверил это на одном локальном сервере Jenkins, версия 2.107.2.

Код для загрузки:

class Foobar {
    private name = 'foobar'
    private now

    Foobar() {
        this.now = new Date()
    }

    String say() {
        "My name is $name and I was created at $now"    
    }

}

def build_foobar() {
    new Foobar()
}

return this

Трубопровод:

def foobar

node() {
    foobar = load '/tmp/foobar.groovy'
    println "After load: $foobar"
}

node() {
    stage('checkout') {
        println 'checkout from scm'
    }
    stage('build') {
        println "at build: $foobar"
        testing()
    }
}

def testing() {
    println "at testing: $foobar"
    def foo = foobar.build_foobar()
    println foobar.say()
}

Когда я пытаюсь его выполнить, foobar генерирует исключение привязки, как если бы я не объявил конвейер раньше, даже если я применил return this к концу 'foobar.groovy':

[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: foobar for class: groovy.lang.Binding
    at groovy.lang.Binding.getVariable(Binding.java:63)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:242)
    at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:288)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
    at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
    at WorkflowScript.testing(WorkflowScript:22)
    at WorkflowScript.run(WorkflowScript:16)

Чтобы выполнить некоторую отладку, я включил println поверх кода и смог получить Script1@XXXXX, что означает, что код был прочитан, проанализирован и скомпилирован, как и ожидалось. Если я передаю foobar в качестве параметра testing(), это работает, как и ожидалось:

[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/teste
[Pipeline] {
[Pipeline] load
[Pipeline] { (/tmp/foobar.groovy)
[Pipeline] }
[Pipeline] // load
[Pipeline] echo
Script1@150cc39b
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/teste
[Pipeline] {
[Pipeline] stage
[Pipeline] { (checkout scm)
[Pipeline] echo
checkout
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (build)
[Pipeline] echo
at build: Script1@150cc39b
[Pipeline] echo
at testing: Script1@150cc39b
[Pipeline] echo
My name is foobar and I was created at Mon May 07 09:15:15 BRT 2018
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Теперь это другое поведение, когда у меня есть главный и подчиненный узлы. Единственный способ запустить этот код в подчиненном устройстве (после load от ведущего устройства) - забыть о foobar() и выполнить методы конвейера внутри подчиненного узла, все работает как положено. Конечно, это нежелательно, поскольку я просто копирую и вставляю код, а не использую его повторно.

Что мне там не хватает?

...