2011-12-16 5 views
35

Tôi có một chương trình mà tôi xây dựng từ nguồn. Đối với điều này tôi đang sử dụng tài nguyên script. Một cách tốt để thực hiện logic để cài đặt và cập nhật là gì? Ngay bây giờ tôi chỉ cần cài đặt được thực hiện với điều kiện tích hợp trong not_if.đầu bếp cài đặt và cập nhật chương trình từ nguồn

script "install_program" do 
    not_if {File.exists?('/program')} 
    interpreter "bash" 
    user "root" 
    cwd "/tmp" 
    code <<-EOH 
    wget http://www.example.com/program.tar.gz 
    tar -zxf program.tar.gz 
    cd tarball 
    ./configure 
    make 
    make install 
    EOH 
end 

Trả lời

67

Trước hết, nếu bạn có phương tiện để lưu trữ một kho gói nội, tôi thường khuyên bạn nên xây dựng các gói bản địa cho nền tảng mục tiêu của bạn (s), và sử dụng tài nguyên package để quản lý chúng, chứ không phải là xây dựng từ nguồn. Tôi biết rằng không phải lúc nào cũng có sẵn hoặc có tính khả thi, vì vậy ...

Phương pháp mà bạn thực hiện một "./configure & & làm & & make install" kịch bản cài đặt phong cách idempotent phụ thuộc vào loại phần mềm bạn đang làm việc với. Thông thường, nó là đủ để kiểm tra sự tồn tại của tập tin đích. Đôi khi, nó là mong muốn để xác định phiên bản nào là cần thiết, và phiên bản chương trình sẽ xuất ra khi thực thi với tùy chọn dòng lệnh thích hợp. Tôi sẽ sử dụng tài nguyên của bạn ở trên làm điểm bắt đầu cho các ví dụ này. Lưu ý rằng bạn có thể sử dụng bash làm lối tắt cho script tài nguyên có thông dịch viên bash.

Giả định: Chương trình được cài đặt thành /usr/local/bin/program và nhận đối số --version có lẽ là để hiển thị số phiên bản. Tôi đặt cd, cấu hình, và thực hiện lệnh cùng với && vì có lẽ nếu một lỗi chúng tôi không nên cố gắng tiếp tục thực hiện.

bash "install_program" do 
    not_if "/usr/local/bin/program --version | grep -q '#{node[:program][:version]}'" 
    user "root" 
    cwd "/tmp" 
    code <<-EOH 
    wget http://www.example.com/program-#{node[:program][:version]}.tar.gz -O /tmp/program-#{node[:program][:version]}.tar.gz 
    tar -zxf program-#{node[:program][:version]}.tar.gz 
    (cd program-#{node[:program][:version]}/ && ./configure && make && make install) 
    EOH 
end 

Thay vì sử dụng wget nó là một chút tốt hơn để sử dụng tài nguyên remote_file vì đây là idempotent ngày của riêng mình. Lưu ý rằng tham số checksum được thêm vào, với giá trị là thuộc tính. Tham số này cho đầu bếp không tải xuống tệp từ xa nếu tệp đích cục bộ khớp với tổng kiểm tra. Đây là tổng kiểm tra SHA256. Ngoài ra, tài nguyên này sẽ thông báo cho tập lệnh chạy ngay lập tức, vì vậy sau khi được tải xuống. Tập lệnh được đặt với hành động :nothing vì vậy nó chỉ được thực thi nếu tệp từ xa được tải xuống.

remote_file "/tmp/program-#{node[:program][:version]}.tar.gz" do 
    source "http://www.example.com/program-#{node[:program][:version]}.tar.gz" 
    checksum node[:program][:checksum] 
    notifies :run, "bash[install_program]", :immediately 
end 

bash "install_program" do 
    user "root" 
    cwd "/tmp" 
    code <<-EOH 
    tar -zxf program-#{node[:program][:version]}.tar.gz 
    (cd program-#{node[:program][:version]}/ && ./configure && make && make install) 
    EOH 
    action :nothing 
end 

Ngoài ra, /tmp có thể bị xóa trên hệ thống của bạn khi khởi động lại. Bạn nên tải xuống một vị trí khác không bị xóa, chẳng hạn như vị trí bộ nhớ cache của đầu bếp, giá trị là Chef::Config[:file_cache_path]. Ví dụ:

remote_file "#{Chef::Config[:file_cache_path]}/program.tar.gz" do 
    ... 
end 

Đối với ví dụ hơn nữa, bạn có thể nhìn thấy "nguồn" công thức nấu ăn trong một số sách dạy nấu ăn được chia sẻ bởi Opscode đây: http://github.com/opscode/cookbooks. php, python, gnu_parallelnagios sách dạy nấu ăn đều có công thức "nguồn".

+0

LƯU Ý: Một lỗi với '' remote_file'' đôi khi có thể '' giải nén'' một tệp có phần mở rộng '' .gz'', như '' tar.gz''. Vì vậy, '' tar-zxf'' sẽ thất bại vì nó không thực sự là một gzip. – Evgeny

+1

Tôi thích câu trả lời này – Galen

+0

@jtimberman, bạn có thể giải thích thêm, ở đâu từ biến 'program' và' version' được đặt là –