web-dev-qa-db-fra.com

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

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

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

L'exemple suggère:

Full Jenkins Pipeline with problematic function circled

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

79
Daniel Hernández

Quickfix

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 traitement
  2. Il y avait une commande en attente, que je devais approuver.

In process approval link in Jenkins 2.61 Alternative 1: Désactiver le bac à sable

Comme l'explique en détail article , les scripts groovy sont exécutés en mode sandbox par défaut. 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 en mode sandbox, ce qui implique que l'intégralité du script doit être approuvée 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: enter image description here

Alternative 2: Désactiver la sécurité du script

Comme cela article , il est également possible de désactiver complètement la sécurité des scripts. Commencez par installer le plugin de sécurité de script permissif , puis modifiez votre fichier jenkins.xml en ajoutant cet argument:

-Dpermissive-script-security.enabled = true

Donc, jenkins.xml ressemblera à 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 ceci!

207
Maarten Kieft

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 pour lesquels le script groovy provient de la scm. Pour plus d'informations, voir https://issues.jenkins-ci.org/browse/JENKINS-28178

10
Andre

Pour contourner le sandboxing des scripts Groovy stockés dans SCM, je vous recommande d'exécuter le script en tant que commande Groovy (au lieu de 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 au maître Jenkins où il peut être exécuté en tant que system Groovy Script. Le bac à sable est supprimé tant que le tiliser Groovy Sandbox n'est pas coché .

4
Stepan Vavra

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

Exemple:

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

à:

myvar = userInput
1
Mark