Qual é o efeito de @NonCPS em um script de pipeline do Jenkins


110

Eu tenho um script de pipeline no Jenkins.

Eu costumava receber esta exceção:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts não permitidos para usar o método groovy.json.JsonSlurperClassic parseText java.lang.String

Eu pesquisei a exceção e encontrei algumas indicações de que devo anotar o método com o qual a exceção ocorre @NonCPS. Eu fiz isso, sem realmente entender o que isso significa.

Depois disso, no entanto, uma exceção que eu estava lançando naquele método não era mais capturada por uma trycláusula.

Qual é a ideia por trás disso @NonCPS? Quais são os efeitos de usá-lo?


1
O blog oficial de jenkins tem um artigo que apresenta essa anotação e pode ajudá-lo. jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice
袁文涛

Respostas:


142

A exceção que você está vendo é devido à segurança do script e ao sandbox. Basicamente, por padrão, quando você executa um script de pipeline, ele é executado em uma caixa de proteção que só permite o uso de determinados métodos e classes. Existem maneiras de colocar operações na lista de permissões, verifique o link acima.

A @NonCPSanotação é útil quando você tem métodos que usam objetos que não são serializáveis. Normalmente, todos os objetos que você cria no script do pipeline devem ser serializáveis ​​(a razão para isso é que o Jenkins deve ser capaz de serializar o estado do script para que possa ser pausado e armazenado no disco).

Quando você coloca @NonCPSum método, o Jenkins executa o método inteiro de uma vez, sem a capacidade de fazer uma pausa. Além disso, você não tem permissão para fazer referência a nenhuma etapa do pipeline ou métodos transformados CPS de dentro de um @NonCPSmétodo anotado. Mais informações sobre isso podem ser encontradas aqui .

Quanto ao tratamento de exceções: Não tenho 100% de certeza do que está ocorrendo; Tentei o seguinte e funcionou conforme o esperado:

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

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

e

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

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

mySecondFunction();

e finalmente:

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

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

mySecondFunction();

Todos imprimem "Pego" conforme o esperado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.