覆盖配方中的属性

时间:2013-01-31 05:19:24

标签: chef chef-recipe

我们说我在食谱中有一个默认属性:

default.nginx_upstreams = {
    'service1' => ['service1.server.com'],
    'service2' => ['service2.server.com'],
}

然后它会在角色和环境中被修改和覆盖,直到它最终到达我的食谱。在那里,我计算了一些我想要添加到属性的附加服务。如果我做这样的事情:

node.nginx_upstreams.merge! {'service3' => ['service3.server.com']}

然后当我尝试在我的模板中使用该属性时,我尝试在模板中获得undefined method 'each' for nil:NilClass

<% node.nginx_upstreams.each do |name, servers| %>

另外,我还得到WARN: Setting attributes without specifying a precedence is deprecated and will be removed in Chef 11.0。有用的警告告诉我如何以正常优先级设置属性(显然,使用node.set["key"] = "value",但不告诉我如何指定默认或覆盖属性。

我可以通过这样的方式解决这个问题:

upstreams = node.nginx_upstreams.to_hash
upstreams.merge! {'service3' => ['service3.server.com']}

template "nginx_config" do
    variables({:upstreams=>upstreams})
end

但这感觉就像一个黑客。我找不到node.set() node.set()以外的任何文档,这也表明您可以在配方中设置正常和覆盖属性,但不会说明如何。

那么......你如何从配方中正确设置属性(与其他所有东西深度融合)? {{1}}调用实际上做了什么,我可以告诉它我想要合并的优先级吗?

3 个答案:

答案 0 :(得分:43)

default.nginx_upstreamsdefault[:nginx_upstreams]default['nginx_upstreams']相同 - 惯例是使用后两者中的一个。当你进一步使用字符串时,也可以在这里使用它们。

在属性文件中初始化nginx_upstreams的方式与以这种方式执行相同:

default['nginx_upstreams']['service1'] = ['service1.server.com']
default['nginx_upstreams']['service2'] = ['service2.server.com']

在此之前你不必初始化default['nginx_upstreams'] = {}。这些不是哈希,而是属性,而且它们更聪明。 :)

从配方内部修改属性就像这样:

node.default['nginx_upstreams']['service3'] = ['service3.server.com']

如果您需要更改优先顺序,可以在此处使用setoverride代替default。省略优先名称(node['nginx_upstreams']node.nginx_upstreams)将使用set优先级。但这已被弃用,很快就会被删除 - 这就是警告的全部内容。 查看manual page about attributes,因为一切都在那里。

答案 1 :(得分:10)

只是想进一步了解Chef属性,对于将要在节点属性覆盖上引用此问题的用户来说非常重要。

文件方法对应属性

在菜谱的属性文件中或在配方中使用以下方法。这些方法对应于同名的属性类型:

  • 倍率
  • 默认
  • 正常(或设置,其中set是普通的别名)
  • _unless
  • 属性?

属性优先

属性始终由chef-client按以下顺序应用:

  1. 位于cookbook属性文件中的默认属性
  2. 位于食谱中的默认属性
  3. 位于环境中的默认属性
  4. 位于角色
  5. 中的默认属性
  6. 位于cookbook属性文件中的force_default属性
  7. 位于食谱中的force_default属性
  8. 位于cookbook属性文件中的普通属性
  9. 位于食谱中的普通属性
  10. 位于cookbook属性文件中的覆盖属性
  11. 位于食谱中的覆盖属性
  12. 位于角色
  13. 中的覆盖属性
  14. 位于环境中的覆盖属性
  15. 位于cookbook属性文件中的force_override属性
  16. 位于食谱中的force_override属性
  17. Ohai在厨师 - 客户运行开始时识别的自动属性
  18. 其中列表中的最后一个属性是应用于节点的属性。

    这意味着,OHAI属性将具有最高优先级,其中cookbook属性文件中的默认属性将具有最低优先级。

    注意:为了用户的利益,为attributes的Chef文档提供了重要的详细信息。因为有时URL会被移动或无效。

答案 2 :(得分:4)

所以在挖掘之后,我找到了答案:

<强> node.set
使用node.default(或者可能是node.override)而不是node.set,因为node.set是node.normal的别名。正常数据保留在节点对象上。因此,使用node.set将持久保存节点对象中的数据。如果稍后删除使用node.set的代码,如果已在节点上设置了该数据,则该数据将保留。

正常和覆盖属性在chef-client运行开始时被清除,然后根据当时烹饪书和食谱中的代码重建为运行的一部分。

node.set(和node.normal)只应用于在第一次自选 - 客户端运行时为数据库生成密码,之后会记住(而不是保留)。即使是这种情况也应该避免,因为使用数据包是存储此类数据的推荐方法。