7

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

例如,我希望能够在其中做这样的事情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

使用厨师 10.16.4。

4

2 回答 2

8

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

这样,只有当前的食谱会包含模块,而不是整个厨师运行中的所有模块(因此可以避免名称冲突)。

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

于 2013-10-02T10:37:21.013 回答
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

我不知道是否不赞成使用类变量,但它在我所有的测试中都有效,而且很好用且易于使用。

于 2013-12-03T01:59:09.100 回答