厨师覆盖同一食谱中另一个食谱的属性
Chef overriding attributes from another recipe in same cookbook
我有一本包含 2 个食谱的食谱。
attributes/default.rb
default['vpn']['crt'] = 'nocrt'
默认配方具有创建通用 crt 文件的文件资源
file 'cert' do
path "/etc/vpn/#{node.default['network']['hostname']}.crt"
owner 'root'
group 'root'
mode '0644'
content node.default['vpn']['crt']
end
在第二个配方 client.rb
中,我包含默认配方,为该 "client" 加载加密数据包并覆盖属性。但它不会被覆盖。
include_recipe 'my-cookbook'
vault = ChefVault::Item.load('auth', 'client')
node.override['vpn']['crt'] = vault['crt']
...
文件内容== 'nocrt'
根据Chef's Attribute Precedence,它应该覆盖vault['crt']
的内容。
更新:
Javier Cortejoso:您的答案在文件资源中使用时有效。
但是考虑这个例子:
attributes/default.rb:
default['network']['hostname'] = 'generic-host-name'
在recipes/default.rb:
Chef::Log.info(node['network']['hostname'])
Chef::Log.info(node.default['network']['hostname'])
Chef::Log.info(node.override['network']['hostname'])
在recipes/client.rb:
node.override['network']['hostname'] = 'client-host-name'
include_recipe 'cookbook::default'
所以即使我先将执行顺序更改为 client.rb 配方,然后在覆盖后 default.rb,它仍然给我主机名 'generic-host-name':
==> default: [2015-03-04T17:30:43+00:00] INFO: generic-host-name
==> default: [2015-03-04T17:30:43+00:00] INFO: generic-host-name
==> default: [2015-03-04T17:30:43+00:00] INFO: {}
解决方案
我是个****白痴。我的 Vagrant 文件中有这两个:
chef.add_role "cookbook"
chef.add_recipe "cookbook::client"
感谢 Javier Cortejoso 为我指出延迟属性加载。
IMO 似乎在编译后该属性被覆盖了 file['cert']
。这是一个 "time" 问题而不是 "priority" 问题。为了获得正确的食谱执行顺序,您可能需要注意一些要点:
执行顺序应该是 运行 首先是你覆盖属性的配方 (client.rb
),然后是你使用覆盖属性的配方 (default.rb
).
您还可以将 lazy attribute evaluation 用于您的内容属性。
所以你的 default.rb
应该是:
include_recipe 'my-cookbook::client'
file 'cert' do
path "/etc/vpn/#{node.default['network']['hostname']}.crt"
owner 'root'
group 'root'
mode '0644'
content lazy node.default['vpn']['crt']
end
我有一本包含 2 个食谱的食谱。
attributes/default.rb
default['vpn']['crt'] = 'nocrt'
默认配方具有创建通用 crt 文件的文件资源
file 'cert' do
path "/etc/vpn/#{node.default['network']['hostname']}.crt"
owner 'root'
group 'root'
mode '0644'
content node.default['vpn']['crt']
end
在第二个配方 client.rb
中,我包含默认配方,为该 "client" 加载加密数据包并覆盖属性。但它不会被覆盖。
include_recipe 'my-cookbook'
vault = ChefVault::Item.load('auth', 'client')
node.override['vpn']['crt'] = vault['crt']
...
文件内容== 'nocrt'
根据Chef's Attribute Precedence,它应该覆盖vault['crt']
的内容。
更新:
Javier Cortejoso:您的答案在文件资源中使用时有效。
但是考虑这个例子:
attributes/default.rb:
default['network']['hostname'] = 'generic-host-name'
在recipes/default.rb:
Chef::Log.info(node['network']['hostname'])
Chef::Log.info(node.default['network']['hostname'])
Chef::Log.info(node.override['network']['hostname'])
在recipes/client.rb:
node.override['network']['hostname'] = 'client-host-name'
include_recipe 'cookbook::default'
所以即使我先将执行顺序更改为 client.rb 配方,然后在覆盖后 default.rb,它仍然给我主机名 'generic-host-name':
==> default: [2015-03-04T17:30:43+00:00] INFO: generic-host-name
==> default: [2015-03-04T17:30:43+00:00] INFO: generic-host-name
==> default: [2015-03-04T17:30:43+00:00] INFO: {}
解决方案
我是个****白痴。我的 Vagrant 文件中有这两个:
chef.add_role "cookbook"
chef.add_recipe "cookbook::client"
感谢 Javier Cortejoso 为我指出延迟属性加载。
IMO 似乎在编译后该属性被覆盖了 file['cert']
。这是一个 "time" 问题而不是 "priority" 问题。为了获得正确的食谱执行顺序,您可能需要注意一些要点:
执行顺序应该是 运行 首先是你覆盖属性的配方 (
client.rb
),然后是你使用覆盖属性的配方 (default.rb
).您还可以将 lazy attribute evaluation 用于您的内容属性。
所以你的 default.rb
应该是:
include_recipe 'my-cookbook::client'
file 'cert' do
path "/etc/vpn/#{node.default['network']['hostname']}.crt"
owner 'root'
group 'root'
mode '0644'
content lazy node.default['vpn']['crt']
end