У меня есть фрагмент кода для перечисления всех файлов в каталоге /tmp
на двух узлах, например (синтаксис сценария):
stage('Demo') {
node('node1') {
println new File('/tmp/').listFiles().toList()
}
node('node2') {
println new File('/tmp/').listFiles().toList()
}
}
Однако результаты для обоих узлов идентичны. Похоже, что код выполняется на мастере, только функция println выполняется на двух узлах.
Вопрос в том, правда ли это? и если да, то как мне узнать, выполняется ли код на главном или подчиненном устройстве?
@mkobit: Согласно этим двум ссылкам, разве блоки кода внутри node
не должны выполняться на агентах?
любой из шагов Jenkins, использующих контекст node
, будет выполняться на этих агентах. Например, sh 'ls -1 /tmp/
'будет запускать команду ls -1 /tmp/
на этом агенте. Но фактический метод Groovy sh
и код JVM выполняются на мастере Jenkins. Весь Groovy внутри конвейера Jenkins выполняется на мастере. Следовательно, new File('/tmp')
выполняется на мастере, а не на агенте. Надеюсь, это не добавит путаницы.
@mkobit: Пожалуйста, сделайте свой комментарий ответом, чтобы я мог отметить этот вопрос как решенный. Если можно, расскажите подробнее, как узнать, требуется ли для шага контекст Дженкинса.
Контекст конвейера DSL работает на главном узле, даже если вы пишете node('someAgentName')
в конвейере. new File
будет работать только на мастере.
Но вы можете читать данные из файла через ш (). Что-то вроде:
def list = sh(returnStdout: true, script: 'ls').trim()
Все шаги Jenkins, использующие контекст node
, будут выполняться на этих агентах (из блоков node
). Например, sh 'ls -1 /tmp/'
запустит ls -1 /tmp/ command
на том агенте, который находится в блоке. Но фактический метод Groovy sh
и код JVM выполняются на мастере Jenkins.
Весь Groovy внутри конвейера Jenkins выполняется на ведущем устройстве особым образом, преобразованным в исходный код из Плагин Pipeline Groovy. Следовательно, почему new File('/tmp')
выполняется на мастере, а не на агенте. Если бы вы запускали свой конвейер с использованием изолированной программной среды безопасности, вы бы получили исключение безопасности, потому что new File
по умолчанию запрещен. Фактически, любые обычные методы стиля JVM запрещены. Например, не было бы ужасно, если бы конвейер мог вызвать System.exit(0)
и закрыть Jenkins для всех пользователей?
Похожие вопросы:
Конвейерный код исполняется на
master
. Я написал пару ответов, которые касаются этого (например, здесь и здесь).