2013-01-12 37 views

Trả lời

104

Đối với các độc giả đến với câu hỏi này và câu trả lời trong thời gian tới có thể không quen thuộc với Chef, một chạy Chef "hội tụ" nút, hoặc mang nó phù hợp với chính sách khai báo trong công thức đang chạy. Điều này cũng được gọi là "hội tụ". Điều này có hai giai đoạn, "biên dịch" và "thực thi". Giai đoạn biên dịch là khi Chef đánh giá ("biên dịch") mã Ruby của công thức nấu ăn, tìm kiếm các tài nguyên để thêm vào Bộ sưu tập tài nguyên. Khi điều đó hoàn tất, nó "thực hiện" các hành động cho mỗi tài nguyên để đưa nó vào trạng thái mong muốn. Lệnh hệ thống được chạy, v.v.

Erik Hollensbe đã viết xuất sắc đi qua how this works in 2013.

Bây giờ, đối với câu trả lời:

Có một số cách để chấm dứt một chạy Chef, hoặc thoát khỏi một công thức Chef, tùy thuộc vào cách bạn muốn đi về nó, kể từ Chef công thức nấu ăn là của Ruby mã.

Nếu mục tiêu của bạn là ngừng xử lý công thức dựa trên điều kiện, nhưng tiếp tục với phần còn lại của chạy, hãy sử dụng từ khóa return Ruby. Ví dụ:

file '/tmp/ponies' do 
    action :create 
end 

return if node['platform'] == 'windows' 

package 'bunnies-and-flowers' do 
    action :install 
end 

Chúng tôi giả định rằng nếu hệ thống là Windows, nó không có trình quản lý gói có thể cài đặt gói thỏ và hoa, vì vậy chúng tôi trở lại.

Nếu bạn muốn hủy bỏ việc Chef chạy hoàn toàn

Có một vài thứ khác bạn có thể làm. Đầu bếp sẽ thoát ra nếu nó gặp phải một ngoại lệ chưa được giải quyết ở bất kỳ đâu trong phần đầu bếp. Ví dụ, nếu một tài nguyên mẫu không thể tìm thấy tệp nguồn của nó, hoặc nếu người dùng chạy đầu bếp không có quyền thực hiện điều gì đó như tạo một thư mục. Đây là lý do tại sao sử dụng raise hoạt động để kết thúc chạy.

Nơi bạn đặt raise vấn đề. Nếu bạn sử dụng nó trong một tài nguyên ruby_block, nó sẽ chỉ tăng trong giai đoạn thực hiện hội tụ. Nếu bạn sử dụng nó bên ngoài tài nguyên như ví dụ return ở trên, nó sẽ xảy ra trong giai đoạn biên dịch.

file '/tmp/ponies' do 
    action :create 
end 

raise if node['platform'] == 'windows' 

package 'bunnies-and-flowers' do 
    action :install 
end 

Có lẽ chúng tôi có trình quản lý gói trên Windows và chúng tôi muốn gói này được cài đặt. Việc nâng cao sẽ dẫn đến đầu bếp nghiêm trọng thoát và đưa ra một dấu vết ngăn xếp.

Cách tiếp cận khác là sử dụng Chef::Application.fatal!. Thao tác này sẽ ghi lại thông báo fatal tới trình ghi đầu bếp và STDERR và thoát khỏi ứng dụng. Bạn cũng có thể cung cấp cho nó một mã trả về (có thể bạn có một kịch bản để kiểm tra những cái đó?).

Chef::Application.fatal!("Didn't expect the Spanish Inquistion", 42) if spanish_inquisition 

(dĩ nhiên spanish_inquisition thường là không vì không ai mong đợi ... Tôi phân ...)

Điều này sẽ dẫn đến việc thoát khỏi Đầu bếp, thông báo tường trình được gửi và mã trả về 42 từ quy trình.

Note: Điều này làm cho toàn bộ ứng dụng để thoát khỏi, có nghĩa là nếu nó đang chạy như một dịch vụ daemonized, nó sẽ chấm dứt, và tùy thuộc vào cách dịch vụ được quản lý, nó có thể hoặc không thể bắt đầu lại. Ví dụ: dịch vụ init.d sẽ không khởi động lại, nhưng sẽ có dịch vụ runit.

