it-swarm.com.de

Was ist der Effekt von @NonCPS in einem Jenkins-Pipeline-Skript?

Ich habe ein Pipeline-Skript in Jenkins.

Früher habe ich diese Ausnahme bekommen:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Skripte dürfen die Methode groovy.json.JsonSlurperClassic parseText Java.lang.String nicht verwenden

Ich habe die Ausnahme nachgeschlagen und einige Hinweise gefunden, dass ich die Methode, bei der die Ausnahme auftritt, mit @NonCPS Kommentieren sollte. Ich habe das getan, ohne wirklich zu verstehen, was das tut.

Danach wurde eine Ausnahme, die ich in dieser Methode ausgelöst habe, nicht mehr von einer try -Klausel erfasst.

Welche Idee steckt also hinter @NonCPS? Welche Auswirkungen hat die Verwendung?

79
octavian

Die Ausnahme, die Sie sehen, ist auf Skriptsicherheit und Sandboxing zurückzuführen. Grundsätzlich wird ein Pipeline-Skript beim Ausführen standardmäßig in einer Sandbox ausgeführt, in der nur bestimmte Methoden und Klassen verwendet werden können. Es gibt Möglichkeiten, Operationen auf die Whitelist zu setzen. Überprüfen Sie den obigen Link.

Die Annotation @NonCPS Ist nützlich, wenn Sie Methoden haben, die Objekte verwenden, die nicht serialisierbar sind. Normalerweise müssen alle Objekte, die Sie in Ihrem Pipeline-Skript erstellen, serialisierbar sein (der Grund dafür ist, dass Jenkins den Status des Skripts serialisieren kann, damit es angehalten und auf der Festplatte gespeichert werden kann).

Wenn Sie einer Methode @NonCPS Zuweisen, führt Jenkins die gesamte Methode auf einmal aus, ohne die Möglichkeit zu unterbrechen. Außerdem dürfen Sie innerhalb einer mit @NonCPS - Annotationen versehenen Methode keine Pipelineschritte oder CPS-transformierten Methoden referenzieren. Weitere Informationen dazu finden Sie hier .

Was die Ausnahmebehandlung betrifft: Nicht 100% sicher, was Sie erleben; Ich habe Folgendes versucht und es funktioniert wie erwartet:

@NonCPS
def myFunction() {
    throw new RuntimeException();
}

try {
    myFunction();
} catch (Exception e) {
    echo "Caught";
}

und

@NonCPS
def myFunction() {
    throw new RuntimeException();
}

def mySecondFunction() {
    try {
        myFunction();
    } catch (Exception e) {
        echo "Caught";
    }
}

mySecondFunction();

und schlussendlich:

@NonCPS
def myFunction() {
    throw new RuntimeException();
}

@NonCPS
def mySecondFunction() {
    try {
        myFunction();
    } catch (Exception e) {
        echo "Caught";
    }
}

mySecondFunction();

Alle drucken "Gefangen" wie erwartet.

97
Jon S