2012-11-08 43 views
5

我通過模塊擴展了食譜類,以提供一些屬性,使我可以全局訪問我的路徑,這是動態構建的。 實施例:廚師食譜 - 模塊方法在資源中不可用

module Variables 
    def user 
    "user_name" 
    end 
    def user_home 
    "/home/#{node['user']}" 
    end 
end 

class Chef::Recipe 
    include Variables 
end 

的問題是,該資源塊內的這些方法都無法使用。

bash "do_something_with_property" do 
    user user 
    code "somecommand #{user_home}" 
end 

NoMethodError:未定義的方法`USER_HOME」主廚::資源::猛砸

奇怪的行爲,用戶屬性工作正常,但在代碼塊中使用的一個屬性不起作用。

這之後,我也這樣做,這包括在模塊的所有資源:

class Chef::Resource 
    include Variables 
end 

現在我USER_HOME屬性的資源塊內的行爲不同使用「外」時相比,意爲:

directory "#{user_home}/new_dir" do 
    action :create 
end 

創建/ home/user_name/new_dir

bash "create_dir" do 
    code "mkdir #{user_home}/new_dir" 
end 

結果在/ home // new_目錄

我測試過這個測試腳本,一切正常。

module MyModule 
def module_method 
    puts "blablalba" 
end 
end 

class A 
def block_method (&block) 
    block.call 
end 
end 

class B 
include MyModule 

def doit 
    a = A.new 
    a.block_method { module_method } 
end 
end 

B.new.doit 

對我來說,這似乎必須是一個廚師特有的問題。

任何人都可以解釋我,爲什麼發生這種情況?

是否有一個更好的解決方案來獲得全局訪問我的路徑和屬性的動態構建?

謝謝。

回答

1

你可以把你的路徑作爲屬性?

在環境級別還是節點級別?

我們做了一些類似於cookbook的屬性,我們這樣做來構建安裝說明。在這種情況下,我們從databag

default['splunk']['server'] = Chef::DataBagItem.load('Splunk', 'Install')["Server"] 
default['splunk']['install_args'] = Chef::DataBagItem.load('Splunk', 'Install')["Arguments"] 

default['splunk']['installcommands'] = "RECEIVING_INDEXER=\"#{default['splunk']['server']}\" #{default['splunk']['install_args']} /quiet" 

與所有的說我認爲資源類的擴展應該罰款見過你構建安裝說明。當你說內部資源的表現與外部表現不同時。目錄是一種資源,也是這樣在這種情況下它的兩個資源

http://wiki.opscode.com/display/chef/Resources#Resources-Directory

因此,也許這是與同時導致不一致的行爲的資源的一個問題之間表現不同?

+0

屬性的問題在於它們不考慮在角色或環境中覆蓋的值:
默認['user'] ='user_name' default ['user_home'] =「/ home#{node ['user ']}「 那就是爲什麼我在配方(或無論我需要它)中構建我的user_home路徑 – DELUXEnized

+0

不一致的行爲是由於某些原因,在塊上下文中評估某些屬性(如bash上的代碼屬性)和其他人(如用戶和組)在配方上下文中進行評估,在此配置上定義了屬性。無論如何,我不應該在Resource類中包含相同的模塊,因爲在其上下文中,節點不可用並返回不同的值。 – DELUXEnized

+0

您可以使用配方來設置節點級別的屬性: node ['user_home'] =「/ home#{node ['user']}」,然後它將播放opscode放置的優先模型。該配方可以添加到角色的開始?意味着所有的食譜都可以利用這個屬性,並且可以傳遞給資源? 也許這對你想要做的事情有點時髦 或者使用環境變量? – PatrickWalker

0

我已經成功注入方法到資源的範圍如下:

libraries/helper.rb

module MyCookbook 
    module Helper 
    def my_method 
     "foobar" 
    end 
    end 
end 

Chef::Resource.send(:include, MyCookbook::Helper) 

recipes/default.rb

file 'foo' do 
    content my_method 
end 

這裏的關鍵是Chef::Resource.send(:include, ...)中注入你的模塊直接進入Chef::Resource類,使您的模塊方法可用於您的所有資源。