假设我在食谱中有一个默认属性:
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()
调用实际上做了什么,我可以告诉它我想要合并的优先级吗?