我正在尝试为厨师食谱编写一个库,以简化一些常见搜索。
例如,我希望能够在cookbook/libraries/library.rb
中执行此类操作,然后在同一本食谱中的食谱中使用它:
module Example
def self.search_attribute(attribute_name)
return search(:nodes, node[attribute_name])
end
end
问题是,在Chef库文件中,node
对象或search
函数都不可用。
使用Chef::Search::Query.new().search(...)
似乎可以进行搜索,但我找不到任何可以访问node
的内容。由此产生的错误是:
undefined local variable or method `node' for Example:Module
使用Chef 10.16.4。
答案 0 :(得分:6)
您可以做的是将模块包含在配方中。这样,您的模块函数就可以访问配方的方法,包括node
。
我通常会为我的库模块执行此操作:
# my_cookbook/libraries/helpers.rb
module MyCookbook
module Helpers
def foo
node["foo"]
end
end
end
然后,在配方中,我将模块包含在配方的当前实例中:
# my_cookbook/recipes/default.rb
extend MyCookbook::Helpers
这样,只有当前的配方才能包含模块,而不是所有的模块都在整个厨师的运行中(因此可以避免名称冲突)。
或者,您可以将当前节点作为参数传递给函数。这样,您不需要包含模块(它具有保留模块名称空间的优点),但具有更复杂的方法调用的缺点。
答案 1 :(得分:0)
我试图访问库中的当前环境时遇到了这个问题。我无法弄清楚如何使用模块来访问节点,我不想将节点传递给每个方法调用(或实例化调用)所以我做了这个(示例代码..而不是实际的功能):
# libraries/account.rb
class Account
@@env = "_default"
def self.env=(env)
@@env = env
end
def settings
Chef::EncryptedDataBagItem.load(@@env, "settings") || {}
end
end
# recipes/accounts.rb
Account.env = node.chef_environment
Account.new.settings
我不知道是否使用类变量是不受欢迎的,但它适用于我的所有测试,并且它很好用且易于使用。