2013-01-31 13 views
11

Ho due LWRP. Il primo riguarda la creazione di un volume del disco, la sua formattazione e il suo montaggio su una macchina virtuale, chiameremo questa risorsa cloud_volume. La seconda risorsa (non molto importante per quello che fa) ha bisogno di un UUID per il volume appena formattato che è un attributo obbligatorio, chiameremo questa risorsa foobar.Esiste un modo per ritardare la risoluzione degli attributi di una risorsa fino alla fase "Esegui"?

Le risorse cloud_volume e foobar vengono utilizzate in una ricetta come la seguente.

volumes.each do |mount_point, volume| 
    cloud_volume "#{mount_point}" do 
    size volume['size'] 
    label volume['label'] 
    action [:create, :initialize] 
    end 
    foobar "#{mount_point}" do 
    disk_uuid node[:volumes][mount_point][:uuid] # This is set by cloud_volume 
    action [:do_stuff] 
    end 
end 

Quindi, quando eseguo uno chef, ottengo un'eccezione Required argument disk_identifier is missing!.

Dopo aver eseguito alcuni scavi ho scoperto che le ricette vengono elaborate in due fasi, una fase di compilazione e una fase di esecuzione. Sembra che il problema sia in fase di compilazione poiché è il momento in cui node[:volumes][mount_point][:uuid] non è impostato.

purtroppo non posso utilizzare il trucco che ha Opscode here le notifiche vengono utilizzati nel LWRP cloud_volume (quindi sarebbe cadere nella anti-modello mostrato nella documentazione)

Quindi, dopo tutto questo, la mia domanda è, c'è un modo per aggirare il requisito che il valore di disk_uuid essere noto al momento della compilazione?

risposta

15

Un modo più semplice sarebbe utilizzare Lazy Attribute Evaluation. Questo valuterà node[:volumes][mount_point][:uuid] durante il tempo di esecuzione invece di compilare

foobar "#{mount_point}" do 
    disk_uuid lazy { node[:volumes][mount_point][:uuid] } 
    action [:do_stuff] 
end 
13

responsabilità: questo è il modo di andare con più vecchio Chef (< 11.6.0), prima di essere aggiunto lazy attribute evaluation.

Avvolgi la tua risorsa foobar in ruby_block e definisci il foobar in modo dinamico. In questo modo, dopo la fase di compilazione, si avrà un codice rubino nella raccolta delle risorse e verrà valutato in fase di esecuzione.

ruby_block "mount #{mount_point} using foobar" do 
    block do 
    res = Chef::Resource::Foobar.new(mount_point, run_context) 
    res.disk_uuid node[:volumes][mount_point][:uuid] 
    res.run_action :do_stuff 
    end 
end 

In questo modo node[:volumes][mount_point][:uuid] saranno resi noti al momento della compilazione, ma anche non sarà possibile accedere al momento della compilazione. Sarà accessibile solo nella fase di esecuzione, quando dovrebbe essere già impostato.

+0

Ahhh, questo è esattamente quello che sto cercando! Ho lavorato come un incantesimo, grazie :-) – Matt

+0

Ti ho già fatto +1, ma grazie mille per aver indicato la versione in cui è stata aggiunta la valutazione degli attributi pigri. –

Problemi correlati