Os scripts do Jenkins CI Pipeline não têm permissão para usar o método groovy.lang.GroovyObject

104

Estou usando o Jenkins 2 para compilar projetos Java, quero ler a versão de um pom.xml, estava seguindo este exemplo:

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

O exemplo sugere:

Pipeline completo do Jenkins com função problemática circulada

Parece que há algum problema de segurança ao acessar o sistema de arquivos, mas não consigo descobrir o que está causando (ou por que) esse problema:

Estou apenas fazendo um pouco diferente do exemplo:

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

O erro que estou obtendo ao executar o método 'version':

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)

Estou usando estas versões: Plugin Pipeline 2.1 Jenkins 2.2

Daniel Hernández
fonte
Tive um erro semelhante sobre Scripts not permitted to use method, mas aconteceu porque escrevi em scm 'checkout'vez de checkou scm. Caso alguém caia nisso, preste atenção à sintaxe errada :). Fazer o que Maarten Kieft disse me permitiu ver uma mensagem de erro mais clara sobre o comando incorreto :)
GabLeRoux

Respostas:

261

Conserto rápido

Eu tive um problema semelhante e resolvi fazendo o seguinte

  1. Navegue até jenkins> Gerenciar jenkins> Aprovação de script em processo
  2. Havia um comando pendente, que eu tive que aprovar.

Em processo de link de aprovação no Jenkins 2.61 Alternativa 1: Desativar sandbox

Como este artigo explica em detalhes, os scripts bacanas são executados no modo sandbox por padrão. Isso significa que um subconjunto de métodos interessantes pode ser executado sem a aprovação do administrador. Também é possível executar scripts fora do modo sandbox, o que implica que todo o script precisa ser aprovado por um administrador de uma vez. Isso evita que os usuários aprovem cada linha no momento.

A execução de scripts sem sandbox pode ser feita desmarcando esta caixa de seleção na configuração do projeto logo abaixo do script: insira a descrição da imagem aqui

Alternativa 2: Desative a segurança do script

Como este artigo explica, também é possível desabilitar completamente a segurança do script. Primeiro instale o plug - in de segurança de script permissivo e depois altere seu arquivo jenkins.xml, adicione este argumento:

-Dpermissive-script-security.enabled = true

Então seu jenkins.xml será parecido com isto:

<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>

Certifique-se de saber o que está fazendo se implementar isso!

Maarten Kieft
fonte
1
Se aprovar todo o roteiro é melhor, depende da estrutura da equipe. Para alguns desenvolvedores com acesso total, é muito bom. Mas uma configuração com várias equipes forçaria os administradores a aprovar todas as alterações em todos os scripts do pipeline.
Roger Lehmann
2
A alternativa 3 (deveria realmente ser a primeira sugestão) é alterar o código problemático não incluído na lista branca . Nesse caso, um simples uso de @NonCPSpara o Matcheruso seria suficiente. Não há necessidade, neste caso, de desativar a segurança de todo o pipeline e, especialmente, de toda a instalação do Jenkins. Avalie cada chamada bloqueada individualmente e decida se você realmente precisa aprová-las.
mkobit
1
@mkobit não funciona para mim. @NonCPSnão ajuda.
warvariuc
@warvariuc hmm, pode ser se você estiver retornando Matcherpropriamente dito, pois Matchernão implementa a Serializableinterface. Pode valer a pena fazer uma nova pergunta. Desejo que a documentação referenciada na pergunta original seja mantida e não esteja errada para começar.
mkobit de
2
@mkobit eu decorei com NonCPS uma função que usa currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). O NonCPS não ajuda em nada com os problemas de segurança, pelo que li.
warvariuc
12

Você tem que desabilitar a sandbox para Groovy em sua configuração de trabalho.

Atualmente, isso não é possível para projetos multibrânquicos em que o script bacana vem do scm. Para obter mais informações, consulte https://issues.jenkins-ci.org/browse/JENKINS-28178

Andre
fonte
6

Eu encontrei isso quando reduzi o número de parâmetros de entrada do usuário em userInput de 3 para 1. Isso mudou o tipo de saída variável de userInput de um array para um primitivo.

Exemplo:

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

para:

myvar = userInput
Marca
fonte
Essa é exatamente a correção para o sintoma que experimentei. A mensagem de erro foi org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. O método esperava 2 parâmetros e estava recebendo 3.
Tyler W
4

Para contornar a sandbox de scripts Groovy armazenados no SCM, recomendo executar o script como Comando Groovy (em vez de arquivo de Script Groovy ):

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)

nesse caso, o script bacana é transferido da área de trabalho para o Jenkins Master, onde pode ser executado como um system Groovy Script. O sandboxing é suprimido enquanto a opção Usar Groovy Sandbox não estiver marcada .

Stepan Vavra
fonte
5
Isso parece desajeitado, arriscado e destinado a voltar e morder você.
Simon Forsberg
4
Bem, a segurança é importante, especialmente quando protege os dados confidenciais do usuário, mas também tem um preço, como uma complicação durante o processo de desenvolvimento. Quando as ferramentas de segurança estão apenas parcialmente implementadas, fica ainda pior. O sandboxing do script Jenkins é um bom exemplo de ferramenta de segurança parcialmente implementada e, como resultado, você pode precisar desativar completamente o recurso, caso contrário, isso significa que não vai para você.
Stepan Vavra
3
No meu caso, após uma atualização de um Jenkins mais antigo, meu script Groovy parou de funcionar e a única maneira de fazê-lo funcionar seria executar o script 300 vezes (apenas uma estimativa) e para cada execução clicar na IU do Jenkins para permitir todas as chamadas de método em um script de 200 linhas. Além disso, a IU não permite que você cole a lista completa de todas as chamadas de método permitidas, caso você seja capaz de gerá-las de alguma forma. Além disso, a IU parou de mostrar algumas das chamadas de método e depois de um tempo, não consegui prosseguir.
Stepan Vavra