web-dev-qa-db-fra.com

Quel est l’effet de @NonCPS dans un script de pipeline Jenkins?

J'ai un script de pipeline à Jenkins.

J'avais l'habitude d'avoir cette exception:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts non autorisés à utiliser la méthode groovy.json.JsonSlurperClassic parseText Java.lang.String

J'ai regardé l'exception et j'ai trouvé des indications que je devrais annoter la méthode où l'exception se produit avec @NonCPS. Je l'ai fait, sans vraiment comprendre ce que cela fait.

Cependant, après cela, une exception que j’ai lancée dans cette méthode n’est plus interceptée par une clause try.

Alors, quelle est l'idée derrière @NonCPS? Quels sont les effets de l'utiliser?

79
octavian

L'exception que vous voyez est due à sécurité du script et au sandboxing. Fondamentalement, par défaut, lorsque vous exécutez un script de pipeline, celui-ci s’exécute dans un sandbox qui autorise uniquement l’utilisation de certaines méthodes et classes. Il existe des moyens de liste blanche des opérations, consultez le lien ci-dessus.

L'annotation @NonCPS est utile lorsque vous utilisez des méthodes qui utilisent des objets non sérialisables. Normalement, tous les objets que vous créez dans votre script de pipeline doivent être sérialisables (la raison en est que Jenkins doit être capable de sérialiser l'état du script afin qu'il puisse être suspendu et stocké sur le disque).

Lorsque vous mettez @NonCPS sur une méthode, Jenkins exécute la méthode en une fois sans possibilité de pause. En outre, vous n'êtes pas autorisé à référencer les étapes de pipeline ou les méthodes transformées par CPS à partir d'une méthode annotée @NonCPS. Plus d'informations à ce sujet peuvent être trouvées ici .

En ce qui concerne la gestion des exceptions: vous n'êtes pas sûr à 100% de ce que vous vivez; J'ai essayé ce qui suit et cela fonctionne comme prévu:

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

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

et

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

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

mySecondFunction();

et enfin:

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

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

mySecondFunction();

Tous les imprimés "pris" comme prévu.

97
Jon S