【发布时间】:2013-01-15 03:41:53
【问题描述】:
假设我在食谱中有一个默认属性:
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
但这感觉就像一个黑客。除了this page,我在node.set() 上找不到任何文档,这也表明您可以在配方中设置普通属性和覆盖属性,但没有说明如何设置。
那么...您如何从配方中正确设置属性(与其他所有内容一起深度合并)? node.set() 调用实际上做了什么,我可以告诉它我想要合并的优先级吗?
【问题讨论】:
-
由@Draco Ater 提供的快速答案是
node.default["key"] = "value"、node.set["key"] = "value"和node.override["key"] = "value",分别代表默认、正常和覆盖优先级