Les scripts Jenkins CI Pipeline ne sont pas autorisés à utiliser la méthode groovy.lang.GroovyObject

105

J'utilise Jenkins 2 pour compiler des projets Java, je veux lire la version à partir d'un pom.xml, je suivais cet exemple:

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

L'exemple suggère:

Pipeline Jenkins complet avec fonction problématique encerclée

Il semble qu'il y ait un problème de sécurité pour accéder au système de fichiers, mais je ne peux pas comprendre ce qu'il donne (ou pourquoi) ce problème:

Je fais juste un peu différent de l'exemple:

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

L'erreur que j'obtiens lors de l'exécution de la méthode '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)

J'utilise ces versions: Plugin Pipeline 2.1 Jenkins 2.2

Daniel Hernández
la source
J'ai eu une erreur similaire Scripts not permitted to use method, mais c'est arrivé parce que j'ai écrit à la scm 'checkout'place checkou scm. Juste au cas où quelqu'un tomberait dessus, surveillez la mauvaise syntaxe :). Faire comme Maarten Kieft m'a permis de voir un message d'erreur plus clair sur la mauvaise commande :)
GabLeRoux

Réponses:

262

Solution rapide

J'ai eu un problème similaire et je l'ai résolu en procédant comme suit

  1. Accédez à jenkins> Gérer jenkins> Approbation de script en cours de processus
  2. Il y avait une commande en attente, que j'ai dû approuver.

Lien d'approbation en cours dans Jenkins 2.61 Alternative 1: désactiver le bac à sable

Comme cet article l' explique en détail, les scripts groovy sont exécutés par défaut en mode sandbox. Cela signifie qu'un sous-ensemble de méthodes groovy est autorisé à s'exécuter sans l'approbation de l'administrateur. Il est également possible d'exécuter des scripts pas en mode sandbox, ce qui implique que l'ensemble du script doit être approuvé par un administrateur à la fois. Cela empêche les utilisateurs d'approuver chaque ligne à la fois.

L'exécution de scripts sans sandbox peut être effectuée en décochant cette case dans la configuration de votre projet juste en dessous de votre script: entrez la description de l'image ici

Alternative 2: désactiver la sécurité des scripts

Comme cet article l' explique, il est également possible de désactiver complètement la sécurité des scripts. Installez d'abord le plugin de sécurité de script permissif, puis modifiez votre fichier jenkins.xml, ajoutez cet argument:

-Dpermissive-script-security.enabled = true

Ainsi, jenkins.xml ressemblera à quelque chose comme ceci:

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

Assurez-vous de savoir ce que vous faites si vous implémentez cela!

Maarten Kieft
la source
1
Si l'approbation de l'ensemble du script est meilleure, cela dépend de la structure de l'équipe. Pour quelques développeurs avec un accès complet, c'est plutôt sympa. Mais une configuration avec plusieurs équipes obligerait les administrateurs à approuver chaque changement dans tous les scripts de pipeline.
Roger Lehmann
2
L'alternative 3 (devrait vraiment être la première suggestion) consiste à modifier le code problématique non inscrit sur la liste blanche . Dans ce cas, une simple utilisation de @NonCPSpour l' Matcherusage suffirait. Il n'est pas nécessaire dans ce cas de désactiver la sécurité pour tout le pipeline, et en particulier pour toute l'installation de Jenkins. Évaluez chaque appel bloqué individuellement et décidez si vous devez vraiment les approuver.
mkobit le
1
@mkobit ne fonctionne pas pour moi. @NonCPSn'aide pas.
warvariuc
@warvariuc hmm, cela pourrait être si vous vous renvoyez Matcher, car n'implémente Matcherpas l' Serializableinterface. Cela pourrait valoir la peine de poser une nouvelle question. Je souhaite que la documentation mentionnée dans la question initiale soit conservée et qu'elle ne soit pas erronée au départ.
mkobit
2
@mkobit j'ai décoré avec NonCPS une fonction qui utilise currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). NonCPS n'aide pas du tout avec les problèmes de sécurité, d'après ce que j'ai lu.
warvariuc
12

Vous devez désactiver le bac à sable pour Groovy dans la configuration de votre travail.

Actuellement, cela n'est pas possible pour les projets multibranches où le script groovy provient du scm. Pour plus d'informations, voir https://issues.jenkins-ci.org/browse/JENKINS-28178

André
la source
6

J'ai rencontré cela lorsque j'ai réduit le nombre de paramètres d'entrée utilisateur dans userInput de 3 à 1. Cela a changé le type de sortie variable de userInput d'un tableau à une primitive.

Exemple:

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

à:

myvar = userInput
marque
la source
C'est exactement la solution pour le symptôme que j'ai ressenti. Le message d'erreur était org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. La méthode attendait 2 paramètres et recevait 3.
Tyler W
4

Pour contourner le sandboxing des scripts Groovy stockés par SCM, je recommande d'exécuter le script en tant que Groovy Command (au lieu du fichier 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)

dans ce cas, le script groovy est transféré de l'espace de travail vers le maître Jenkins où il peut être exécuté en tant que fichier system Groovy Script. Le sandboxing est supprimé tant que la case Use Groovy Sandbox n'est pas cochée .

Stépan Vavra
la source
5
Cela semble maladroit, risqué et voué à revenir vous mordre.
Simon Forsberg
4
Eh bien, la sécurité est importante en particulier lorsqu'elle protège les données sensibles des utilisateurs, mais elle a également un prix tel qu'une complication pendant le processus de développement. Lorsque les outils de sécurité ne sont qu'à moitié mis en œuvre, cela s'aggrave. Le sandboxing de script Jenkins est un bel exemple d'outils de sécurité à moitié implémentés et, par conséquent, vous devrez peut-être désactiver complètement la fonctionnalité, sinon cela signifie que vous ne pouvez pas y aller.
Stepan Vavra
3
Dans mon cas, après une mise à niveau d'un ancien Jenkins, mon script Groovy a cessé de fonctionner et la seule façon de le faire fonctionner serait d'exécuter le script 300 fois (juste une estimation) et pour chaque exécution de cliquer dans l'interface utilisateur de Jenkins pour autoriser tous les appels de méthode dans un script de 200 lignes. De plus, l'interface utilisateur ne vous permet pas de coller la liste complète de tous les appels de méthode autorisés au cas où vous auriez pu les générer d'une manière ou d'une autre. De plus, l'interface utilisateur a cessé d'afficher certains des appels de méthode et après un certain temps, je n'ai pas pu continuer.
Stepan Vavra