2013-04-01 14 views
8

Sto avendo un po 'di sfida su una ricetta dello Chef. Sono nuovo per Chef, quindi per favore portami con me.Chef: crea un modello con variabile dinamica?

Passaggio 1: la ricetta del mio chef installa Ruby Passenger, quindi compila il modulo nginx Passenger insieme a 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 

Passaggio 2: Dopodiché, creo il file di configurazione nginx utilizzando un modello. Questa configurazione richiede l'ubicazione di Passenger, che dipende dal completamento del passaggio 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 

Problema: lo chef sembra compilare i modelli all'inizio della corsa. Quindi, quello che succede è che il Passo 2 è in realtà compilato prima che venga eseguito il Passo 1. Ciò significa che la variabile passenger_root è vuota. È necessario completare il passaggio 1 prima di poter ottenere la pirata_del passeggero, quindi eseguire il modello.

Ho provato a inserire il codice di passaggio 2 in un ruby_block ma questo non funziona: modello undefined method per Chef :: Risorsa :: RubyBlock`.

Non sai cosa fare qui, o qual è la migliore pratica per Chef per qualcosa di simile?

Grazie in anticipo,

Leonard

risposta

1

Sì, Chef è una bestia. Penso che parte del problema sia che ci sono un milione di modi per fare le stesse cose, ma in realtà non esiste una documentazione che specifichi il modo migliore. Quello che probabilmente si desidera è utilizzare Notifications, in modo che il blocco 1 venga eseguito prima di notificare il blocco 2 da eseguire. Questo significa che il blocco 2 ha bisogno di action :none in modo che non si attivi fino a quando non viene notificato.

ho aggiunto il notificare al vostro esempio nel blocco 1 e ha aggiunto l'azione: nessuno di bloccare 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

Non appena si avvolgono il codice in ruby_block non è possibile utilizzare più ordinaria dichiarazione risorsa ricetta. Devi scrivere codice rubino puro:

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. E suppongo che vogliate usare strip invece di chomp per rimuovere spazi bianchi.

11

Un modo più pulito e consigliato è quello di utilizzare 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 

Inoltre, mi piacerebbe suggerisco di usare strip invece di chomp [grazie Draco].

Problemi correlati