Vì công thức nấu ăn là Ruby, bạn cũng có thể xử lý các điều kiện lỗi một cách duyên dáng với khối begin..rescue.

begin 
    dater = data_bag_item(:basket, "flowers") 
rescue Net::HTTPServerException 
    # maybe some retry code here? 
    raise "Couldn't find flowers in the basket, need those to continue!" 
end 

data_bag_item làm cho một yêu cầu HTTP cho một túi dữ liệu trên Chef Server, và sẽ trả về một Net::HTTPServerException nếu có một vấn đề từ máy chủ (404 không tìm thấy, 403 trái phép, vv). Chúng tôi có thể cố gắng thử lại hoặc thực hiện một số thao tác khác và sau đó quay lại raise.

Báo cáo lỗi

Đơn giản chỉ cần thoát và tung một stack trace là tốt nếu bạn đang chạy Chef từ dòng lệnh. Tuy nhiên, nếu bạn đang chạy nó trong cron hoặc như một daemon trên một vài, hoặc thậm chí hàng chục hoặc hàng trăm máy, đây không phải là một cách tuyệt vời để giữ sự tỉnh táo khi có vấn đề.

Nhập Chef's report/exception handler feature. Bạn có thể sử dụng một trình xử lý cho đầu bếp của bạn chạy. Tất cả các trình xử lý báo cáo đều được chạy ở cuối đầu bếp. Xử lý ngoại lệ được chạy vào cuối của một đầu bếp bị hủy bỏ. Tình trạng chạy được theo dõi, và có thể được kiểm tra trong trình xử lý, vì vậy bạn có thể viết một trong đó xử lý cả hai loại chạy (thành công/hoàn thành hoặc không thành công/hủy bỏ).

documentation cho bạn biết cách viết. Nó cũng bao gồm một danh sách có sẵn open source handlers mà bạn có thể sử dụng cho một loạt các dịch vụ, bao gồm:

  • Email qua SMTP
  • IRC
  • Graphite
  • HipChat

Và nhiều hơn .

+2

Câu trả lời thú vị! Rất hữu ích. Tôi đã tìm kiếm điều này trong các nguồn đầu bếp khác nhau, nhưng không tìm thấy nó. Nếu tôi có, Câu hỏi này sẽ không tồn tại.Gần đây, tôi quyết định rằng khi tôi tìm kiếm câu trả lời cho một câu hỏi và không tìm thấy câu trả lời cho Stackoverflow hoặc dễ dàng từ các tài nguyên dự kiến, một khi tôi có câu trả lời, tôi sẽ kết hợp một cặp Câu hỏi và Trả lời Stackoverflow để nắm bắt những gì tôi đã học . –

+1

Tôi chưa bao giờ có thể nhận được 'rescue Net :: HTTPServerException' để làm việc. Nó không giải quyết được ngoại lệ. – Zabba

+0

yêu thích ý kiến ​​inquisition tiếng Tây Ban Nha :-) – Mamun

7

Cách được khuyến nghị để hủy hoặc chỉnh sửa đầu bếp là tăng ngoại lệ. Dưới đây là một ví dụ:

ruby_block "some tricky operation" do 
    block do 
    OperationFoo 
    raise "Operation Foo Failed" if some_condition 
    end 
end 
4

Chef :: Application.fatal! nên làm những gì bạn đang tìm kiếm. Đây là một ví dụ từ cơ sở mã của chúng tôi có thể hữu ích.

cipher = case key.length 
    when 16 then "AES-128-ECB" 
    when 24 then "AES-192-ECB" 
    when 32 then "AES-256-ECB" 
else 
    Chef::Application.fatal!("AES Key must be 16, 24, or 32 characters in length but key #{key} has length of #{key.length}") 
end 
-3

Để làm được một lối ra ô uế trong quá trình chạy đầu bếp hát solo, hãy thử này:

bash 'exit' do 
    code 'killall -9 chef-solo' 
end 
-1

Chỉ cần sử dụng dưới đây trình bày khi bạn muốn chef để kết thúc sau khi một số hành động:

throw :end_client_run_early 

Nó sẽ thoát mà không có bất kỳ lỗi nào.

Các vấn đề liên quan