如何覆盖一些厨师包的资源属性,而不需要定义所有其他的属性?

我使用Chef在我的节点中安装RHEL 5.x软件包。 我当然使用包资源,就像这样

package 'jdk' 

正如你所想象的,我在很多食谱中都有大量的资源调用。

根据Chef软件包文档 ,资源具有retries和retry_delay属性,默认值分别为0和2secs。

现在我想改变这个行为,所以重试12,retry_delay是5秒。 现在我知道我可以做到这一点

 package 'jdk' do retries 12 retry_delay 5 end 

但是,我必须在所有包资源调用中这样做。 就像我说的我有很多,所以我不一定要这样做。

我已经开始编写一个custom_resource ,并且称mycompany_package可以在mycompany_package / resource / default.rb文件中执行此操作。

 # Package name property :name, String, required: true, name_property: true # Retries property :retries, Integer, required: false, default: 12 # Delay between retries property :retry_delay, Integer, required: false, default: 5 action :install do package name do action :install retries retries retry_delay retry_delay end end action :remove do package name do action :remove end end action :update do package name do action :update retries retries retry_delay retry_delay end end 

现在我可以做到这一点

 mycompany_package 'jdk' 

我会得到12个重试和5个retry_delays。 很公平。

但是,这是行不通的

 mycompany_package 'jdk' do flush_cache [:before, :after] end 

因为mycompany_package没有定义flush_cache属性。 现在我必须在我的mycompany_package食谱中定义所有包资源的属性。 哎呀!

那么覆盖软件包资源的retries和retry_delay默认值的最好方法是什么?

LWRP对于你正在做的事情可能是过度的。 需要记住的一点是,配方只是Ruby,而在编译阶段执行的所有在块之外编写的Ruby都将被执行。 所以考虑到这一点,你可以编程生成在收敛阶段执行的块。

解决你的问题最简单的例子是做这样的事情:

 %w(jdk package2 package3).each do |pkg| package pkg do retries 12 retry_delay 5 end end 

更进一步,您可以使用哈希而不是数组:

 { 'jdk' => { 'version' => '1.8.0_92', 'flush_cache' => [:before, :after] }, 'package2' => { 'version' => '1.0.0' }, 'package3' => {} }.each do |pkg,opts| package pkg do retries 12 retry_delay 5 version opts['version'] if opts.has_key? 'version' flush_cache opts['flush_cache'] if opts.has_key? 'flush_cache' end end 

您也可以将Hash或Array存储在属性中,但请记住属性不是真正的Hash,它们是Mash,当尝试覆盖属性时,有些内容会被忽略,但这是一个完全不同的讨论。