2013-01-31 17 views
11

मेरे पास दो एलडब्ल्यूआरपी हैं। डिस्क वॉल्यूम बनाने, इसे स्वरूपित करने और वर्चुअल मशीन पर इसे घुमाने के साथ पहला सौदा, हम इस संसाधन को cloud_volume पर कॉल करेंगे। दूसरा संसाधन (वास्तव में यह महत्वपूर्ण नहीं है कि) क्या नए प्रारूपित वॉल्यूम के लिए यूयूआईडी की आवश्यकता है जो एक आवश्यक विशेषता है, हम इस संसाधन को foobar पर कॉल करेंगे।क्या "निष्पादन" चरण तक संसाधन के गुण समाधान में देरी करने का कोई तरीका है?

संसाधन cloud_volume और foobar रेसिपी में निम्न जैसा कुछ उपयोग किया जाता है।

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 

तो, जब मैं एक शेफ रन करता हूं तो मुझे Required argument disk_identifier is missing! अपवाद मिलता है।

कुछ खुदाई करने के बाद मैंने पाया कि व्यंजनों को दो चरणों में संकलित किया जाता है, एक संकलन चरण और एक निष्पादन चरण। ऐसा लगता है कि समस्या संकलन समय पर है क्योंकि यह उस बिंदु पर है जब node[:volumes][mount_point][:uuid] सेट नहीं है।

दुर्भाग्य से मैं चाल OpsCode here है कि के रूप में सूचनाएं cloud_volume LWRP में इस्तेमाल किया जा रहा उपयोग नहीं कर सकते (इसलिए यह विरोधी पैटर्न प्रलेखन में दिखाया गया है में गिर जाएगा)

तो, यह सब के बाद, मेरा सवाल यह है कि, क्या आवश्यकता है कि disk_uuid का मान संकलन समय पर ज्ञात हो?

उत्तर

15

Lazy Attribute Evaluation का उपयोग करने के लिए एक क्लीनर तरीका होगा। यह निष्पादन समय के दौरान node[:volumes][mount_point][:uuid] का मूल्यांकन करेंगे बजाय संकलन

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

अस्वीकरण: इस पुराने बावर्ची (< 11.6.0) के साथ जाने के लिए इससे पहले कि वे lazy attribute evaluation जोड़ा तरीका है।

ruby_block में अपने foobar संसाधन को लपेटें और गतिशील रूप से foobar परिभाषित करें। संकलन चरण के बाद इस तरह आपके संसाधन संसाधन में रूबी कोड होगा और इसका मूल्यांकन चरण चरण में किया जाएगा।

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 

इस तरह node[:volumes][mount_point][:uuid] संकलन समय पर जाना जाता है नहीं किया जाएगा, लेकिन यह भी संकलन समय पर पहुँचा नहीं किया जाएगा। इसे केवल चलने वाले चरण में ही एक्सेस किया जाएगा, जब इसे पहले से सेट किया जाना चाहिए।

+0

आह, कि वास्तव में है मैं के लिए क्या देख रहा हूँ! एक आकर्षण की तरह काम किया, धन्यवाद :-) – Matt

+0

मैंने पहले ही आपको +1 किया है, लेकिन उस संस्करण को दर्शाने के लिए बड़ा धन्यवाद जहां आलसी विशेषता मूल्यांकन जोड़ा गया था। –