i use Chef to install RHEL 5.x packages in my nodes. I of course use the package resource, like so
package 'jdk'
As you can imagine, I have a LOT of package resource calls in a LOT of cookbooks.
Per the Chef package documentation, the resource has the retries and retry_delay properties, with default values of 0 and 2secs respectively.
Now I want to change this behavior so retries in 12 and retry_delay is 5 secs. Now I know I can do this
package 'jdk' do
retries 12
retry_delay 5
end
But then I'd have to do this in ALL package resource calls. Like I said I have a LOT of them, so I don't necessarily want to do this.
I have started writing a custom_resource, and call it say, mycompany_package can can do this, in my mycompany_package/resource/default.rb file.
# 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
Now I can do this
mycompany_package 'jdk'
and I will get 12 retries and 5 retry_delays. Fair enough.
HOWEVER, this does NOT work
mycompany_package 'jdk' do
flush_cache [:before, :after]
end
since mycompany_package does NOT define the flush_cache property. Now I have to define ALL of the package resource's properties in my mycompany_package cookbook. Yikes!
So what is the best way to override the retries and retry_delay default values of the package resource?
Best Answer
LWRP is probably overkill for what you're trying to do. Something to remember is that recipes are just Ruby and any Ruby you write outside of a block is executed during the compile phase. So with that in mind you can programmatically generate blocks that are executed in the converge phase.
The simplest example to solve your problem be to do something like this:
To go a step further, you can use a Hash instead of an Array:
You can also store the Hash or Array in attributes, but keep in mind that attributes aren't a true Hash, they're a Mash and there's some got'chas in there when trying to override attributes, but that's an entirely different discussion.