2013-04-01 13 views
8

Mam trochę wyzwanie na przepis na szefa kuchni. Jestem nowym szefem kuchni, więc proszę, dajcie mi spokój.Szef kuchni - utwórz szablon ze zmienną dynamiczną?

Krok 1: Mój przepis na szefa kuchni instaluje Ruby Passenger, a następnie kompiluje moduł Passenger nginx wraz z 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 

Krok 2: Następnie utworzę plik konfiguracyjny nginx za pomocą szablonu. Ta konfiguracja wymaga lokalizacji pasażera, która jest zależna od ukończenia etapu 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 

Problem: Chef wydaje się kompilować szablony na początku biegu. Tak więc dzieje się tak, że krok 2 jest właściwie kompilowany przed uruchomieniem kroku 1. Oznacza to, że zmienna_pasażerka jest pusta. Zanim będzie można pobrać plik guest_root, konieczne będzie wykonanie kroku 1, a następnie uruchomienie szablonu.

Próbowałem owijać kod kroku 2 w ruby_block, ale to nie działa: undefined method szablon "dla Chef :: Resource :: RubyBlock".

Nie jesteś pewien, co tutaj robić, a jaka jest najlepsza praktyka dla szefa kuchni w takich sytuacjach?

Dzięki z góry,

Leonard

Odpowiedz

1

Tak, Chef jest bestia. Myślę, że częścią problemu jest milion sposobów na robienie tych samych rzeczy, ale naprawdę nie ma dokumentacji opisującej najlepszy sposób. Najprawdopodobniej użyjesz Notifications, tak aby blok 1 działał jako pierwszy, niż powiadamia blok 2, aby działał. Oznacza to, że blok 2 potrzebuje action :none, aby nie uruchamiał się, dopóki nie otrzyma powiadomienia.

I dodaje zgłaszają swój przykład w bloku 1 i dodaje akcję: none zablokować 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

Jak najszybciej owinąć kod w ruby_block nie można użyć zwykłego oświadczenia zasobów przepis już. Musisz napisać czysty kod ruby:

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. I myślę, że chcesz użyć strip zamiast chomp, aby usunąć białe spacje.

11

Czystszym i zalecanym sposobem jest użycie 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 

Również Sugeruję użyciu strip zamiast chomp [Dzięki Draco].

Powiązane problemy