Apa efek @NonCPS dalam skrip pipeline Jenkins

110

Saya memiliki skrip saluran pipa di Jenkins.

Saya biasa mendapatkan pengecualian ini:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Skrip tidak diizinkan untuk menggunakan metode groovy.json.JsonSlurperClassic parseText java.lang.String

Saya mencari pengecualian dan saya menemukan beberapa indikasi bahwa saya harus menjelaskan metode di mana pengecualian tersebut terjadi @NonCPS. Saya melakukan ini, tanpa benar-benar memahami apa yang dilakukannya.

Namun, setelah itu, Pengecualian yang saya lemparkan dalam metode itu tidak lagi terperangkap oleh tryklausa.

Jadi apa idenya @NonCPS? Apa efek dari menggunakannya?

oktavianus
sumber
1
Blog resmi jenkins memiliki artikel yang memperkenalkan anotasi ini dan dapat membantu Anda. jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice
袁文涛

Jawaban:

142

Pengecualian yang Anda lihat adalah karena keamanan skrip dan kotak pasir. Pada dasarnya, secara default, saat Anda menjalankan skrip pipeline, skrip ini berjalan di kotak pasir yang hanya mengizinkan penggunaan metode dan kelas tertentu. Ada cara untuk memasukkan operasi ke daftar putih, periksa tautan di atas.

The @NonCPSpenjelasan ini berguna bila Anda memiliki metode yang menggunakan benda-benda yang tidak serializable. Biasanya, semua objek yang Anda buat di skrip pipeline Anda harus dapat diserialkan (alasannya adalah Jenkins harus dapat membuat serial status skrip sehingga dapat dijeda dan disimpan di disk).

Saat Anda @NonCPSmenggunakan metode, Jenkins akan menjalankan seluruh metode sekaligus tanpa kemampuan untuk menjeda. Selain itu, Anda tidak diizinkan untuk mereferensikan langkah pipeline apa pun atau metode CPS yang diubah dari dalam @NonCPSmetode beranotasi. Informasi lebih lanjut tentang ini dapat ditemukan di sini .

Adapun penanganan pengecualian: Tidak 100% yakin apa yang Anda alami; Saya telah mencoba yang berikut dan berfungsi seperti yang diharapkan:

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

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

dan

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

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

mySecondFunction();

dan akhirnya:

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

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

mySecondFunction();

Semua mencetak "Tertangkap" seperti yang diharapkan.

Jon S
sumber