2013-04-01 61 views
8

我對廚師食譜有點挑戰。我是廚師新手,請耐心等待。廚師 - 使用動態變量創建模板?

第1步:我的廚師食譜安裝Ruby Passenger,然後編譯Passenger nginx模塊和Nginx。

# Install passenger and nginx module 
bash "Install Passenger" do 
    code <<-EOF 
    source /usr/local/rvm/scripts/rvm 
    gem install passenger 
    EOF 
    user "root" 
    not_if { `gem list`.lines.grep(/^passenger \(.*\)/).count > 0 } 
end 

# Install passenger 
# Note that we have to explicitly include the RVM script otherwise it won't setup the environment correctly 
bash "Install passenger nginx module and nginx from source" do 
    code <<-EOF 
    source /usr/local/rvm/scripts/rvm 
    passenger-install-nginx-module --auto --prefix=/opt/nginx --auto-download 
    EOF 
    user "root" 
    not_if { File.directory? "/opt/nginx" } 
end 

第2步:之後,我使用模板創建nginx配置文件。這種配置需要乘客的位置,這取決於步驟1的完成。

template "/opt/nginx/conf/nginx.conf" do 
    source "nginx.conf.erb" 
    action :create 
    variables(
    deploy_user: deploy_user, 
    passenger_root: `bash -c "source /usr/local/rvm/scripts/rvm; passenger-config --root"`.chomp, 
    passenger_ruby: `bash -c "source /usr/local/rvm/scripts/rvm; which ruby"`.chomp, 
    passenger: node[:passenger] 
) 
end 

問題:廚師似乎在開始運行時編譯模板。所以最終發生的是第2步實際上是在步驟1運行之前編譯的。這意味着passenger_root變量是空白的。在獲得passenger_root之前,需要完成第1步才能完成,然後運行模板。

我試着將ruby_block中的第2步代碼包裝起來,但是這不起作用:undefined method模板用於Chef :: Resource :: RubyBlock。

不知道這裏要做什麼,或者對於這樣的事情廚師的最佳做法是什麼?

由於提前,

倫納德

回答

1

呀,廚師是一個野獸。我認爲問題的一部分是有一百萬種方法可以做同樣的事情,但實際上沒有詳細說明最佳方法的文檔。您可能需要的是使用Notifications,以便塊1先運行,然後通知塊2運行。這意味着塊2需要action :none,以便它在觸發通知之前不會觸發。

我加入了通知你的例子在塊1,並且增加了操作:無阻擋2.

bash "Install Passenger" do 
    code <<-EOF 
    source /usr/local/rvm/scripts/rvm 
    gem install passenger 
    EOF 
    user "root" 
    not_if { `gem list`.lines.grep(/^passenger \(.*\)/).count > 0 } 
    notifies :run, 'bash[Install passenger nginx module and nginx from source]', :immediately 
end 

bash "Install passenger nginx module and nginx from source" do 
    code <<-EOF 
    source /usr/local/rvm/scripts/rvm 
    passenger-install-nginx-module --auto --prefix=/opt/nginx --auto-download 
    EOF 
    user "root" 
    action :none 
end 
3

只要你在ruby_block包裝你的代碼,你可以不再使用普通的配方資源聲明。你必須寫純寶石代碼:

ruby_block "create /opt/nginx/conf/nginx.conf from template" do 
    block do 
    res = Chef::Resource::Template.new "/opt/nginx/conf/nginx.conf", run_context 
    res.source "nginx.conf.erb" 
    res.variables(
     deploy_user: deploy_user, 
     passenger_root: `bash -c "source /usr/local/rvm/scripts/rvm; passenger-config --root"`.chomp, 
     passenger_ruby: `bash -c "source /usr/local/rvm/scripts/rvm; which ruby"`.chomp, 
     passenger: node[:passenger] 
    ) 
    res.run_action :create 
    end 
end 

PS。我想你想用strip而不是chomp來刪除空格。

11

清潔和推薦的方法是使用Lazy Attribute Evaluation

template "/opt/nginx/conf/nginx.conf" do 
    source "nginx.conf.erb" 
    action :create 
    variables lazy { 
    { 
     deploy_user: deploy_user, 
     passenger_root: `bash -c "source /usr/local/rvm/scripts/rvm; passenger-config --root"`.strip, 
     passenger_ruby: `bash -c "source /usr/local/rvm/scripts/rvm; which ruby"`.strip, 
     passenger: node[:passenger] 
    } 
    } 
end 

另外,我建議使用strip代替chomp [感謝德拉科。