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

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

我使用 Chef 在我的节点中安装 RHEL 5.x 软件包。我当然使用软件包资源,如下所示

package 'jdk'

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

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

现在我想改变这种行为,使其在 12 秒内重试,并且 retry_delay 为 5 秒。现在我知道我可以做到这一点

package 'jdk' do
  retries 12
  retry_delay 5
end

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

我已经开始写自定义资源,并在我的 mycompany_package/resource/default.rb 文件中调用它,说 mycompany_package 可以做到这一点。

# 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 cookbook 中定义包资源的所有属性。哎呀!

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

答案1

对于您要做的事情,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

您还可以将哈希或数组存储在属性中,但请记住,属性不是真正的哈希,它们是混合体,并且在尝试覆盖属性时会出现一些问题,但这是一个完全不同的讨论。

相关内容