我通过模块扩展了配方类,以提供一些属性,这些属性使我可以全局访问我的路径,这些路径是动态构造的。 例如:
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:Chef :: Resource :: Bash
的未定义方法`user_home'奇怪的是,用户属性工作正常,但代码块中使用的属性不起作用。
在此之后,我还将模块包含在所有资源中:
class Chef::Resource
include Variables
end
现在我的user_home属性在资源块中的行为与在“outside”中使用时的行为不同,这意味着:
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_dir
我用一点测试脚本对此进行了测试,一切正常。
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
所以对我而言,这似乎必须是特定于厨师的问题。
任何人都可以解释一下,为什么会这样?
对于我的路径和属性的全局访问是否有更好的解决方案可以动态构建?
感谢。
答案 0 :(得分:1)
我已成功将方法注入资源范围,如下所示:
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
类,使您的模块方法可用于您的所有资源。
答案 1 :(得分:0)
你能把你的路径作为属性吗?
在环境级别还是节点级别?
我们做了类似于cookbook属性的事情,我们这样做是为了构建安装说明。在这种情况下,我们从数据库
构建安装指令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
所以也许这是导致行为不一致的资源之一的问题?