Gli script della pipeline CI di Jenkins non sono autorizzati a utilizzare il metodo groovy.lang.GroovyObject


104

Sto usando Jenkins 2 per compilare progetti Java, voglio leggere la versione da un pom.xml, stavo seguendo questo esempio:

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

L'esempio suggerisce:

Pipeline Jenkins completa con funzione problematica cerchiata

Sembra che ci sia qualche problema di sicurezza durante l'accesso al File System ma non riesco a capire cosa sta dando (o perché) quel problema:

Sto solo facendo un po 'di differenza rispetto all'esempio:

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

L'errore che ricevo durante l'esecuzione del metodo "versione":

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)

Sto usando queste versioni: Plugin Pipeline 2.1 Jenkins 2.2


Ho avuto un errore simile su Scripts not permitted to use method, ma è successo perché ho scritto scm 'checkout'invece di checkou scm. Nel caso qualcuno ci cada, fai attenzione alla cattiva sintassi :). Fare come ha detto Maarten Kieft mi ha permesso di vedere un messaggio di errore più chiaro sul cattivo comando :)
GabLeRoux

Risposte:


261

Soluzione rapida

Ho avuto un problema simile e l'ho risolto facendo quanto segue

  1. Passa a jenkins> Gestisci jenkins> Approvazione script in-process
  2. C'era un comando in sospeso, che ho dovuto approvare.

Collegamento di approvazione in corso in Jenkins 2.61 Alternativa 1: disabilita sandbox

Come questo articolo spiega in dettaglio, gli script groovy vengono eseguiti in modalità sandbox per impostazione predefinita. Ciò significa che un sottoinsieme di metodi groovy può essere eseguito senza l'approvazione dell'amministratore. È anche possibile eseguire script non in modalità sandbox, il che implica che l'intero script deve essere approvato da un amministratore contemporaneamente. Ciò impedisce agli utenti di approvare ogni riga in quel momento.

L'esecuzione di script senza sandbox può essere eseguita deselezionando questa casella di controllo nella configurazione del progetto appena sotto lo script: inserisci qui la descrizione dell'immagine

Alternativa 2: disabilitare la sicurezza degli script

Come spiega questo articolo, è anche possibile disabilitare completamente la sicurezza degli script. Prima installa il plug-in di sicurezza degli script permissivi e successivamente modifica il tuo file jenkins.xml aggiungi questo argomento:

-Dpermissive-script-security.enabled = true

Quindi il tuo jenkins.xml avrà un aspetto simile a questo:

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

Assicurati di sapere cosa stai facendo se lo implementi!


1
Se l'approvazione dell'intero script è migliore, dipende dalla struttura del team. Per alcuni sviluppatori con accesso completo è abbastanza carino. Ma una configurazione con più team costringerebbe gli amministratori ad approvare ogni modifica in tutti gli script della pipeline.
Roger Lehmann

2
L'alternativa 3 (dovrebbe davvero essere il primo suggerimento) è modificare il codice problematico non autorizzato . In questo caso, sarebbe sufficiente un semplice utilizzo di @NonCPSper l' Matcherutilizzo. Non è necessario in questo caso disabilitare la sicurezza per l'intera pipeline e soprattutto per l'intera installazione di Jenkins. Valuta singolarmente ogni chiamata bloccata e decidi se devi davvero approvarla.
mkobit

1
@mkobit non funziona per me. @NonCPSnon aiuta.
warvariuc

@warvariuc hmm, potrebbe essere se stai restituendo Matcherse stesso, perché Matchernon implementa l' Serializableinterfaccia. Potrebbe valere la pena fare una nuova domanda. Vorrei che la documentazione a cui si fa riferimento nella domanda originale fosse mantenuta e non fosse sbagliata all'inizio.
mkobit

2
@mkobit ho decorato con NonCPS una funzione che utilizza currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). NonCPS non aiuta affatto con i problemi di sicurezza, da quello che ho letto.
warvariuc


6

Mi sono imbattuto in questo quando ho ridotto il numero di parametri di input dell'utente in userInput da 3 a 1. Ciò ha cambiato il tipo di output variabile di userInput da un array a una primitiva.

Esempio:

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

per:

myvar = userInput

Questa è esattamente la soluzione per il sintomo che ho riscontrato. Il messaggio di errore era org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. Il metodo prevedeva 2 parametri e ne riceveva 3.
Tyler W

4

Per aggirare il sandboxing degli script Groovy archiviati in SCM, consiglio di eseguire lo script come Groovy Command (invece del file 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)

in tal caso, lo script groovy viene trasferito dall'area di lavoro a Jenkins Master dove può essere eseguito come file system Groovy Script. Il sandboxing viene soppresso fintanto che Use Groovy Sandbox non è selezionato .


5
Questo sembra goffo, rischioso e destinato a tornare e morderti.
Simon Forsberg

4
Bene, la sicurezza è importante soprattutto quando protegge i dati sensibili degli utenti, ma ha anche un prezzo come una complicazione durante il processo di sviluppo. Quando gli strumenti di sicurezza sono implementati solo a metà, peggiorano ulteriormente. Lo script sandbox di Jenkins è un bell'esempio di strumenti di sicurezza implementati a metà e di conseguenza potresti dover disabilitare completamente la funzione perché altrimenti significa che non puoi farlo.
Stepan Vavra

3
Nel mio caso, dopo un aggiornamento da un vecchio Jenkins, il mio script Groovy ha smesso di funzionare e l'unico modo per farlo funzionare sarebbe eseguire lo script 300 volte (solo una stima) e per ogni esecuzione fare clic sull'interfaccia utente di Jenkins per consentire tutte le chiamate di metodo in uno script di 200 righe. Inoltre l'interfaccia utente non ti consente di incollare l'elenco completo di tutte le chiamate di metodo consentite nel caso in cui tu fossi in grado di generarle in qualche modo. Inoltre, l'interfaccia utente ha smesso di mostrare alcune delle chiamate al metodo e dopo un po 'non sono stato in grado di procedere.
Stepan Vavra
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.