2013-04-01 24 views
8

Şef tarifinde biraz zorlanıyorum. Şef için yeniyim, lütfen benimle birlikte ol.Şef - dinamik değişkenli şablon oluşturulsun mu?

Adım 1: Şef tarifim Ruby Yolcu'nu kurar, ardından Yolcu nginx modülünü Nginx ile birlikte derler.

# 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 

Adım 2: Bundan sonra şablon kullanarak nginx yapılandırma dosyasını oluşturuyorum. Bu yapılandırma, 1. adımın tamamlanmasına bağlı olan Yolcu'nun yerini gerektirir.

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 

Sorun: Şef, şablonları çalışmanın ebeginning'inde derlemek için görünüyor. Peki, sonuçta ortaya çıkan şey Adım 2'nin çalıştırılmasından önce Adım 2'nin gerçekten derlenmiş olmasıdır. Bu, yolcu_kökü değişkeninin boş olduğu anlamına gelir. Yolcu_rootunu alabilmek için önce Adım 1'e ihtiyaç var, daha sonra şablonu çalıştırın.

Adım 2 kodunu bir ruby_block'da sarmayı denedim, ancak bu işe yaramadı: undefined method template for Chef :: Resource :: RubyBlock`.

Burada ne yapacağınızdan emin değil misiniz, veya Şef için en iyi uygulama hangisi böyle? peşin

sayesinde

Leonard

cevap

1

Evet, şef bir yaratıktır. Bence problemin bir kısmı aynı şeyleri yapmak için milyonlarca yol var ama gerçekten en iyi yolu gösteren bir belge yok. Muhtemelen istediğiniz, Notifications'u kullanmaktır, böylece blok 1, blok 2'nin çalışması için bildirmekten daha önce çalışır. Bu, blok 2'nin action :none'a ihtiyacı olduğu anlamına gelir, böylece bildirim alınana kadar tetiklenmez.

Bloktaki 1 daki örneğe bildirmek eklendi ve eylemi ekledi: Eğer artık sıradan tarifi kaynak beyanı kullanamaz ruby_block kodunuzu sarın olarak hiçbiri kısa sürede

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

blok 2'ye. Saf Ruby kodu yazmalısınız:

PS. Ve sanırım boşluğu kaldırmak için chomp yerine strip kullanmak istiyorsunuz.

11

Temizleyici ve önerilen bir yöntem Lazy Attribute Evaluation kullanmaktır.

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 

Ayrıca, ben strip yerine chomp [teşekkürler Draco] kullanmanızı öneririz olur.