如何从Chef cookbook中的库访问当前节点?

我正在尝试为厨师食谱编写一个库,简化了一些常见搜索。

例如,我希望能够在cookbook/libraries/library.rb执行类似的操作,然后在同一个cookbook中的配方中使用它:

 module Example def self.search_attribute(attribute_name) return search(:nodes, node[attribute_name]) end end 

问题是,在Chef库文件中, node对象或searchfunction都不可用。

使用Chef::Search::Query.new().search(...)似乎可以Chef::Search::Query.new().search(...) ,但我找不到任何可以访问node 。 由此产生的错误是:

 undefined local variable or method `node' for Example:Module 

使用Chef 10.16.4。

您可以做的是将模块包含在配方中。 这样,您的模块函数可以访问配方的方法,包括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 

这样,只有当前配方包含模块,而不是所有这些都在整个厨师运行中(因此避免了名称冲突)。

或者,您可以将当前节点作为参数传递给函数。 这样,您不需要包含模块(它具有保留模块名称空间的优点),但具有更复杂的方法调用的缺点。

我试图访问库中的当前环境时遇到了这个问题。 我无法弄清楚如何使用模块来访问节点,我不想将节点传递给每个方法调用(或实例化调用)所以我做了这个(示例代码..而不是实际的function):

 # 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 

我不知道是否使用类变量是不受欢迎的,但它适用于我的所有测试,它很好用且易于使用。