Los scripts Jenkins CI Pipeline no pueden usar el método groovy.lang.GroovyObject

104

Estoy usando Jenkins 2 para compilar proyectos Java, quiero leer la versión de un pom.xml, estaba siguiendo este ejemplo:

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

El ejemplo sugiere:

Pipeline Jenkins completo con función problemática en un círculo

Parece que hay algún problema de seguridad al acceder al sistema de archivos, pero no puedo entender qué está dando (o por qué) ese problema:

Solo estoy haciendo un poco diferente al ejemplo:

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

El error que obtengo al ejecutar el método de 'versión':

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)

Estoy usando estas versiones: Plugin Pipeline 2.1 Jenkins 2.2

Daniel Hernández
fuente
Tuve un error similar sobre Scripts not permitted to use method, pero sucedió porque escribí en scm 'checkout'lugar de checkou scm. En caso de que alguien caiga en esto, tenga cuidado con la sintaxis incorrecta :). Hacer lo que dijo Maarten Kieft me permitió ver un mensaje de error más claro sobre el comando incorrecto :)
GabLeRoux

Respuestas:

261

Arreglo rapido

Tuve un problema similar y lo resolví haciendo lo siguiente

  1. Vaya a jenkins> Administrar jenkins> Aprobación de script en proceso
  2. Había un comando pendiente, que tuve que aprobar.

En enlace de aprobación de proceso en Jenkins 2.61 Alternativa 1: deshabilitar la zona de pruebas

Como este artículo explica en profundidad, los scripts maravillosos se ejecutan en modo sandbox de forma predeterminada. Esto significa que un subconjunto de métodos maravillosos puede ejecutarse sin la aprobación del administrador. También es posible ejecutar scripts que no estén en modo sandbox, lo que implica que todo el script debe ser aprobado por un administrador a la vez. Esto evita que los usuarios aprueben cada línea en ese momento.

Se pueden ejecutar scripts sin sandbox desmarcando esta casilla de verificación en la configuración de su proyecto justo debajo de su script: ingrese la descripción de la imagen aquí

Alternativa 2: deshabilitar la seguridad del script

Como se explica en este artículo , también es posible deshabilitar la seguridad del script por completo. Primero instale el complemento de seguridad de script permisivo y luego cambie su archivo jenkins.xml agregue este argumento:

-Dpermissive-script-security.enabled = true

Entonces, jenkins.xml se verá así:

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

¡Asegúrese de saber lo que está haciendo si implementa esto!

Maarten Kieft
fuente
1
Si aprobar todo el guión es mejor, depende de la estructura del equipo. Para algunos desarrolladores con acceso completo, es bastante bueno. Pero una configuración con varios equipos obligaría a los administradores a aprobar cada cambio en todos los scripts de canalización.
Roger Lehmann
2
La alternativa 3 (realmente debería ser la primera sugerencia) es alterar el código problemático no incluido en la lista blanca . En este caso, sería suficiente un simple uso de @NonCPSpara el Matcheruso. En este caso, no es necesario deshabilitar la seguridad para toda la tubería, y especialmente para toda la instalación de Jenkins. Evalúe cada llamada bloqueada individualmente y decida si realmente necesita aprobarla.
mkobit
1
@mkobit no funciona para mí. @NonCPSno ayuda.
warvariuc
@warvariuc hmm, podría ser si está regresando Matcher, porque Matcherno implementa la Serializableinterfaz. Podría valer la pena hacer una nueva pregunta. Deseo que la documentación a la que se hace referencia en la pregunta original se mantenga y no sea incorrecta para empezar.
mkobit
2
@mkobit lo decoré con NonCPS una función que usa currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). NonCPS no ayuda en absoluto con los problemas de seguridad, por lo que leí.
warvariuc
12

Tienes que deshabilitar la caja de arena para Groovy en la configuración de tu trabajo.

Actualmente, esto no es posible para proyectos de múltiples ramas donde el script maravilloso proviene de scm. Para obtener más información, consulte https://issues.jenkins-ci.org/browse/JENKINS-28178

Andre
fuente
6

Me encontré con esto cuando reduje el número de parámetros de entrada de usuario en userInput de 3 a 1. Esto cambió el tipo de salida variable de userInput de una matriz a una primitiva.

Ejemplo:

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

a:

myvar = userInput
marca
fuente
Esta es exactamente la solución para el síntoma que experimenté. El mensaje de error fue org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. El método esperaba 2 parámetros y estaba recibiendo 3.
Tyler W
4

Para sortear el sandboxing de los scripts Groovy almacenados en SCM, recomiendo ejecutar el script como Groovy Command (en lugar del archivo 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)

en tal caso, la secuencia de comandos maravillosa se transfiere del espacio de trabajo al Jenkins Master, donde se puede ejecutar como system Groovy Script. El sandboxing se suprime siempre que la opción Use Groovy Sandbox no esté marcada .

Stepan Vavra
fuente
5
Esto parece torpe, arriesgado y destinado a volver y morderte.
Simon Forsberg
4
Bueno, la seguridad es importante especialmente cuando protege los datos confidenciales del usuario, pero también tiene un precio, como una complicación durante el proceso de desarrollo. Cuando las herramientas de seguridad están implementadas a la mitad, empeora aún más. El sandboxing de secuencia de comandos de Jenkins es un buen ejemplo de herramientas de seguridad implementadas a medias y, como resultado, es posible que deba deshabilitar por completo la función porque, de lo contrario, no significará nada para usted.
Stepan Vavra
3
En mi caso, después de una actualización de un Jenkins anterior, mi script Groovy dejó de funcionar y la única forma de hacerlo funcionar sería ejecutar el script 300 veces (solo una estimación) y para cada ejecución hacer clic en la interfaz de usuario de Jenkins para permitir todas las llamadas a métodos en un script de 200 líneas. Además, la interfaz de usuario no le permite pegar la lista completa de todas las llamadas de método permitidas en caso de que pueda generarlas de alguna manera. Además, la interfaz de usuario dejó de mostrar algunas de las llamadas al método y, después de un tiempo, no pude continuar.
Stepan Vavra