Сценарии конвейера CI Jenkins не могут использовать метод groovy.lang.GroovyObject

105

Я использую Jenkins 2 для компиляции проектов Java, я хочу прочитать версию из pom.xml, я следовал этому примеру:

https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md

Пример предлагает:

Полный конвейер Jenkins с проблемной функцией обведен кружком

Кажется, что существует некоторая проблема с безопасностью доступа к файловой системе, но я не могу понять, что это дает (или почему) эту проблему:

Я просто делаю немного иначе, чем в примере:

def version() {
    String path = pwd();
    def matcher = readFile("${path}/pom.xml") =~ '<version>(.+)</version>'
    return matcher ? matcher[0][1] : null
}

Ошибка, которую я получаю при запуске метода версии:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (org.codehaus.groovy.runtime.GStringImpl call org.codehaus.groovy.runtime.GStringImpl)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:165)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:117)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:103)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:15)
    at WorkflowScript.run(WorkflowScript:71)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:55)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:100)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)

Я использую эти версии: Plugin Pipeline 2.1 Jenkins 2.2

Даниэль Эрнандес
источник
У меня была похожая ошибка Scripts not permitted to use method, но это произошло потому, что я написал scm 'checkout'вместо checkou scm. На всякий случай, если кто-то попадется, следите за синтаксисом :). Выполнение того, что сказал Маартен Кифт, позволило мне увидеть более четкое сообщение об ошибке о неправильной команде :)
ГабЛеРу,

Ответы:

263

Быстрая починка

У меня была аналогичная проблема, и я решил ее, выполнив следующие действия

  1. Перейдите к jenkins> Управление jenkins> Утверждение сценария в процессе
  2. Была отложенная команда, которую я должен был утвердить.

Ссылка в процессе утверждения в Jenkins 2.61 Альтернатива 1: отключить песочницу

Как подробно объясняется в этой статье , скрипты Groovy по умолчанию запускаются в режиме песочницы. Это означает, что подмножество Groovy-методов может выполняться без одобрения администратора. Также можно запускать сценарии не в режиме песочницы, что означает, что весь сценарий должен быть одобрен администратором сразу. Это мешает пользователям одновременно утверждать каждую строку.

Запуск сценариев без песочницы можно выполнить, сняв этот флажок в конфигурации проекта чуть ниже сценария: введите описание изображения здесь

Альтернатива 2: отключить безопасность сценариев

Как объясняется в этой статье, также можно полностью отключить безопасность сценариев. Сначала установите разрешающий плагин безопасности сценария, а после этого измените файл jenkins.xml и добавьте этот аргумент:

-Dpermissive-script-security.enabled = true

Итак, jenkins.xml будет выглядеть примерно так:

<executable>..bin\java</executable>
<arguments>-Dpermissive-script-security.enabled=true -Xrs -Xmx4096m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=80 --webroot="%BASE%\war"</arguments>

Убедитесь, что вы знаете, что делаете, если реализуете это!

Маартен Кифт
источник
1
Если одобрение всего сценария лучше, это зависит от структуры команды. Для нескольких разработчиков с полным доступом это очень приятно. Но установка с несколькими командами заставит администраторов одобрять каждое изменение во всех сценариях конвейера.
Роджер Леманн
3
Альтернатива 3 (действительно должна быть первым предложением) - изменить проблемный код, не внесенный в белый список . В этом случае, простое использование @NonCPSдля Matcherиспользования будет достаточно. В этом случае нет необходимости отключать безопасность для всего конвейера, и особенно для всей установки Jenkins. Оцените каждый заблокированный вызов индивидуально и решите, действительно ли вам нужно их одобрять.
mkobit
1
@mkobit у меня не работает. @NonCPSне помогает.
warvariuc
@warvariuc хм, это может быть, если вы возвращаете Matcherсебя, потому Matcherчто не реализует Serializableинтерфейс. Возможно, стоит задать новый вопрос. Я хочу, чтобы документация, указанная в исходном вопросе, была сохранена и не была неправильной с самого начала.
mkobit
2
@mkobit Я украсил NonCPS функцией, которая использует currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). Из того, что я читал, NonCPS вообще не помогает с проблемами безопасности.
warvariuc
12

Вы должны отключить песочницу для Groovy в конфигурации вашего задания.

В настоящее время это невозможно для многоотраслевых проектов, где Groovy-скрипт берется из scm. Для получения дополнительной информации см. Https://issues.jenkins-ci.org/browse/JENKINS-28178.

Андре
источник
6

Я столкнулся с этим, когда уменьшил количество вводимых пользователем параметров в userInput с 3 до 1. Это изменило тип вывода переменной userInput с массива на примитив.

Пример:

myvar1 = userInput['param1']
myvar2 = userInput['param2']

кому:

myvar = userInput
отметка
источник
Это как раз то, что устраняет симптом, который я испытал. Сообщение об ошибке было org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. Метод ожидал 2 параметра и получил 3.
Tyler W
4

Чтобы обойти изолирование скриптов Groovy, хранящихся в SCM, я рекомендую запускать скрипт как Groovy Command (вместо файла Groovy Script ):

import hudson.FilePath
final GROOVY_SCRIPT = "workspace/relative/path/to/the/checked/out/groovy/script.groovy"

evaluate(new FilePath(build.workspace, GROOVY_SCRIPT).read().text)

в таком случае Groovy-скрипт переносится из рабочей области в Jenkins Master, где он может быть выполнен как system Groovy Script. Песочница подавляется, пока не установлен флажок Использовать песочницу Groovy .

Степан Вавра
источник
5
Это кажется неуклюжим, рискованным и обязательно вернется и укусит вас.
Саймон Форсберг
4
Что ж, безопасность важна, особенно когда она защищает конфиденциальные данные пользователя, но она также имеет свою цену, например, усложнение в процессе разработки. Когда инструменты безопасности реализованы лишь наполовину, становится еще хуже. Песочница сценария Jenkins - хороший пример наполовину реализованного инструментария безопасности, и в результате вам может потребоваться полностью отключить эту функцию, потому что в противном случае это означает, что вы не пойдете.
Степан Вавра
3
В моем случае после обновления более старого Jenkins мой скрипт Groovy перестал работать, и единственный способ заставить его работать - это запустить скрипт 300 раз (только приблизительная оценка) и для каждого запуска щелкать в пользовательском интерфейсе Jenkins, чтобы разрешить все вызовы методов в сценарии из 200 строк. Более того, пользовательский интерфейс не позволяет вам вставить полный список всех разрешенных вызовов методов, если вы смогли каким-то образом их сгенерировать. Кроме того, пользовательский интерфейс перестал отображать некоторые вызовы методов, и через некоторое время я не смог продолжить.
Степан Вавра