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

bor*_*ing 7 ruby chef-infra

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

例如,我希望能够做同样的事情cookbook/libraries/library.rb,然后在同一本食谱中的食谱中使用它:

module Example
    def self.search_attribute(attribute_name)
        return search(:nodes, node[attribute_name])
    end
end
Run Code Online (Sandbox Code Playgroud)

问题是,在Chef库文件中,node对象或search函数都不可用.

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

undefined local variable or method `node' for Example:Module
Run Code Online (Sandbox Code Playgroud)

使用Chef 10.16.4.

Hol*_*ust 8

您可以做的是将模块包含在配方中.这样,您的模块函数就可以访问配方的方法,包括node.

我通常为我的库模块执行此操作:

# my_cookbook/libraries/helpers.rb
module MyCookbook
  module Helpers
    def foo
      node["foo"]
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后,在配方中,我将模块包含在配方的当前实例中:

# my_cookbook/recipes/default.rb
extend MyCookbook::Helpers
Run Code Online (Sandbox Code Playgroud)

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

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

  • 人们经常调用`Chef :: Recipe.include MyCookbook :: Helpers`,它使得辅助函数在所有配方中都可用(并且可以覆盖具有相同名称的潜在已有的函数).我认为这是一种代码味道,并且更喜欢我的版本,只是将'Helpers`模块明确地包含在配方中. (3认同)