Tác dụng của @NonCPS trong tập lệnh đường dẫn Jenkins là gì


110

Tôi có một kịch bản đường ống trong Jenkins.

Tôi đã từng mắc phải ngoại lệ này:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Các tập lệnh không được phép sử dụng phương thức groovy.json.JsonSlurperClassic parseText java.lang.String

Tôi đã tìm kiếm ngoại lệ và tôi tìm thấy một số dấu hiệu cho thấy tôi nên chú thích phương thức mà ngoại lệ xảy ra với @NonCPS. Tôi đã làm điều này, mà không thực sự hiểu điều này làm gì.

Tuy nhiên, sau đó, một Ngoại lệ mà tôi đã đưa vào phương thức đó không còn bị bắt bởi một trymệnh đề.

Vậy ý tưởng đằng sau là @NonCPSgì? Những tác dụng của việc sử dụng nó là gì?


1
Blog chính thức của jenkins có một bài viết giới thiệu chú thích này và có thể giúp ích cho bạn. jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice
袁文涛

Câu trả lời:


141

Ngoại lệ mà bạn đang thấy là do bảo mật tập lệnh và hộp cát. Về cơ bản, theo mặc định, khi bạn chạy một tập lệnh đường ống, nó sẽ chạy trong một hộp cát chỉ cho phép sử dụng một số phương thức và lớp nhất định. Có nhiều cách để lập danh sách trắng các hoạt động, hãy kiểm tra liên kết ở trên.

Các @NonCPS chú thích rất hữu ích khi bạn có phương pháp mà sử dụng đối tượng mà không phải là serializable. Thông thường, tất cả các đối tượng mà bạn tạo trong tập lệnh đường ống của mình phải có thể tuần tự hóa (lý do cho điều này là Jenkins phải có khả năng tuần tự hóa trạng thái của tập lệnh để có thể tạm dừng và lưu trữ trên đĩa).

Khi bạn đặt @NonCPSmột phương thức, Jenkins sẽ thực thi toàn bộ phương thức trong một lần mà không có khả năng tạm dừng. Ngoài ra, bạn không được phép tham chiếu bất kỳ bước đường ống hoặc phương pháp được chuyển đổi CPS nào từ bên trong một @NonCPSphương pháp được chú thích. Thông tin thêm về điều này có thể được tìm thấy ở đây .

Đối với việc xử lý ngoại lệ: Không chắc chắn 100% những gì bạn đang gặp phải; Tôi đã thử những cách sau và nó hoạt động như mong đợi:

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

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

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

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

mySecondFunction();

và cuối cùng:

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

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

mySecondFunction();

Tất cả đều in "Caught" như mong đợi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.